##// END OF EJS Templates
Implements validation of variable's data (1)...
Implements validation of variable's data (1) Creates helper used to validate data, depending on the server set at compile time

File last commit:

r1196:8028c7299f05
r1198:077a4fb03e91
Show More
TestAmdaFuzzing.cpp
332 lines | 11.2 KiB | text/x-c | CppLexer
/ plugins / amda / tests / TestAmdaFuzzing.cpp
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170 #include "FuzzingDefs.h"
Alexandre Leroux
Defines fuzzing operations...
r1171 #include "FuzzingOperations.h"
Alexandre Leroux
Adds utility class to get random values
r1175 #include "FuzzingUtils.h"
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 #include "FuzzingValidators.h"
Alexandre Leroux
Adds utility class to get random values
r1175
Alexandre Leroux
Adds initial test case
r1179 #include "AmdaProvider.h"
Alexandre Leroux
Inits test structure
r1168 #include <Network/NetworkController.h>
Alexandre Leroux
Adds the ability to set cache tolerance for tests
r1191 #include <Settings/SqpSettingsDefs.h>
Alexandre Leroux
Inits test structure
r1168 #include <SqpApplication.h>
#include <Time/TimeController.h>
Alexandre Leroux
Defines VariableState struct (3)...
r1189 #include <Variable/Variable.h>
Alexandre Leroux
Inits test structure
r1168 #include <Variable/VariableController.h>
#include <QLoggingCategory>
#include <QObject>
#include <QtTest>
#include <memory>
Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
namespace {
Alexandre Leroux
Defines fuzzing operations...
r1171 // /////// //
// Aliases //
// /////// //
Alexandre Leroux
Defines variable pool...
r1172 using VariableId = int;
Alexandre Leroux
Adds weights to operations (2)...
r1183 using Weight = double;
using Weights = std::vector<Weight>;
Alexandre Leroux
Defines variable pool...
r1172
Alexandre Leroux
Implements test execute() method...
r1174 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
using VariablesOperations = std::vector<VariableOperation>;
Alexandre Leroux
Adds weights to operations (2)...
r1183 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
Alexandre Leroux
Defines VariableState struct (3)...
r1189 using VariablesPool = std::map<VariableId, VariableState>;
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
Alexandre Leroux
Defines variable pool...
r1172
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170 // ///////// //
// Constants //
// ///////// //
// Defaults values used when the associated properties have not been set for the test
const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
Alexandre Leroux
Adds delete operation
r1192 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
{FuzzingOperationType::CREATE, 1.},
{FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
{FuzzingOperationType::PAN_LEFT, 1.},
{FuzzingOperationType::PAN_RIGHT, 1.},
{FuzzingOperationType::ZOOM_IN, 1.},
{FuzzingOperationType::ZOOM_OUT, 1.}});
Alexandre Leroux
Adds the ability to set cache tolerance for tests
r1191 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
Alexandre Leroux
Implements move operations (3)...
r1186
/// Delay between each operation (in ms)
const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
Alexandre Leroux
Completes fuzzing test structure by setting initial range for the time controller
r1178
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 /// Validators for the tests (executed in the order in which they're defined)
const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
Alexandre Leroux
Implements test execute() method...
r1174 // /////// //
// Methods //
// /////// //
/// Goes through the variables pool and operations pool to determine the set of {variable/operation}
/// pairs that are valid (i.e. operation that can be executed on variable)
Alexandre Leroux
Adds weights to operations (2)...
r1183 std::pair<VariablesOperations, Weights>
availableOperations(const VariablesPool &variablesPool,
const WeightedOperationsPool &operationsPool)
Alexandre Leroux
Implements test execute() method...
r1174 {
VariablesOperations result{};
Alexandre Leroux
Adds weights to operations (2)...
r1183 Weights weights{};
Alexandre Leroux
Implements test execute() method...
r1174
for (const auto &variablesPoolEntry : variablesPool) {
auto variableId = variablesPoolEntry.first;
Alexandre Leroux
Defines VariableState struct (3)...
r1189 const auto &variableState = variablesPoolEntry.second;
Alexandre Leroux
Implements test execute() method...
r1174
Alexandre Leroux
Adds weights to operations (2)...
r1183 for (const auto &operationsPoolEntry : operationsPool) {
auto operation = operationsPoolEntry.first;
auto weight = operationsPoolEntry.second;
Alexandre Leroux
Implements test execute() method...
r1174 // A pair is valid if the current operation can be executed on the current variable
Alexandre Leroux
Defines VariableState struct (3)...
r1189 if (operation->canExecute(variableState)) {
Alexandre Leroux
Implements test execute() method...
r1174 result.push_back({variableId, operation});
Alexandre Leroux
Adds weights to operations (2)...
r1183 weights.push_back(weight);
Alexandre Leroux
Implements test execute() method...
r1174 }
}
}
Alexandre Leroux
Adds weights to operations (2)...
r1183 return {result, weights};
Alexandre Leroux
Implements test execute() method...
r1174 }
Alexandre Leroux
Adds weights to operations (2)...
r1183 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
Alexandre Leroux
Defines operations pool...
r1173 {
Alexandre Leroux
Adds weights to operations (2)...
r1183 WeightedOperationsPool result{};
Alexandre Leroux
Defines operations pool...
r1173
Alexandre Leroux
Adds weights to operations (2)...
r1183 std::transform(
types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
});
Alexandre Leroux
Defines operations pool...
r1173
return result;
}
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 Validators createValidators(const ValidatorsTypes &types)
{
Validators result{};
std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
[](const auto &type) { return FuzzingValidatorFactory::create(type); });
return result;
}
Alexandre Leroux
Calls validation after each operation
r1196 /**
* Validates all the variables' states passed in parameter, according to a set of validators
* @param variablesPool the variables' states
* @param validators the validators used for validation
*/
void validate(const VariablesPool &variablesPool, const Validators &validators)
{
for (const auto &variablesPoolEntry : variablesPool) {
auto variableId = variablesPoolEntry.first;
const auto &variableState = variablesPoolEntry.second;
auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
: QStringLiteral("null variable");
qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
<< variableId << "(" << variableMessage << ")...";
for (const auto &validator : validators) {
validator->validate(VariableState{variableState});
}
qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
}
}
Alexandre Leroux
Inits test structure
r1168 /**
* Class to run random tests
*/
class FuzzingTest {
public:
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 explicit FuzzingTest(VariableController &variableController, Properties properties)
: m_VariableController{variableController},
m_Properties{std::move(properties)},
Alexandre Leroux
Defines variable pool...
r1172 m_VariablesPool{}
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 {
Alexandre Leroux
Defines variable pool...
r1172 // Inits variables pool: at init, all variables are null
for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
Alexandre Leroux
Defines VariableState struct (3)...
r1189 m_VariablesPool[variableId] = VariableState{};
Alexandre Leroux
Defines variable pool...
r1172 }
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 }
Alexandre Leroux
Inits test structure
r1168 void execute()
{
Alexandre Leroux
Some fixes...
r1190 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
<< nbMaxVariables() << "variable(s)...";
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170
Alexandre Leroux
Implements test execute() method...
r1174 auto canExecute = true;
for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
// Retrieves all operations that can be executed in the current context
Alexandre Leroux
Adds weights to operations (2)...
r1183 VariablesOperations variableOperations{};
Weights weights{};
std::tie(variableOperations, weights)
= availableOperations(m_VariablesPool, operationsPool());
Alexandre Leroux
Implements test execute() method...
r1174
canExecute = !variableOperations.empty();
if (canExecute) {
// Of the operations available, chooses a random operation and executes it
auto variableOperation
Alexandre Leroux
Adds weights to operations (2)...
r1183 = RandomGenerator::instance().randomChoice(variableOperations, weights);
Alexandre Leroux
Implements test execute() method...
r1174
auto variableId = variableOperation.first;
Alexandre Leroux
Defines VariableState struct (3)...
r1189 auto &variableState = m_VariablesPool.at(variableId);
Alexandre Leroux
Implements test execute() method...
r1174 auto fuzzingOperation = variableOperation.second;
Alexandre Leroux
Defines VariableState struct (3)...
r1189 fuzzingOperation->execute(variableState, m_VariableController, m_Properties);
Alexandre Leroux
Implements move operations (3)...
r1186 QTest::qWait(operationDelay());
Alexandre Leroux
Calls validation after each operation
r1196
// Validates variables
validate(m_VariablesPool, validators());
Alexandre Leroux
Implements test execute() method...
r1174 }
else {
Alexandre Leroux
Some fixes...
r1190 qCInfo(LOG_TestAmdaFuzzing()).noquote()
Alexandre Leroux
Implements test execute() method...
r1174 << "No more operations are available, the execution of the test will stop...";
}
}
Alexandre Leroux
Some fixes...
r1190 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
Alexandre Leroux
Inits test structure
r1168 }
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169
private:
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170 int nbMaxOperations() const
{
static auto result
= m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
.toInt();
return result;
}
int nbMaxVariables() const
{
static auto result
= m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
return result;
}
Alexandre Leroux
Implements move operations (3)...
r1186 int operationDelay() const
{
static auto result
= m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
return result;
}
Alexandre Leroux
Adds weights to operations (2)...
r1183 WeightedOperationsPool operationsPool() const
Alexandre Leroux
Defines operations pool...
r1173 {
static auto result = createOperationsPool(
m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
Alexandre Leroux
Adds weights to operations (2)...
r1183 .value<WeightedOperationsTypes>());
Alexandre Leroux
Defines operations pool...
r1173 return result;
}
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 Validators validators() const
{
static auto result
= createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
.value<ValidatorsTypes>());
return result;
}
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 VariableController &m_VariableController;
Properties m_Properties;
Alexandre Leroux
Defines variable pool...
r1172 VariablesPool m_VariablesPool;
Alexandre Leroux
Inits test structure
r1168 };
} // namespace
class TestAmdaFuzzing : public QObject {
Q_OBJECT
private slots:
/// Input data for @sa testFuzzing()
void testFuzzing_data();
void testFuzzing();
};
void TestAmdaFuzzing::testFuzzing_data()
{
// ////////////// //
// Test structure //
// ////////////// //
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 QTest::addColumn<Properties>("properties"); // Properties for random test
Alexandre Leroux
Inits test structure
r1168
// ////////// //
// Test cases //
// ////////// //
Alexandre Leroux
Adds initial test case
r1179 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
// Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
// QVariant
std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
QTest::newRow("fuzzingTest") << Properties{
{MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
{METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
{PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
Alexandre Leroux
Inits test structure
r1168 }
void TestAmdaFuzzing::testFuzzing()
{
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 QFETCH(Properties, properties);
Alexandre Leroux
Adds the ability to set cache tolerance for tests
r1191 // Sets cache property
QSettings settings{};
auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
Alexandre Leroux
Inits test structure
r1168 auto &variableController = sqpApp->variableController();
auto &timeController = sqpApp->timeController();
Alexandre Leroux
Completes fuzzing test structure by setting initial range for the time controller
r1178 // Generates random initial range (bounded to max range)
auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
.value<SqpRange>();
QVERIFY(maxRange != INVALID_RANGE);
auto initialRangeStart
= RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
auto initialRangeEnd
= RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
if (initialRangeStart > initialRangeEnd) {
std::swap(initialRangeStart, initialRangeEnd);
}
// Sets initial range on time controller
SqpRange initialRange{initialRangeStart, initialRangeEnd};
Alexandre Leroux
Some fixes...
r1190 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
Alexandre Leroux
Completes fuzzing test structure by setting initial range for the time controller
r1178 timeController.onTimeToUpdate(initialRange);
Alexandre Leroux
Some fixes...
r1190 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
Alexandre Leroux
Completes fuzzing test structure by setting initial range for the time controller
r1178
Alexandre Leroux
Adds variable controller and properties to test structure...
r1169 FuzzingTest test{variableController, properties};
Alexandre Leroux
Inits test structure
r1168 test.execute();
}
int main(int argc, char *argv[])
{
QLoggingCategory::setFilterRules(
"*.warning=false\n"
"*.info=false\n"
"*.debug=false\n"
"FuzzingOperations.info=true\n"
Alexandre Leroux
Adds validators to the fuzzing test...
r1195 "FuzzingValidators.info=true\n"
Alexandre Leroux
Inits test structure
r1168 "TestAmdaFuzzing.info=true\n");
SqpApplication app{argc, argv};
Alexandre Leroux
Adds the ability to set cache tolerance for tests
r1191 SqpApplication::setOrganizationName("LPP");
SqpApplication::setOrganizationDomain("lpp.fr");
SqpApplication::setApplicationName("SciQLop-TestFuzzing");
Alexandre Leroux
Inits test structure
r1168 app.setAttribute(Qt::AA_Use96Dpi, true);
TestAmdaFuzzing testObject{};
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&testObject, argc, argv);
}
#include "TestAmdaFuzzing.moc"