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