##// END OF EJS Templates
Modif test fuzzing to enable custom test on specific operation
perrinel -
r1388:ed9e8c09ce2a
parent child
Show More
@@ -1,118 +1,119
1 1 #include "FuzzingDefs.h"
2 2
3 3 const QString ACQUISITION_TIMEOUT_PROPERTY = QStringLiteral("acquisitionTimeout");
4 4 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
5 5 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
6 6 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
7 7 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
8 8 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
9 9 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
10 10 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
11 11 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
12 12 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
13 13 const QString OPERATION_DELAY_BOUNDS_PROPERTY = QStringLiteral("operationDelays");
14 14 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
15 15 const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY = QStringLiteral("validationFrequencyBounds");
16 const QString CUSTOM_OPERATIONS_PROPERTY = QStringLiteral("customOperations");
16 17
17 18 // //////////// //
18 19 // FuzzingState //
19 20 // //////////// //
20 21
21 22 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
22 23 {
23 24 return m_SyncGroupsPool.at(id);
24 25 }
25 26
26 27 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
27 28 {
28 29 return m_SyncGroupsPool.at(id);
29 30 }
30 31
31 32 const VariableState &FuzzingState::variableState(VariableId id) const
32 33 {
33 34 return m_VariablesPool.at(id);
34 35 }
35 36
36 37 VariableState &FuzzingState::variableState(VariableId id)
37 38 {
38 39 return m_VariablesPool.at(id);
39 40 }
40 41
41 42 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
42 43 {
43 44 auto end = m_SyncGroupsPool.cend();
44 45 auto it
45 46 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
46 47 const auto &syncGroup = syncGroupEntry.second;
47 48 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
48 49 });
49 50
50 51 return it != end ? it->first : SyncGroupId{};
51 52 }
52 53
53 54 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
54 55 {
55 56 std::vector<SyncGroupId> result{};
56 57
57 58 for (const auto &entry : m_SyncGroupsPool) {
58 59 result.push_back(entry.first);
59 60 }
60 61
61 62 return result;
62 63 }
63 64
64 65 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
65 66 {
66 67 if (syncGroupId.isNull()) {
67 68 return;
68 69 }
69 70
70 71 // Registers variable into sync group
71 72 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
72 73 auto &variableState = m_VariablesPool.at(variableId);
73 74 syncGroup.m_Variables.insert(variableId);
74 75 if (syncGroup.m_Variables.size() == 1) {
75 76 // If it's the first variable, sets the variable range as the sync group range
76 77 syncGroup.m_Range = variableState.m_Range;
77 78 }
78 79 else {
79 80 // If a variable is added to an existing group, sets its range to the group's range
80 81 variableState.m_Range = syncGroup.m_Range;
81 82 }
82 83 }
83 84
84 85 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
85 86 {
86 87 if (syncGroupId.isNull()) {
87 88 return;
88 89 }
89 90
90 91 // Unregisters variable from sync group: if there is no more variable in the group, resets the
91 92 // range
92 93 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
93 94 syncGroup.m_Variables.erase(variableId);
94 95 if (syncGroup.m_Variables.empty()) {
95 96 syncGroup.m_Range = INVALID_RANGE;
96 97 }
97 98 }
98 99
99 100 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
100 101 {
101 102 auto syncGroupId = this->syncGroupId(variableId);
102 103
103 104 // Retrieves the variables to update:
104 105 // - if the variable is synchronized to others, updates the range of the group and of all
105 106 // synchronized variables
106 107 // - otherwise, updates only the variable
107 108 if (syncGroupId.isNull()) {
108 109 m_VariablesPool.at(variableId).m_Range = newRange;
109 110 }
110 111 else {
111 112 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
112 113 syncGroup.m_Range = newRange;
113 114
114 115 for (const auto &variableId : syncGroup.m_Variables) {
115 116 m_VariablesPool.at(variableId).m_Range = newRange;
116 117 }
117 118 }
118 119 }
@@ -1,128 +1,131
1 1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 2 #define SCIQLOP_FUZZINGDEFS_H
3 3
4 4 #include <Data/SqpRange.h>
5 5
6 6 #include <QString>
7 7 #include <QUuid>
8 8 #include <QVariantHash>
9 9
10 10 #include <memory>
11 11 #include <set>
12 12
13 13 // /////// //
14 14 // Aliases //
15 15 // /////// //
16 16
17 17 using MetadataPool = std::vector<QVariantHash>;
18 18 Q_DECLARE_METATYPE(MetadataPool)
19 19
20 20 using Properties = QVariantHash;
21 21
22 22 // ///////// //
23 23 // Constants //
24 24 // ///////// //
25 25
26 26 /// Timeout set for data acquisition for an operation (in ms)
27 27 extern const QString ACQUISITION_TIMEOUT_PROPERTY;
28 28
29 29 /// Max number of operations to generate
30 30 extern const QString NB_MAX_OPERATIONS_PROPERTY;
31 31
32 32 /// Max number of sync groups to create through operations
33 33 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
34 34
35 35 /// Max number of variables to manipulate through operations
36 36 extern const QString NB_MAX_VARIABLES_PROPERTY;
37 37
38 38 /// Set of operations available for the test
39 39 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
40 40
41 41 /// Tolerance used for variable's cache (in ratio)
42 42 extern const QString CACHE_TOLERANCE_PROPERTY;
43 43
44 44 /// Range with which the timecontroller is initialized
45 45 extern const QString INITIAL_RANGE_PROPERTY;
46 46
47 47 /// Max range that an operation can reach
48 48 extern const QString MAX_RANGE_PROPERTY;
49 49
50 50 /// Set of metadata that can be associated to a variable
51 51 extern const QString METADATA_POOL_PROPERTY;
52 52
53 53 /// Provider used to retrieve data
54 54 extern const QString PROVIDER_PROPERTY;
55 55
56 56 /// Min/max times left for an operation to execute
57 57 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
58 58
59 59 /// Validators used to validate an operation
60 60 extern const QString VALIDATORS_PROPERTY;
61 61
62 62 /// Min/max number of operations to execute before calling validation of the current test's state
63 63 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
64 64
65 /// Custom operations to execute instead of random operations
66 extern const QString CUSTOM_OPERATIONS_PROPERTY;
67
65 68 // /////// //
66 69 // Structs //
67 70 // /////// //
68 71
69 72 class Variable;
70 73 struct VariableState {
71 74 std::shared_ptr<Variable> m_Variable{nullptr};
72 75 SqpRange m_Range{INVALID_RANGE};
73 76 };
74 77
75 78 using VariableId = int;
76 79 using VariablesPool = std::map<VariableId, VariableState>;
77 80
78 81 /**
79 82 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
80 83 * with each other, and the current range of the group (i.e. range of the last synchronized variable
81 84 * that has been moved)
82 85 */
83 86 struct SyncGroup {
84 87 std::set<VariableId> m_Variables{};
85 88 SqpRange m_Range{INVALID_RANGE};
86 89 };
87 90
88 91 using SyncGroupId = QUuid;
89 92 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
90 93
91 94 /**
92 95 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
93 96 * the test, as well as the synchronization status of these variables.
94 97 */
95 98 struct FuzzingState {
96 99 const SyncGroup &syncGroup(SyncGroupId id) const;
97 100 SyncGroup &syncGroup(SyncGroupId id);
98 101
99 102 const VariableState &variableState(VariableId id) const;
100 103 VariableState &variableState(VariableId id);
101 104
102 105 /// @return the identifier of the synchronization group in which the variable passed in
103 106 /// parameter is located. If the variable is not in any group, returns an invalid identifier
104 107 SyncGroupId syncGroupId(VariableId variableId) const;
105 108
106 109 /// @return the set of synchronization group identifiers
107 110 std::vector<SyncGroupId> syncGroupsIds() const;
108 111
109 112 /// Updates fuzzing state according to a variable synchronization
110 113 /// @param variableId the variable that is synchronized
111 114 /// @param syncGroupId the synchronization group
112 115 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
113 116
114 117 /// Updates fuzzing state according to a variable desynchronization
115 118 /// @param variableId the variable that is desynchronized
116 119 /// @param syncGroupId the synchronization group from which to remove the variable
117 120 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
118 121
119 122 /// Updates the range of a variable and all variables to which it is synchronized
120 123 /// @param the variable for which to affect the range
121 124 /// @param the range to affect
122 125 void updateRanges(VariableId variableId, const SqpRange &newRange);
123 126
124 127 VariablesPool m_VariablesPool;
125 128 SyncGroupsPool m_SyncGroupsPool;
126 129 };
127 130
128 131 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,395 +1,572
1 1 #include "FuzzingDefs.h"
2 2 #include "FuzzingOperations.h"
3 3 #include "FuzzingUtils.h"
4 4 #include "FuzzingValidators.h"
5 5
6 6 #include "AmdaProvider.h"
7 7
8 8 #include <Common/SignalWaiter.h>
9 9 #include <Network/NetworkController.h>
10 10 #include <Settings/SqpSettingsDefs.h>
11 11 #include <SqpApplication.h>
12 12 #include <Time/TimeController.h>
13 13 #include <Variable/Variable.h>
14 14 #include <Variable/VariableController.h>
15 15
16 16 #include <QLoggingCategory>
17 17 #include <QObject>
18 18 #include <QtTest>
19 19
20 20 #include <memory>
21 21
22 22 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
23 23
24 24 /**
25 25 * Macro used to generate a getter for a property in @sa FuzzingTest. The macro generates a static
26 26 * attribute that is initialized by searching in properties the property and use a default value if
27 27 * it's not present. Macro arguments are:
28 28 * - GETTER_NAME : name of the getter
29 29 * - PROPERTY_NAME: used to generate constants for property's name ({PROPERTY_NAME}_PROPERTY) and
30 30 * default value ({PROPERTY_NAME}_DEFAULT_VALUE)
31 31 * - TYPE : return type of the getter
32 32 */
33 33 // clang-format off
34 34 #define DECLARE_PROPERTY_GETTER(GETTER_NAME, PROPERTY_NAME, TYPE) \
35 35 TYPE GETTER_NAME() const \
36 36 { \
37 37 static auto result = m_Properties.value(PROPERTY_NAME##_PROPERTY, PROPERTY_NAME##_DEFAULT_VALUE).value<TYPE>(); \
38 38 return result; \
39 39 } \
40 40 // clang-format on
41 41
42 42 namespace {
43 43
44 44 // /////// //
45 45 // Aliases //
46 46 // /////// //
47 47
48 48 using IntPair = std::pair<int, int>;
49 49 using Weight = double;
50 50 using Weights = std::vector<Weight>;
51 51
52 52 struct OperationProperty {
53 53 Weight m_Weight{1.};
54 54 bool m_WaitAcquisition{false};
55 55 };
56 56
57 57 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
58 58 using VariablesOperations = std::vector<VariableOperation>;
59 59
60 struct CustomVariableOperation {
61 VariableOperation m_VariableOperation{};
62 bool m_WaitAcquisition{false};
63 };
64 using CustomVariablesOperations = std::vector<CustomVariableOperation>;
65
60 66 using OperationsTypes = std::map<FuzzingOperationType, OperationProperty>;
61 67 using OperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, OperationProperty>;
62 68
63 69 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
64 70
65 71 // ///////// //
66 72 // Constants //
67 73 // ///////// //
68 74
69 75 // Defaults values used when the associated properties have not been set for the test
70 76 const auto ACQUISITION_TIMEOUT_DEFAULT_VALUE = 30000;
71 77 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
72 78 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
73 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
79 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 2;
74 80 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(
75 OperationsTypes{{FuzzingOperationType::CREATE, {1., true}},
76 {FuzzingOperationType::DELETE, {0.1}}, // Delete operation is less frequent
81 OperationsTypes{{FuzzingOperationType::CREATE, {400., true}},
82 {FuzzingOperationType::DELETE, {0.0}}, // Delete operation is less frequent
77 83 {FuzzingOperationType::PAN_LEFT, {1.}},
78 84 {FuzzingOperationType::PAN_RIGHT, {1.}},
79 85 {FuzzingOperationType::ZOOM_IN, {1.}},
80 86 {FuzzingOperationType::ZOOM_OUT, {1.}},
81 {FuzzingOperationType::SYNCHRONIZE, {0.8}},
87 {FuzzingOperationType::SYNCHRONIZE, {4000.0}},
82 88 {FuzzingOperationType::DESYNCHRONIZE, {0.4}}});
83 89 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
84 90
85 91 /// Min/max delays between each operation (in ms)
86 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(100, 3000));
92 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(3000, 3000));
87 93
88 94 /// Validators for the tests (executed in the order in which they're defined)
89 95 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
90 96 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
91 97
92 98 /// Min/max number of operations to execute before calling validation
93 const auto VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(1, 10));
99 const auto VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(8, 8));
100
101
102 // /////// //////
103 // CUSTOM CASE //
104 // /////// //////
105
106 auto op = [](auto type){
107 return FuzzingOperationFactory::create(type);
108 };
109
110
111 const QVariant CUSTOM_CASE_ONE =QVariant::fromValue(CustomVariablesOperations{{{0, op(FuzzingOperationType::CREATE)}, true},
112 {{0, op(FuzzingOperationType::SYNCHRONIZE)}},
113 {{1, op(FuzzingOperationType::CREATE)}, true},
114 {{1, op(FuzzingOperationType::SYNCHRONIZE)}},
115 {{0, op(FuzzingOperationType::PAN_LEFT)}},
116 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
117 {{0, op(FuzzingOperationType::PAN_LEFT)}},
118 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
119 {{0, op(FuzzingOperationType::PAN_LEFT)}},
120 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
121 {{0, op(FuzzingOperationType::PAN_LEFT)}},
122 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
123 {{0, op(FuzzingOperationType::PAN_LEFT)}},
124 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
125 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
126 {{1, op(FuzzingOperationType::PAN_LEFT)}},
127 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
128 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
129 {{0, op(FuzzingOperationType::PAN_LEFT)}},
130 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
131 {{0, op(FuzzingOperationType::PAN_LEFT)}},
132 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
133 {{0, op(FuzzingOperationType::PAN_LEFT)}},
134 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
135 {{0, op(FuzzingOperationType::PAN_LEFT)}},
136 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
137 {{0, op(FuzzingOperationType::PAN_LEFT)}},
138 {{1, op(FuzzingOperationType::PAN_LEFT)}},
139 {{0, op(FuzzingOperationType::PAN_LEFT)}},
140 {{1, op(FuzzingOperationType::PAN_LEFT)}},
141 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
142 {{1, op(FuzzingOperationType::PAN_LEFT)}},
143 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
144 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
145 {{0, op(FuzzingOperationType::PAN_LEFT)}},
146 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
147 {{0, op(FuzzingOperationType::PAN_LEFT)}},
148 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
149 {{0, op(FuzzingOperationType::PAN_LEFT)}},
150 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
151 {{0, op(FuzzingOperationType::PAN_LEFT)}},
152 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
153 {{0, op(FuzzingOperationType::PAN_LEFT)}},
154 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
155 {{0, op(FuzzingOperationType::PAN_LEFT)}},
156 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
157 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
158 {{1, op(FuzzingOperationType::PAN_LEFT)}},
159 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
160 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
161 {{0, op(FuzzingOperationType::PAN_LEFT)}},
162 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
163 {{0, op(FuzzingOperationType::PAN_LEFT)}},
164 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
165 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
166 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
167 {{0, op(FuzzingOperationType::PAN_LEFT)}},
168 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
169 {{0, op(FuzzingOperationType::PAN_LEFT)}},
170 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
171 {{0, op(FuzzingOperationType::PAN_LEFT)}},
172 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
173 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
174 {{1, op(FuzzingOperationType::PAN_LEFT)}},
175 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
176 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
177 {{0, op(FuzzingOperationType::PAN_LEFT)}},
178 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
179 {{0, op(FuzzingOperationType::PAN_LEFT)}},
180 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
181 {{0, op(FuzzingOperationType::PAN_LEFT)}},
182 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
183 {{0, op(FuzzingOperationType::PAN_LEFT)}},
184 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
185 {{0, op(FuzzingOperationType::PAN_LEFT)}},
186 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
187 {{0, op(FuzzingOperationType::PAN_LEFT)}},
188 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
189 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
190 {{1, op(FuzzingOperationType::PAN_LEFT)}},
191 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
192 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
193 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
194 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
195 {{0, op(FuzzingOperationType::PAN_LEFT)}},
196 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
197 {{0, op(FuzzingOperationType::PAN_LEFT)}},
198 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
199 {{0, op(FuzzingOperationType::PAN_LEFT)}},
200 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
201 {{0, op(FuzzingOperationType::PAN_LEFT)}},
202 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
203 {{0, op(FuzzingOperationType::PAN_LEFT)}},
204 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
205 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
206 {{1, op(FuzzingOperationType::PAN_LEFT)}},
207 {{0, op(FuzzingOperationType::PAN_RIGHT)}},
208 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
209 {{0, op(FuzzingOperationType::PAN_LEFT)}},
210 {{1, op(FuzzingOperationType::PAN_RIGHT)}},
211 });
212
213 const QVariant CUSTOM_CASE_TWO =QVariant::fromValue(CustomVariablesOperations{{{0, op(FuzzingOperationType::CREATE)}, true},
214 {{0, op(FuzzingOperationType::SYNCHRONIZE)}},
215 {{1, op(FuzzingOperationType::CREATE)}, true},
216 {{1, op(FuzzingOperationType::SYNCHRONIZE)}},
217 {{0, op(FuzzingOperationType::ZOOM_IN)}},
218 {{1, op(FuzzingOperationType::ZOOM_IN)}},
219 {{0, op(FuzzingOperationType::ZOOM_IN)}},
220 {{1, op(FuzzingOperationType::ZOOM_OUT)}},
221 {{0, op(FuzzingOperationType::ZOOM_OUT)}},
222 {{1, op(FuzzingOperationType::ZOOM_OUT)}},
223 {{0, op(FuzzingOperationType::ZOOM_IN)}},
224 {{1, op(FuzzingOperationType::ZOOM_OUT)}},
225 {{0, op(FuzzingOperationType::ZOOM_IN)}},
226 {{0, op(FuzzingOperationType::ZOOM_OUT)}},
227 {{1, op(FuzzingOperationType::ZOOM_IN)}},
228 {{0, op(FuzzingOperationType::ZOOM_IN)}},
229 {{0, op(FuzzingOperationType::ZOOM_OUT)}},
230 {{1, op(FuzzingOperationType::ZOOM_IN)}},
231 {{0, op(FuzzingOperationType::ZOOM_IN)}},
232 {{0, op(FuzzingOperationType::ZOOM_OUT)}},
233 });
94 234
95 235 // /////// //
96 236 // Methods //
97 237 // /////// //
98 238
99 239 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
100 240 /// pairs that are valid (i.e. operation that can be executed on variable)
101 241 std::pair<VariablesOperations, Weights> availableOperations(const FuzzingState &fuzzingState,
102 242 const OperationsPool &operationsPool)
103 243 {
104 244 VariablesOperations result{};
105 245 Weights weights{};
106 246
107 247 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
108 248 auto variableId = variablesPoolEntry.first;
109 249
110 250 for (const auto &operationsPoolEntry : operationsPool) {
111 251 auto operation = operationsPoolEntry.first;
112 252 auto operationProperty = operationsPoolEntry.second;
113 253
114 254 // A pair is valid if the current operation can be executed on the current variable
115 255 if (operation->canExecute(variableId, fuzzingState)) {
116 256 result.push_back({variableId, operation});
117 257 weights.push_back(operationProperty.m_Weight);
118 258 }
119 259 }
120 260 }
121 261
122 262 return {result, weights};
123 263 }
124 264
125 265 OperationsPool createOperationsPool(const OperationsTypes &types)
126 266 {
127 267 OperationsPool result{};
128 268
129 269 std::transform(
130 270 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
131 271 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
132 272 });
133 273
134 274 return result;
135 275 }
136 276
137 277 Validators createValidators(const ValidatorsTypes &types)
138 278 {
139 279 Validators result{};
140 280
141 281 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
142 282 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
143 283
144 284 return result;
145 285 }
146 286
147 287 /**
148 288 * Validates all the variables' states passed in parameter, according to a set of validators
149 289 * @param variablesPool the variables' states
150 290 * @param validators the validators used for validation
151 291 */
152 292 void validate(const VariablesPool &variablesPool, const Validators &validators)
153 293 {
154 294 for (const auto &variablesPoolEntry : variablesPool) {
155 295 auto variableId = variablesPoolEntry.first;
156 296 const auto &variableState = variablesPoolEntry.second;
157 297
158 298 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
159 299 : QStringLiteral("null variable");
160 300 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
161 301 << variableId << "(" << variableMessage << ")...";
162 302
163 303 for (const auto &validator : validators) {
164 304 validator->validate(VariableState{variableState});
165 305 }
166 306
167 307 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
168 308 }
169 309 }
170 310
171 311 /**
172 312 * Class to run random tests
173 313 */
174 314 class FuzzingTest {
175 315 public:
176 316 explicit FuzzingTest(VariableController &variableController, Properties properties)
177 317 : m_VariableController{variableController},
178 318 m_Properties{std::move(properties)},
179 319 m_FuzzingState{}
180 320 {
181 321 // Inits variables pool: at init, all variables are null
182 322 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
183 323 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
184 324 }
185 325
186 326 // Inits sync groups and registers them into the variable controller
187 327 for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
188 328 auto syncGroupId = SyncGroupId::createUuid();
189 329 variableController.onAddSynchronizationGroupId(syncGroupId);
190 330 m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
191 331 }
192 332 }
193 333
194 334 void execute()
195 335 {
196 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
197 << nbMaxVariables() << "variable(s)...";
198
199 336
200 337 // Inits the count of the number of operations before the next validation
201 338 int nextValidationCounter = 0;
202 339 auto updateValidationCounter = [this, &nextValidationCounter]() {
203 340 nextValidationCounter = RandomGenerator::instance().generateInt(
204 341 validationFrequencies().first, validationFrequencies().second);
205 342 qCInfo(LOG_TestAmdaFuzzing()).noquote()
206 343 << "Next validation in " << nextValidationCounter << "operation(s)...";
207 344 };
208 345 updateValidationCounter();
209 346
347 // Get custom operations
348 auto customOperations = m_Properties.value(CUSTOM_OPERATIONS_PROPERTY).value<CustomVariablesOperations>();
349 auto isCustomTest = !customOperations.empty();
350
351 auto nbOperations = isCustomTest ? customOperations.size() : nbMaxOperations();
352
353 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbOperations << "operations on"
354 << nbMaxVariables() << "variable(s)...";
355
210 356 auto canExecute = true;
211 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
212 // Retrieves all operations that can be executed in the current context
213 VariablesOperations variableOperations{};
214 Weights weights{};
215 std::tie(variableOperations, weights)
216 = availableOperations(m_FuzzingState, operationsPool());
217
218 canExecute = !variableOperations.empty();
219 if (canExecute) {
220 --nextValidationCounter;
357 for (auto i = 0; i < nbOperations && canExecute; ++i) {
358 VariableOperation variableOperation{};
359 auto forceWait = false;
360
361 if(isCustomTest){
362 auto customOperation = customOperations.front();
363 variableOperation = customOperation.m_VariableOperation;
364 customOperations.erase(customOperations.begin());
365
366 canExecute = variableOperation.second->canExecute(variableOperation.first, m_FuzzingState);
367 forceWait = customOperation.m_WaitAcquisition;
368 } else {
369 // Retrieves all operations that can be executed in the current context
370 VariablesOperations variableOperations{};
371 Weights weights{};
372 std::tie(variableOperations, weights)
373 = availableOperations(m_FuzzingState, operationsPool());
221 374
222 375 // Of the operations available, chooses a random operation and executes it
223 auto variableOperation
376 variableOperation
224 377 = RandomGenerator::instance().randomChoice(variableOperations, weights);
378 canExecute = !variableOperations.empty();
379 forceWait = operationsPool().at(variableOperation.second).m_WaitAcquisition;
380 }
381
382 if (canExecute) {
383 --nextValidationCounter;
225 384
226 385 auto variableId = variableOperation.first;
227 386 auto fuzzingOperation = variableOperation.second;
228 387
229 388 auto waitAcquisition = nextValidationCounter == 0
230 || operationsPool().at(fuzzingOperation).m_WaitAcquisition;
389 || forceWait;
231 390
232 391 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
233 392 m_Properties);
234 393
235 394 if (waitAcquisition) {
236 395 qCDebug(LOG_TestAmdaFuzzing()) << "Waiting for acquisition to finish...";
237 396 SignalWaiter{m_VariableController, SIGNAL(acquisitionFinished())}.wait(
238 397 acquisitionTimeout());
239 398
240 399 // Validates variables
241 400 if (nextValidationCounter == 0) {
242 401 validate(m_FuzzingState.m_VariablesPool, validators());
243 402 updateValidationCounter();
244 403 }
245 404 }
246 405 else {
247 406 // Delays the next operation with a randomly generated time
248 407 auto delay = RandomGenerator::instance().generateInt(operationDelays().first,
249 408 operationDelays().second);
250 409 qCDebug(LOG_TestAmdaFuzzing())
251 410 << "Waiting " << delay << "ms before the next operation...";
252 411 QTest::qWait(delay);
253 412 }
254 413 }
255 414 else {
256 415 qCInfo(LOG_TestAmdaFuzzing()).noquote()
257 416 << "No more operations are available, the execution of the test will stop...";
258 417 }
259 418 }
260 419
261 420 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
262 421 }
263 422
264 423 private:
265 424 OperationsPool operationsPool() const
266 425 {
267 426 static auto result = createOperationsPool(
268 427 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
269 428 .value<OperationsTypes>());
270 429 return result;
271 430 }
272 431
273 432 Validators validators() const
274 433 {
275 434 static auto result
276 435 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
277 436 .value<ValidatorsTypes>());
278 437 return result;
279 438 }
280 439
281 440 DECLARE_PROPERTY_GETTER(nbMaxOperations, NB_MAX_OPERATIONS, int)
282 441 DECLARE_PROPERTY_GETTER(nbMaxSyncGroups, NB_MAX_SYNC_GROUPS, int)
283 442 DECLARE_PROPERTY_GETTER(nbMaxVariables, NB_MAX_VARIABLES, int)
284 443 DECLARE_PROPERTY_GETTER(operationDelays, OPERATION_DELAY_BOUNDS, IntPair)
285 444 DECLARE_PROPERTY_GETTER(validationFrequencies, VALIDATION_FREQUENCY_BOUNDS, IntPair)
286 445 DECLARE_PROPERTY_GETTER(acquisitionTimeout, ACQUISITION_TIMEOUT, int)
287 446
288 447 VariableController &m_VariableController;
289 448 Properties m_Properties;
290 449 FuzzingState m_FuzzingState;
291 450 };
292 451
293 452 } // namespace
294 453
295 454 Q_DECLARE_METATYPE(OperationsTypes)
455 Q_DECLARE_METATYPE(CustomVariablesOperations)
296 456
297 457 class TestAmdaFuzzing : public QObject {
298 458 Q_OBJECT
299 459
300 460 private slots:
301 461 /// Input data for @sa testFuzzing()
302 462 void testFuzzing_data();
303 463 void testFuzzing();
304 464 };
305 465
306 466 void TestAmdaFuzzing::testFuzzing_data()
307 467 {
308 468 // Note: Comment this line to run fuzzing tests
309 QSKIP("Fuzzing tests are disabled by default");
469 // QSKIP("Fuzzing tests are disabled by default");
310 470
311 471 // ////////////// //
312 472 // Test structure //
313 473 // ////////////// //
314 474
315 475 QTest::addColumn<Properties>("properties"); // Properties for random test
316 476
317 477 // ////////// //
318 478 // Test cases //
319 479 // ////////// //
320 480
321 481 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
322 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
482 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "c1_b"}}};
323 483
324 484 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
325 485 // QVariant
326 486 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
327 487
328 QTest::newRow("fuzzingTest") << Properties{
329 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
330 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
331 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
488
489 // Case Custom one : Only lot of pan on two variables synchronized
490 // QTest::newRow("fuzzingTestPan") << Properties{
491 // {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
492 // {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
493 // {PROVIDER_PROPERTY, QVariant::fromValue(provider)},
494 // {CUSTOM_OPERATIONS_PROPERTY, CUSTOM_CASE_ONE}};
495
496 QTest::newRow("fuzzingTestZoom") << Properties{
497 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
498 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
499 {PROVIDER_PROPERTY, QVariant::fromValue(provider)},
500 {CUSTOM_OPERATIONS_PROPERTY, CUSTOM_CASE_TWO}};
501
502
503 // Fuzzing
504 // QTest::newRow("fuzzingTest") << Properties{
505 // {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
506 // {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
507 // {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
508
332 509 }
333 510
334 511 void TestAmdaFuzzing::testFuzzing()
335 512 {
336 513 QFETCH(Properties, properties);
337 514
338 515 // Sets cache property
339 516 QSettings settings{};
340 517 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
341 518 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
342 519 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
343 520
344 521 auto &variableController = sqpApp->variableController();
345 522 auto &timeController = sqpApp->timeController();
346 523
347 524 // Generates random initial range (bounded to max range)
348 525 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
349 526 .value<SqpRange>();
350 527
351 528 QVERIFY(maxRange != INVALID_RANGE);
352 529
353 530 auto initialRangeStart
354 531 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
355 532 auto initialRangeEnd
356 533 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
357 534 if (initialRangeStart > initialRangeEnd) {
358 535 std::swap(initialRangeStart, initialRangeEnd);
359 536 }
360 537
361 538 // Sets initial range on time controller
362 539 SqpRange initialRange{initialRangeStart, initialRangeEnd};
363 540 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
364 541 timeController.onTimeToUpdate(initialRange);
365 542 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
366 543
367 544 FuzzingTest test{variableController, properties};
368 545 test.execute();
369 546 }
370 547
371 548 int main(int argc, char *argv[])
372 549 {
373 550 // Increases the test function timeout (which is 5 minutes by default) to 12 hours
374 551 // https://stackoverflow.com/questions/42655932/setting-timeout-to-qt-test
375 552 qputenv("QTEST_FUNCTION_TIMEOUT", QByteArray::number(12*60*60*1000));
376 553
377 554 QLoggingCategory::setFilterRules(
378 555 "*.warning=false\n"
379 556 "*.info=false\n"
380 557 "*.debug=false\n"
381 558 "FuzzingOperations.info=true\n"
382 559 "FuzzingValidators.info=true\n"
383 560 "TestAmdaFuzzing.info=true\n");
384 561
385 562 SqpApplication app{argc, argv};
386 563 SqpApplication::setOrganizationName("LPP");
387 564 SqpApplication::setOrganizationDomain("lpp.fr");
388 565 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
389 566 app.setAttribute(Qt::AA_Use96Dpi, true);
390 567 TestAmdaFuzzing testObject{};
391 568 QTEST_SET_MAIN_SOURCE_PATH
392 569 return QTest::qExec(&testObject, argc, argv);
393 570 }
394 571
395 572 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now