##// END OF EJS Templates
Implements execute() method of sync operation
Implements execute() method of sync operation

File last commit:

r1205:b0db13ba024e
r1207:b9a9a3a9f506
Show More
TestAmdaFuzzing.cpp
346 lines | 11.7 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
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
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;
Alexandre Leroux
Sets the number of sync groups to create for fuzzing tests
r1204 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170 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.},
Alexandre Leroux
Creates sync and desync operations and adds them to the fuzzing tests
r1205 {FuzzingOperationType::ZOOM_OUT, 1.},
{FuzzingOperationType::SYNCHRONIZE, 0.8},
{FuzzingOperationType::DESYNCHRONIZE, 0.4}});
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>
Alexandre Leroux
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 availableOperations(const FuzzingState &fuzzingState, 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
Alexandre Leroux
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
Alexandre Leroux
Implements test execute() method...
r1174 auto variableId = variablesPoolEntry.first;
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
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 if (operation->canExecute(variableId, fuzzingState)) {
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
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 m_FuzzingState{}
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
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
Alexandre Leroux
Defines variable pool...
r1172 }
Alexandre Leroux
Sets the number of sync groups to create for fuzzing tests
r1204
// Inits sync groups and registers them into the variable controller
for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
auto syncGroupId = SyncGroupId::createUuid();
variableController.onAddSynchronizationGroupId(syncGroupId);
m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
}
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)
Alexandre Leroux
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 = availableOperations(m_FuzzingState, 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;
auto fuzzingOperation = variableOperation.second;
Alexandre Leroux
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
m_Properties);
Alexandre Leroux
Implements move operations (3)...
r1186 QTest::qWait(operationDelay());
Alexandre Leroux
Calls validation after each operation
r1196
// Validates variables
Alexandre Leroux
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 validate(m_FuzzingState.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;
}
Alexandre Leroux
Sets the number of sync groups to create for fuzzing tests
r1204 int nbMaxSyncGroups() const
{
static auto result
= m_Properties.value(NB_MAX_SYNC_GROUPS_PROPERTY, NB_MAX_SYNC_GROUPS_DEFAULT_VALUE)
.toInt();
return result;
}
Alexandre Leroux
Adds "number of operations" and "number of variables" properties for the tests
r1170 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
Passes FuzzingState and variable id instead VariableState to the methods of operations
r1203 FuzzingState m_FuzzingState;
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"