##// END OF EJS Templates
Randomizes the number of operations to wait between calling validation (defines min/max frequencies)
Alexandre Leroux -
r1244:7202dffeda15
parent child
Show More
@@ -1,107 +1,108
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2
2
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
4 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
5 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
5 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
6 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
6 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
7 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
7 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
8 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
8 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
9 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
9 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
10 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
10 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
11 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
11 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
12 const QString OPERATION_DELAY_BOUNDS_PROPERTY = QStringLiteral("operationDelays");
12 const QString OPERATION_DELAY_BOUNDS_PROPERTY = QStringLiteral("operationDelays");
13 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
13 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
14 const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY = QStringLiteral("validationFrequencyBounds");
14
15
15 // //////////// //
16 // //////////// //
16 // FuzzingState //
17 // FuzzingState //
17 // //////////// //
18 // //////////// //
18
19
19 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
20 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
20 {
21 {
21 return m_SyncGroupsPool.at(id);
22 return m_SyncGroupsPool.at(id);
22 }
23 }
23
24
24 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
25 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
25 {
26 {
26 return m_SyncGroupsPool.at(id);
27 return m_SyncGroupsPool.at(id);
27 }
28 }
28
29
29 const VariableState &FuzzingState::variableState(VariableId id) const
30 const VariableState &FuzzingState::variableState(VariableId id) const
30 {
31 {
31 return m_VariablesPool.at(id);
32 return m_VariablesPool.at(id);
32 }
33 }
33
34
34 VariableState &FuzzingState::variableState(VariableId id)
35 VariableState &FuzzingState::variableState(VariableId id)
35 {
36 {
36 return m_VariablesPool.at(id);
37 return m_VariablesPool.at(id);
37 }
38 }
38
39
39 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
40 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
40 {
41 {
41 auto end = m_SyncGroupsPool.cend();
42 auto end = m_SyncGroupsPool.cend();
42 auto it
43 auto it
43 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
44 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
44 const auto &syncGroup = syncGroupEntry.second;
45 const auto &syncGroup = syncGroupEntry.second;
45 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
46 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
46 });
47 });
47
48
48 return it != end ? it->first : SyncGroupId{};
49 return it != end ? it->first : SyncGroupId{};
49 }
50 }
50
51
51 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
52 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
52 {
53 {
53 std::vector<SyncGroupId> result{};
54 std::vector<SyncGroupId> result{};
54
55
55 for (const auto &entry : m_SyncGroupsPool) {
56 for (const auto &entry : m_SyncGroupsPool) {
56 result.push_back(entry.first);
57 result.push_back(entry.first);
57 }
58 }
58
59
59 return result;
60 return result;
60 }
61 }
61
62
62 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
63 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
63 {
64 {
64 if (syncGroupId.isNull()) {
65 if (syncGroupId.isNull()) {
65 return;
66 return;
66 }
67 }
67
68
68 // Registers variable into sync group: if it's the first variable, sets the variable range as
69 // Registers variable into sync group: if it's the first variable, sets the variable range as
69 // the sync group range
70 // the sync group range
70 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
71 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
71 syncGroup.m_Variables.insert(variableId);
72 syncGroup.m_Variables.insert(variableId);
72 if (syncGroup.m_Variables.size() == 1) {
73 if (syncGroup.m_Variables.size() == 1) {
73 auto &variableState = m_VariablesPool.at(variableId);
74 auto &variableState = m_VariablesPool.at(variableId);
74 syncGroup.m_Range = variableState.m_Range;
75 syncGroup.m_Range = variableState.m_Range;
75 }
76 }
76 }
77 }
77
78
78 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
79 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
79 {
80 {
80 if (syncGroupId.isNull()) {
81 if (syncGroupId.isNull()) {
81 return;
82 return;
82 }
83 }
83
84
84 // Unregisters variable from sync group: if there is no more variable in the group, resets the
85 // Unregisters variable from sync group: if there is no more variable in the group, resets the
85 // range
86 // range
86 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
87 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
87 syncGroup.m_Variables.erase(variableId);
88 syncGroup.m_Variables.erase(variableId);
88 if (syncGroup.m_Variables.empty()) {
89 if (syncGroup.m_Variables.empty()) {
89 syncGroup.m_Range = INVALID_RANGE;
90 syncGroup.m_Range = INVALID_RANGE;
90 }
91 }
91 }
92 }
92
93
93 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
94 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
94 {
95 {
95 auto syncGroupId = this->syncGroupId(variableId);
96 auto syncGroupId = this->syncGroupId(variableId);
96
97
97 // Retrieves the variables to update:
98 // Retrieves the variables to update:
98 // - if the variable is synchronized to others, updates all synchronized variables
99 // - if the variable is synchronized to others, updates all synchronized variables
99 // - otherwise, updates only the variable
100 // - otherwise, updates only the variable
100 auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId}
101 auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId}
101 : m_SyncGroupsPool.at(syncGroupId).m_Variables;
102 : m_SyncGroupsPool.at(syncGroupId).m_Variables;
102
103
103 // Sets new range
104 // Sets new range
104 for (const auto &variableId : variablesToUpdate) {
105 for (const auto &variableId : variablesToUpdate) {
105 m_VariablesPool.at(variableId).m_Range = newRange;
106 m_VariablesPool.at(variableId).m_Range = newRange;
106 }
107 }
107 }
108 }
@@ -1,122 +1,125
1 #ifndef SCIQLOP_FUZZINGDEFS_H
1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
3
3
4 #include <Data/SqpRange.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QString>
6 #include <QString>
7 #include <QUuid>
7 #include <QUuid>
8 #include <QVariantHash>
8 #include <QVariantHash>
9
9
10 #include <memory>
10 #include <memory>
11 #include <set>
11 #include <set>
12
12
13 // /////// //
13 // /////// //
14 // Aliases //
14 // Aliases //
15 // /////// //
15 // /////// //
16
16
17 using MetadataPool = std::vector<QVariantHash>;
17 using MetadataPool = std::vector<QVariantHash>;
18 Q_DECLARE_METATYPE(MetadataPool)
18 Q_DECLARE_METATYPE(MetadataPool)
19
19
20 using Properties = QVariantHash;
20 using Properties = QVariantHash;
21
21
22 // ///////// //
22 // ///////// //
23 // Constants //
23 // Constants //
24 // ///////// //
24 // ///////// //
25
25
26 /// Max number of operations to generate
26 /// Max number of operations to generate
27 extern const QString NB_MAX_OPERATIONS_PROPERTY;
27 extern const QString NB_MAX_OPERATIONS_PROPERTY;
28
28
29 /// Max number of sync groups to create through operations
29 /// Max number of sync groups to create through operations
30 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
30 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
31
31
32 /// Max number of variables to manipulate through operations
32 /// Max number of variables to manipulate through operations
33 extern const QString NB_MAX_VARIABLES_PROPERTY;
33 extern const QString NB_MAX_VARIABLES_PROPERTY;
34
34
35 /// Set of operations available for the test
35 /// Set of operations available for the test
36 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
36 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
37
37
38 /// Tolerance used for variable's cache (in ratio)
38 /// Tolerance used for variable's cache (in ratio)
39 extern const QString CACHE_TOLERANCE_PROPERTY;
39 extern const QString CACHE_TOLERANCE_PROPERTY;
40
40
41 /// Range with which the timecontroller is initialized
41 /// Range with which the timecontroller is initialized
42 extern const QString INITIAL_RANGE_PROPERTY;
42 extern const QString INITIAL_RANGE_PROPERTY;
43
43
44 /// Max range that an operation can reach
44 /// Max range that an operation can reach
45 extern const QString MAX_RANGE_PROPERTY;
45 extern const QString MAX_RANGE_PROPERTY;
46
46
47 /// Set of metadata that can be associated to a variable
47 /// Set of metadata that can be associated to a variable
48 extern const QString METADATA_POOL_PROPERTY;
48 extern const QString METADATA_POOL_PROPERTY;
49
49
50 /// Provider used to retrieve data
50 /// Provider used to retrieve data
51 extern const QString PROVIDER_PROPERTY;
51 extern const QString PROVIDER_PROPERTY;
52
52
53 /// Min/max times left for an operation to execute
53 /// Min/max times left for an operation to execute
54 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
54 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
55
55
56 /// Validators used to validate an operation
56 /// Validators used to validate an operation
57 extern const QString VALIDATORS_PROPERTY;
57 extern const QString VALIDATORS_PROPERTY;
58
58
59 /// Min/max number of operations to execute before calling validation of the current test's state
60 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
61
59 // /////// //
62 // /////// //
60 // Structs //
63 // Structs //
61 // /////// //
64 // /////// //
62
65
63 class Variable;
66 class Variable;
64 struct VariableState {
67 struct VariableState {
65 std::shared_ptr<Variable> m_Variable{nullptr};
68 std::shared_ptr<Variable> m_Variable{nullptr};
66 SqpRange m_Range{INVALID_RANGE};
69 SqpRange m_Range{INVALID_RANGE};
67 };
70 };
68
71
69 using VariableId = int;
72 using VariableId = int;
70 using VariablesPool = std::map<VariableId, VariableState>;
73 using VariablesPool = std::map<VariableId, VariableState>;
71
74
72 /**
75 /**
73 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
76 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
74 * with each other, and the current range of the group (i.e. range of the last synchronized variable
77 * with each other, and the current range of the group (i.e. range of the last synchronized variable
75 * that has been moved)
78 * that has been moved)
76 */
79 */
77 struct SyncGroup {
80 struct SyncGroup {
78 std::set<VariableId> m_Variables{};
81 std::set<VariableId> m_Variables{};
79 SqpRange m_Range{INVALID_RANGE};
82 SqpRange m_Range{INVALID_RANGE};
80 };
83 };
81
84
82 using SyncGroupId = QUuid;
85 using SyncGroupId = QUuid;
83 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
86 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
84
87
85 /**
88 /**
86 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
89 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
87 * the test, as well as the synchronization status of these variables.
90 * the test, as well as the synchronization status of these variables.
88 */
91 */
89 struct FuzzingState {
92 struct FuzzingState {
90 const SyncGroup &syncGroup(SyncGroupId id) const;
93 const SyncGroup &syncGroup(SyncGroupId id) const;
91 SyncGroup &syncGroup(SyncGroupId id);
94 SyncGroup &syncGroup(SyncGroupId id);
92
95
93 const VariableState &variableState(VariableId id) const;
96 const VariableState &variableState(VariableId id) const;
94 VariableState &variableState(VariableId id);
97 VariableState &variableState(VariableId id);
95
98
96 /// @return the identifier of the synchronization group in which the variable passed in
99 /// @return the identifier of the synchronization group in which the variable passed in
97 /// parameter is located. If the variable is not in any group, returns an invalid identifier
100 /// parameter is located. If the variable is not in any group, returns an invalid identifier
98 SyncGroupId syncGroupId(VariableId variableId) const;
101 SyncGroupId syncGroupId(VariableId variableId) const;
99
102
100 /// @return the set of synchronization group identifiers
103 /// @return the set of synchronization group identifiers
101 std::vector<SyncGroupId> syncGroupsIds() const;
104 std::vector<SyncGroupId> syncGroupsIds() const;
102
105
103 /// Updates fuzzing state according to a variable synchronization
106 /// Updates fuzzing state according to a variable synchronization
104 /// @param variableId the variable that is synchronized
107 /// @param variableId the variable that is synchronized
105 /// @param syncGroupId the synchronization group
108 /// @param syncGroupId the synchronization group
106 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
109 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
107
110
108 /// Updates fuzzing state according to a variable desynchronization
111 /// Updates fuzzing state according to a variable desynchronization
109 /// @param variableId the variable that is desynchronized
112 /// @param variableId the variable that is desynchronized
110 /// @param syncGroupId the synchronization group from which to remove the variable
113 /// @param syncGroupId the synchronization group from which to remove the variable
111 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
114 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
112
115
113 /// Updates the range of a variable and all variables to which it is synchronized
116 /// Updates the range of a variable and all variables to which it is synchronized
114 /// @param the variable for which to affect the range
117 /// @param the variable for which to affect the range
115 /// @param the range to affect
118 /// @param the range to affect
116 void updateRanges(VariableId variableId, const SqpRange &newRange);
119 void updateRanges(VariableId variableId, const SqpRange &newRange);
117
120
118 VariablesPool m_VariablesPool;
121 VariablesPool m_VariablesPool;
119 SyncGroupsPool m_SyncGroupsPool;
122 SyncGroupsPool m_SyncGroupsPool;
120 };
123 };
121
124
122 #endif // SCIQLOP_FUZZINGDEFS_H
125 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,354 +1,382
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2 #include "FuzzingOperations.h"
2 #include "FuzzingOperations.h"
3 #include "FuzzingUtils.h"
3 #include "FuzzingUtils.h"
4 #include "FuzzingValidators.h"
4 #include "FuzzingValidators.h"
5
5
6 #include "AmdaProvider.h"
6 #include "AmdaProvider.h"
7
7
8 #include <Network/NetworkController.h>
8 #include <Network/NetworkController.h>
9 #include <Settings/SqpSettingsDefs.h>
9 #include <Settings/SqpSettingsDefs.h>
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11 #include <Time/TimeController.h>
11 #include <Time/TimeController.h>
12 #include <Variable/Variable.h>
12 #include <Variable/Variable.h>
13 #include <Variable/VariableController.h>
13 #include <Variable/VariableController.h>
14
14
15 #include <QLoggingCategory>
15 #include <QLoggingCategory>
16 #include <QObject>
16 #include <QObject>
17 #include <QtTest>
17 #include <QtTest>
18
18
19 #include <memory>
19 #include <memory>
20
20
21 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
21 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
22
22
23 namespace {
23 namespace {
24
24
25 // /////// //
25 // /////// //
26 // Aliases //
26 // Aliases //
27 // /////// //
27 // /////// //
28
28
29 using Weight = double;
29 using Weight = double;
30 using Weights = std::vector<Weight>;
30 using Weights = std::vector<Weight>;
31
31
32 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
32 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
33 using VariablesOperations = std::vector<VariableOperation>;
33 using VariablesOperations = std::vector<VariableOperation>;
34
34
35 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
35 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
36 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
36 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
37
37
38 // ///////// //
38 // ///////// //
39 // Constants //
39 // Constants //
40 // ///////// //
40 // ///////// //
41
41
42 // Defaults values used when the associated properties have not been set for the test
42 // Defaults values used when the associated properties have not been set for the test
43 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
43 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
44 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
44 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
45 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
45 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
46 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
46 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
47 {FuzzingOperationType::CREATE, 1.},
47 {FuzzingOperationType::CREATE, 1.},
48 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
48 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
49 {FuzzingOperationType::PAN_LEFT, 1.},
49 {FuzzingOperationType::PAN_LEFT, 1.},
50 {FuzzingOperationType::PAN_RIGHT, 1.},
50 {FuzzingOperationType::PAN_RIGHT, 1.},
51 {FuzzingOperationType::ZOOM_IN, 1.},
51 {FuzzingOperationType::ZOOM_IN, 1.},
52 {FuzzingOperationType::ZOOM_OUT, 1.},
52 {FuzzingOperationType::ZOOM_OUT, 1.},
53 {FuzzingOperationType::SYNCHRONIZE, 0.8},
53 {FuzzingOperationType::SYNCHRONIZE, 0.8},
54 {FuzzingOperationType::DESYNCHRONIZE, 0.4}});
54 {FuzzingOperationType::DESYNCHRONIZE, 0.4}});
55 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
55 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
56
56
57 /// Min/max delays between each operation (in ms)
57 /// Min/max delays between each operation (in ms)
58 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(100, 3000));
58 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(100, 3000));
59
59
60 /// Validators for the tests (executed in the order in which they're defined)
60 /// Validators for the tests (executed in the order in which they're defined)
61 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
61 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
62 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
62 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
63
63
64 /// Min/max number of operations to execute before calling validation
65 const auto VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(1, 10));
66
64 // /////// //
67 // /////// //
65 // Methods //
68 // Methods //
66 // /////// //
69 // /////// //
67
70
68 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
71 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
69 /// pairs that are valid (i.e. operation that can be executed on variable)
72 /// pairs that are valid (i.e. operation that can be executed on variable)
70 std::pair<VariablesOperations, Weights>
73 std::pair<VariablesOperations, Weights>
71 availableOperations(const FuzzingState &fuzzingState, const WeightedOperationsPool &operationsPool)
74 availableOperations(const FuzzingState &fuzzingState, const WeightedOperationsPool &operationsPool)
72 {
75 {
73 VariablesOperations result{};
76 VariablesOperations result{};
74 Weights weights{};
77 Weights weights{};
75
78
76 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
79 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
77 auto variableId = variablesPoolEntry.first;
80 auto variableId = variablesPoolEntry.first;
78
81
79 for (const auto &operationsPoolEntry : operationsPool) {
82 for (const auto &operationsPoolEntry : operationsPool) {
80 auto operation = operationsPoolEntry.first;
83 auto operation = operationsPoolEntry.first;
81 auto weight = operationsPoolEntry.second;
84 auto weight = operationsPoolEntry.second;
82
85
83 // A pair is valid if the current operation can be executed on the current variable
86 // A pair is valid if the current operation can be executed on the current variable
84 if (operation->canExecute(variableId, fuzzingState)) {
87 if (operation->canExecute(variableId, fuzzingState)) {
85 result.push_back({variableId, operation});
88 result.push_back({variableId, operation});
86 weights.push_back(weight);
89 weights.push_back(weight);
87 }
90 }
88 }
91 }
89 }
92 }
90
93
91 return {result, weights};
94 return {result, weights};
92 }
95 }
93
96
94 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
97 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
95 {
98 {
96 WeightedOperationsPool result{};
99 WeightedOperationsPool result{};
97
100
98 std::transform(
101 std::transform(
99 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
102 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
100 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
103 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
101 });
104 });
102
105
103 return result;
106 return result;
104 }
107 }
105
108
106 Validators createValidators(const ValidatorsTypes &types)
109 Validators createValidators(const ValidatorsTypes &types)
107 {
110 {
108 Validators result{};
111 Validators result{};
109
112
110 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
113 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
111 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
114 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
112
115
113 return result;
116 return result;
114 }
117 }
115
118
116 /**
119 /**
117 * Validates all the variables' states passed in parameter, according to a set of validators
120 * Validates all the variables' states passed in parameter, according to a set of validators
118 * @param variablesPool the variables' states
121 * @param variablesPool the variables' states
119 * @param validators the validators used for validation
122 * @param validators the validators used for validation
120 */
123 */
121 void validate(const VariablesPool &variablesPool, const Validators &validators)
124 void validate(const VariablesPool &variablesPool, const Validators &validators)
122 {
125 {
123 for (const auto &variablesPoolEntry : variablesPool) {
126 for (const auto &variablesPoolEntry : variablesPool) {
124 auto variableId = variablesPoolEntry.first;
127 auto variableId = variablesPoolEntry.first;
125 const auto &variableState = variablesPoolEntry.second;
128 const auto &variableState = variablesPoolEntry.second;
126
129
127 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
130 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
128 : QStringLiteral("null variable");
131 : QStringLiteral("null variable");
129 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
132 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
130 << variableId << "(" << variableMessage << ")...";
133 << variableId << "(" << variableMessage << ")...";
131
134
132 for (const auto &validator : validators) {
135 for (const auto &validator : validators) {
133 validator->validate(VariableState{variableState});
136 validator->validate(VariableState{variableState});
134 }
137 }
135
138
136 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
139 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
137 }
140 }
138 }
141 }
139
142
140 /**
143 /**
141 * Class to run random tests
144 * Class to run random tests
142 */
145 */
143 class FuzzingTest {
146 class FuzzingTest {
144 public:
147 public:
145 explicit FuzzingTest(VariableController &variableController, Properties properties)
148 explicit FuzzingTest(VariableController &variableController, Properties properties)
146 : m_VariableController{variableController},
149 : m_VariableController{variableController},
147 m_Properties{std::move(properties)},
150 m_Properties{std::move(properties)},
148 m_FuzzingState{}
151 m_FuzzingState{}
149 {
152 {
150 // Inits variables pool: at init, all variables are null
153 // Inits variables pool: at init, all variables are null
151 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
154 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
152 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
155 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
153 }
156 }
154
157
155 // Inits sync groups and registers them into the variable controller
158 // Inits sync groups and registers them into the variable controller
156 for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
159 for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
157 auto syncGroupId = SyncGroupId::createUuid();
160 auto syncGroupId = SyncGroupId::createUuid();
158 variableController.onAddSynchronizationGroupId(syncGroupId);
161 variableController.onAddSynchronizationGroupId(syncGroupId);
159 m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
162 m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
160 }
163 }
161 }
164 }
162
165
163 void execute()
166 void execute()
164 {
167 {
165 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
168 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
166 << nbMaxVariables() << "variable(s)...";
169 << nbMaxVariables() << "variable(s)...";
167
170
171
172 // Inits the count of the number of operations before the next validation
173 int nextValidationCounter = 0;
174 auto updateValidationCounter = [this, &nextValidationCounter]() {
175 nextValidationCounter = RandomGenerator::instance().generateInt(
176 validationFrequencies().first, validationFrequencies().second);
177 qCInfo(LOG_TestAmdaFuzzing()).noquote()
178 << "Next validation in " << nextValidationCounter << "operations...";
179 };
180 updateValidationCounter();
181
168 auto canExecute = true;
182 auto canExecute = true;
169 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
183 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
170 // Retrieves all operations that can be executed in the current context
184 // Retrieves all operations that can be executed in the current context
171 VariablesOperations variableOperations{};
185 VariablesOperations variableOperations{};
172 Weights weights{};
186 Weights weights{};
173 std::tie(variableOperations, weights)
187 std::tie(variableOperations, weights)
174 = availableOperations(m_FuzzingState, operationsPool());
188 = availableOperations(m_FuzzingState, operationsPool());
175
189
176 canExecute = !variableOperations.empty();
190 canExecute = !variableOperations.empty();
177 if (canExecute) {
191 if (canExecute) {
192 --nextValidationCounter;
193
178 // Of the operations available, chooses a random operation and executes it
194 // Of the operations available, chooses a random operation and executes it
179 auto variableOperation
195 auto variableOperation
180 = RandomGenerator::instance().randomChoice(variableOperations, weights);
196 = RandomGenerator::instance().randomChoice(variableOperations, weights);
181
197
182 auto variableId = variableOperation.first;
198 auto variableId = variableOperation.first;
183 auto fuzzingOperation = variableOperation.second;
199 auto fuzzingOperation = variableOperation.second;
184
200
185 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
201 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
186 m_Properties);
202 m_Properties);
187
203
188 // Delays the next operation with a randomly generated time
204 // Delays the next operation with a randomly generated time
189 auto delay = RandomGenerator::instance().generateInt(operationDelays().first,
205 auto delay = RandomGenerator::instance().generateInt(operationDelays().first,
190 operationDelays().second);
206 operationDelays().second);
191 qCDebug(LOG_TestAmdaFuzzing())
207 qCDebug(LOG_TestAmdaFuzzing())
192 << "Waiting " << delay << "ms before the next operation...";
208 << "Waiting " << delay << "ms before the next operation...";
193 QTest::qWait(delay);
209 QTest::qWait(delay);
194
210
195 // Validates variables
211 // Validates variables
212 if (nextValidationCounter == 0) {
196 validate(m_FuzzingState.m_VariablesPool, validators());
213 validate(m_FuzzingState.m_VariablesPool, validators());
214 updateValidationCounter();
215 }
197 }
216 }
198 else {
217 else {
199 qCInfo(LOG_TestAmdaFuzzing()).noquote()
218 qCInfo(LOG_TestAmdaFuzzing()).noquote()
200 << "No more operations are available, the execution of the test will stop...";
219 << "No more operations are available, the execution of the test will stop...";
201 }
220 }
202 }
221 }
203
222
204 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
223 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
205 }
224 }
206
225
207 private:
226 private:
208 int nbMaxOperations() const
227 int nbMaxOperations() const
209 {
228 {
210 static auto result
229 static auto result
211 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
230 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
212 .toInt();
231 .toInt();
213 return result;
232 return result;
214 }
233 }
215
234
216 int nbMaxSyncGroups() const
235 int nbMaxSyncGroups() const
217 {
236 {
218 static auto result
237 static auto result
219 = m_Properties.value(NB_MAX_SYNC_GROUPS_PROPERTY, NB_MAX_SYNC_GROUPS_DEFAULT_VALUE)
238 = m_Properties.value(NB_MAX_SYNC_GROUPS_PROPERTY, NB_MAX_SYNC_GROUPS_DEFAULT_VALUE)
220 .toInt();
239 .toInt();
221 return result;
240 return result;
222 }
241 }
223
242
224 int nbMaxVariables() const
243 int nbMaxVariables() const
225 {
244 {
226 static auto result
245 static auto result
227 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
246 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
228 return result;
247 return result;
229 }
248 }
230
249
231 std::pair<int, int> operationDelays() const
250 std::pair<int, int> operationDelays() const
232 {
251 {
233 static auto result
252 static auto result
234 = m_Properties
253 = m_Properties
235 .value(OPERATION_DELAY_BOUNDS_PROPERTY, OPERATION_DELAY_BOUNDS_DEFAULT_VALUE)
254 .value(OPERATION_DELAY_BOUNDS_PROPERTY, OPERATION_DELAY_BOUNDS_DEFAULT_VALUE)
236 .value<std::pair<int, int> >();
255 .value<std::pair<int, int> >();
237 return result;
256 return result;
238 }
257 }
239
258
240 WeightedOperationsPool operationsPool() const
259 WeightedOperationsPool operationsPool() const
241 {
260 {
242 static auto result = createOperationsPool(
261 static auto result = createOperationsPool(
243 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
262 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
244 .value<WeightedOperationsTypes>());
263 .value<WeightedOperationsTypes>());
245 return result;
264 return result;
246 }
265 }
247
266
248 Validators validators() const
267 Validators validators() const
249 {
268 {
250 static auto result
269 static auto result
251 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
270 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
252 .value<ValidatorsTypes>());
271 .value<ValidatorsTypes>());
253 return result;
272 return result;
254 }
273 }
255
274
275 std::pair<int, int> validationFrequencies() const
276 {
277 static auto result = m_Properties
278 .value(VALIDATION_FREQUENCY_BOUNDS_PROPERTY,
279 VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE)
280 .value<std::pair<int, int> >();
281 return result;
282 }
283
256 VariableController &m_VariableController;
284 VariableController &m_VariableController;
257 Properties m_Properties;
285 Properties m_Properties;
258 FuzzingState m_FuzzingState;
286 FuzzingState m_FuzzingState;
259 };
287 };
260
288
261 } // namespace
289 } // namespace
262
290
263 class TestAmdaFuzzing : public QObject {
291 class TestAmdaFuzzing : public QObject {
264 Q_OBJECT
292 Q_OBJECT
265
293
266 private slots:
294 private slots:
267 /// Input data for @sa testFuzzing()
295 /// Input data for @sa testFuzzing()
268 void testFuzzing_data();
296 void testFuzzing_data();
269 void testFuzzing();
297 void testFuzzing();
270 };
298 };
271
299
272 void TestAmdaFuzzing::testFuzzing_data()
300 void TestAmdaFuzzing::testFuzzing_data()
273 {
301 {
274 // ////////////// //
302 // ////////////// //
275 // Test structure //
303 // Test structure //
276 // ////////////// //
304 // ////////////// //
277
305
278 QTest::addColumn<Properties>("properties"); // Properties for random test
306 QTest::addColumn<Properties>("properties"); // Properties for random test
279
307
280 // ////////// //
308 // ////////// //
281 // Test cases //
309 // Test cases //
282 // ////////// //
310 // ////////// //
283
311
284 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
312 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
285 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
313 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
286
314
287 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
315 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
288 // QVariant
316 // QVariant
289 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
317 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
290
318
291 QTest::newRow("fuzzingTest") << Properties{
319 QTest::newRow("fuzzingTest") << Properties{
292 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
320 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
293 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
321 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
294 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
322 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
295 }
323 }
296
324
297 void TestAmdaFuzzing::testFuzzing()
325 void TestAmdaFuzzing::testFuzzing()
298 {
326 {
299 QFETCH(Properties, properties);
327 QFETCH(Properties, properties);
300
328
301 // Sets cache property
329 // Sets cache property
302 QSettings settings{};
330 QSettings settings{};
303 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
331 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
304 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
332 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
305 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
333 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
306
334
307 auto &variableController = sqpApp->variableController();
335 auto &variableController = sqpApp->variableController();
308 auto &timeController = sqpApp->timeController();
336 auto &timeController = sqpApp->timeController();
309
337
310 // Generates random initial range (bounded to max range)
338 // Generates random initial range (bounded to max range)
311 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
339 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
312 .value<SqpRange>();
340 .value<SqpRange>();
313
341
314 QVERIFY(maxRange != INVALID_RANGE);
342 QVERIFY(maxRange != INVALID_RANGE);
315
343
316 auto initialRangeStart
344 auto initialRangeStart
317 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
345 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
318 auto initialRangeEnd
346 auto initialRangeEnd
319 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
347 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
320 if (initialRangeStart > initialRangeEnd) {
348 if (initialRangeStart > initialRangeEnd) {
321 std::swap(initialRangeStart, initialRangeEnd);
349 std::swap(initialRangeStart, initialRangeEnd);
322 }
350 }
323
351
324 // Sets initial range on time controller
352 // Sets initial range on time controller
325 SqpRange initialRange{initialRangeStart, initialRangeEnd};
353 SqpRange initialRange{initialRangeStart, initialRangeEnd};
326 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
354 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
327 timeController.onTimeToUpdate(initialRange);
355 timeController.onTimeToUpdate(initialRange);
328 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
356 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
329
357
330 FuzzingTest test{variableController, properties};
358 FuzzingTest test{variableController, properties};
331 test.execute();
359 test.execute();
332 }
360 }
333
361
334 int main(int argc, char *argv[])
362 int main(int argc, char *argv[])
335 {
363 {
336 QLoggingCategory::setFilterRules(
364 QLoggingCategory::setFilterRules(
337 "*.warning=false\n"
365 "*.warning=false\n"
338 "*.info=false\n"
366 "*.info=false\n"
339 "*.debug=false\n"
367 "*.debug=false\n"
340 "FuzzingOperations.info=true\n"
368 "FuzzingOperations.info=true\n"
341 "FuzzingValidators.info=true\n"
369 "FuzzingValidators.info=true\n"
342 "TestAmdaFuzzing.info=true\n");
370 "TestAmdaFuzzing.info=true\n");
343
371
344 SqpApplication app{argc, argv};
372 SqpApplication app{argc, argv};
345 SqpApplication::setOrganizationName("LPP");
373 SqpApplication::setOrganizationName("LPP");
346 SqpApplication::setOrganizationDomain("lpp.fr");
374 SqpApplication::setOrganizationDomain("lpp.fr");
347 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
375 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
348 app.setAttribute(Qt::AA_Use96Dpi, true);
376 app.setAttribute(Qt::AA_Use96Dpi, true);
349 TestAmdaFuzzing testObject{};
377 TestAmdaFuzzing testObject{};
350 QTEST_SET_MAIN_SOURCE_PATH
378 QTEST_SET_MAIN_SOURCE_PATH
351 return QTest::qExec(&testObject, argc, argv);
379 return QTest::qExec(&testObject, argc, argv);
352 }
380 }
353
381
354 #include "TestAmdaFuzzing.moc"
382 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now