##// END OF EJS Templates
Updates model after an event has been created through the colored zone
Updates model after an event has been created through the colored zone

File last commit:

r1234:76dbe6c8f09b
r1286:073d4af7c849
Show More
FuzzingValidators.cpp
228 lines | 8.5 KiB | text/x-c | CppLexer
/ plugins / amda / tests / FuzzingValidators.cpp
Alexandre Leroux
Creates validator interface
r1226 #include "FuzzingValidators.h"
Alexandre Leroux
Implements validation of variable's data (2)...
r1232 #include "FuzzingDefs.h"
#include <Data/DataSeries.h>
Alexandre Leroux
Implements validation of variable's data (1)...
r1231 #include <Variable/Variable.h>
Alexandre Leroux
Creates validator interface
r1226
Alexandre Leroux
Creates validators for range and data
r1227 #include <QTest>
Alexandre Leroux
Creates validator interface
r1226 #include <functional>
Q_LOGGING_CATEGORY(LOG_FuzzingValidators, "FuzzingValidators")
namespace {
Alexandre Leroux
Implements validation of variable's data (1)...
r1231 // ////////////// //
// DATA VALIDATOR //
// ////////////// //
/// Singleton used to validate data of a variable
class DataValidatorHelper {
public:
/// @return the single instance of the helper
static DataValidatorHelper &instance();
virtual ~DataValidatorHelper() noexcept = default;
virtual void validate(const VariableState &variableState) const = 0;
};
/**
* Default implementation of @sa DataValidatorHelper
*/
class DefaultDataValidatorHelper : public DataValidatorHelper {
public:
void validate(const VariableState &variableState) const override
{
Q_UNUSED(variableState);
qCWarning(LOG_FuzzingValidators()).noquote() << "Checking variable's data... WARN: no data "
"verification is available for this server";
}
};
Alexandre Leroux
Implements validation of variable's data (3)...
r1233 /// Data resolution in local server's files
const auto LOCALHOST_SERVER_RESOLUTION = 4;
Alexandre Leroux
Implements validation of variable's data (4)...
r1234 /// Reference value used to generate the data on the local server (a value is the number of seconds
/// between the data date and this reference date)
const auto LOCALHOST_REFERENCE_VALUE
= DateUtils::secondsSinceEpoch(QDateTime{QDate{2000, 1, 1}, QTime{}, Qt::UTC});
Alexandre Leroux
Implements validation of variable's data (1)...
r1231 /**
* Implementation of @sa DataValidatorHelper for the local AMDA server
*/
class LocalhostServerDataValidatorHelper : public DataValidatorHelper {
public:
void validate(const VariableState &variableState) const override
{
Alexandre Leroux
Implements validation of variable's data (2)...
r1232 // Don't check data for null variable
if (!variableState.m_Variable || variableState.m_Range == INVALID_RANGE) {
return;
}
auto message = "Checking variable's data...";
auto toDateString = [](double value) { return DateUtils::dateTime(value).toString(); };
// Checks that data are defined
auto variableDataSeries = variableState.m_Variable->dataSeries();
if (variableDataSeries == nullptr && variableState.m_Range != INVALID_RANGE) {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL: the variable has no data while a range is defined";
QFAIL("");
}
Alexandre Leroux
Implements validation of variable's data (3)...
r1233 auto dataIts = variableDataSeries->xAxisRange(variableState.m_Range.m_TStart,
variableState.m_Range.m_TEnd);
// Checks that the data are well defined in the range:
// - there is at least one data
// - the data are consistent (no data holes)
if (std::distance(dataIts.first, dataIts.second) == 0) {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL: the variable has no data";
QFAIL("");
}
auto firstXAxisData = dataIts.first->x();
auto lastXAxisData = (dataIts.second - 1)->x();
if (std::abs(firstXAxisData - variableState.m_Range.m_TStart) > LOCALHOST_SERVER_RESOLUTION
|| std::abs(lastXAxisData - variableState.m_Range.m_TEnd)
> LOCALHOST_SERVER_RESOLUTION) {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL: the data in the defined range are inconsistent (data hole "
"found at the beginning or the end)";
QFAIL("");
}
auto dataHoleIt = std::adjacent_find(
dataIts.first, dataIts.second, [](const auto &it1, const auto &it2) {
/// @todo: validate resolution
return std::abs(it1.x() - it2.x()) > 2 * (LOCALHOST_SERVER_RESOLUTION - 1);
});
if (dataHoleIt != dataIts.second) {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL: the data in the defined range are inconsistent (data hole "
"found between times "
<< toDateString(dataHoleIt->x()) << "and " << toDateString((dataHoleIt + 1)->x())
<< ")";
QFAIL("");
}
Alexandre Leroux
Implements validation of variable's data (4)...
r1234 // Checks values
auto dataIndex = 0;
for (auto dataIt = dataIts.first; dataIt != dataIts.second; ++dataIt, ++dataIndex) {
auto xAxisData = dataIt->x();
auto valuesData = dataIt->values();
for (auto valueIndex = 0, valueEnd = valuesData.size(); valueIndex < valueEnd;
++valueIndex) {
auto value = valuesData.at(valueIndex);
auto expectedValue = xAxisData + valueIndex * LOCALHOST_SERVER_RESOLUTION
- LOCALHOST_REFERENCE_VALUE;
if (value != expectedValue) {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL: incorrect value data at time"
<< toDateString(xAxisData) << ", index" << valueIndex << "(found:" << value
<< ", expected:" << expectedValue << ")";
QFAIL("");
}
}
}
// At this step validation is OK
qCInfo(LOG_FuzzingValidators()).noquote() << message << "OK";
Alexandre Leroux
Implements validation of variable's data (1)...
r1231 }
};
/// Creates the @sa DataValidatorHelper according to the server passed in parameter
std::unique_ptr<DataValidatorHelper> createDataValidatorInstance(const QString &server)
{
if (server == QString{"localhost"}) {
return std::make_unique<LocalhostServerDataValidatorHelper>();
}
else {
return std::make_unique<DefaultDataValidatorHelper>();
}
}
DataValidatorHelper &DataValidatorHelper::instance()
{
// Creates instance depending on the SCIQLOP_AMDA_SERVER value at compile time
static auto instance = createDataValidatorInstance(SCIQLOP_AMDA_SERVER);
return *instance;
}
Alexandre Leroux
Implements validation of variable's range
r1230 // /////////////// //
// RANGE VALIDATOR //
// /////////////// //
/**
* Checks that a range of a variable matches the expected range passed as a parameter
* @param variable the variable for which to check the range
* @param expectedRange the expected range
* @param getVariableRangeFun the function to retrieve the range from the variable
* @remarks if the variable is null, checks that the expected range is the invalid range
*/
void validateRange(std::shared_ptr<Variable> variable, const SqpRange &expectedRange,
std::function<SqpRange(const Variable &)> getVariableRangeFun)
{
auto compare = [](const auto &range, const auto &expectedRange, const auto &message) {
if (range == expectedRange) {
qCInfo(LOG_FuzzingValidators()).noquote() << message << "OK";
}
else {
qCInfo(LOG_FuzzingValidators()).noquote()
<< message << "FAIL (current range:" << range
<< ", expected range:" << expectedRange << ")";
QFAIL("");
}
};
if (variable) {
compare(getVariableRangeFun(*variable), expectedRange, "Checking variable's range...");
}
else {
compare(INVALID_RANGE, expectedRange, "Checking that there is no range set...");
}
}
Alexandre Leroux
Creates validator interface
r1226 /**
* Default implementation of @sa IFuzzingValidator. This validator takes as parameter of its
* construction a function of validation which is called in the validate() method
*/
class FuzzingValidator : public IFuzzingValidator {
public:
/// Signature of a validation function
using ValidationFunction = std::function<void(const VariableState &variableState)>;
explicit FuzzingValidator(ValidationFunction fun) : m_Fun(std::move(fun)) {}
void validate(const VariableState &variableState) const override { m_Fun(variableState); }
private:
ValidationFunction m_Fun;
};
} // namespace
Alexandre Leroux
Creates validators for range and data
r1227
std::unique_ptr<IFuzzingValidator> FuzzingValidatorFactory::create(FuzzingValidatorType type)
{
switch (type) {
case FuzzingValidatorType::DATA:
return std::make_unique<FuzzingValidator>([](const VariableState &variableState) {
Alexandre Leroux
Implements validation of variable's data (1)...
r1231 DataValidatorHelper::instance().validate(variableState);
Alexandre Leroux
Creates validators for range and data
r1227 });
case FuzzingValidatorType::RANGE:
return std::make_unique<FuzzingValidator>([](const VariableState &variableState) {
Alexandre Leroux
Implements validation of variable's range
r1230 auto getVariableRange = [](const Variable &variable) { return variable.range(); };
validateRange(variableState.m_Variable, variableState.m_Range, getVariableRange);
Alexandre Leroux
Creates validators for range and data
r1227 });
default:
// Default case returns invalid validator
break;
}
// Invalid validator
return std::make_unique<FuzzingValidator>(
[](const VariableState &) { QFAIL("Invalid validator"); });
}