##// END OF EJS Templates
Defines VariableState struct (3)...
Alexandre Leroux -
r1222:70ee007bcdd0
parent child
Show More
@@ -1,269 +1,268
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
4
5 #include "AmdaProvider.h"
5 #include "AmdaProvider.h"
6
6
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
11 #include <Variable/VariableController.h>
11
12
12 #include <QLoggingCategory>
13 #include <QLoggingCategory>
13 #include <QObject>
14 #include <QObject>
14 #include <QtTest>
15 #include <QtTest>
15
16
16 #include <memory>
17 #include <memory>
17
18
18 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
19 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
19
20
20 namespace {
21 namespace {
21
22
22 // /////// //
23 // /////// //
23 // Aliases //
24 // Aliases //
24 // /////// //
25 // /////// //
25
26
26 using VariableId = int;
27 using VariableId = int;
27 using Weight = double;
28 using Weight = double;
28 using Weights = std::vector<Weight>;
29 using Weights = std::vector<Weight>;
29
30
30 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
31 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
31 using VariablesOperations = std::vector<VariableOperation>;
32 using VariablesOperations = std::vector<VariableOperation>;
32
33
33 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
34 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
34 using VariablesPool = std::map<VariableId, std::shared_ptr<Variable> >;
35 using VariablesPool = std::map<VariableId, VariableState>;
35
36
36 // ///////// //
37 // ///////// //
37 // Constants //
38 // Constants //
38 // ///////// //
39 // ///////// //
39
40
40 // Defaults values used when the associated properties have not been set for the test
41 // Defaults values used when the associated properties have not been set for the test
41 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
42 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
42 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
43 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
43 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
44 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
44 = QVariant::fromValue(WeightedOperationsTypes{{FuzzingOperationType::CREATE, 1.},
45 = QVariant::fromValue(WeightedOperationsTypes{{FuzzingOperationType::CREATE, 1.},
45 {FuzzingOperationType::PAN_LEFT, 1.},
46 {FuzzingOperationType::PAN_LEFT, 1.},
46 {FuzzingOperationType::PAN_RIGHT, 1.},
47 {FuzzingOperationType::PAN_RIGHT, 1.},
47 {FuzzingOperationType::ZOOM_IN, 1.},
48 {FuzzingOperationType::ZOOM_IN, 1.},
48 {FuzzingOperationType::ZOOM_OUT, 1.}});
49 {FuzzingOperationType::ZOOM_OUT, 1.}});
49
50
50 /// Delay between each operation (in ms)
51 /// Delay between each operation (in ms)
51 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
52 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
52
53
53 // /////// //
54 // /////// //
54 // Methods //
55 // Methods //
55 // /////// //
56 // /////// //
56
57
57 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
58 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
58 /// pairs that are valid (i.e. operation that can be executed on variable)
59 /// pairs that are valid (i.e. operation that can be executed on variable)
59 std::pair<VariablesOperations, Weights>
60 std::pair<VariablesOperations, Weights>
60 availableOperations(const VariablesPool &variablesPool,
61 availableOperations(const VariablesPool &variablesPool,
61 const WeightedOperationsPool &operationsPool)
62 const WeightedOperationsPool &operationsPool)
62 {
63 {
63 VariablesOperations result{};
64 VariablesOperations result{};
64 Weights weights{};
65 Weights weights{};
65
66
66 for (const auto &variablesPoolEntry : variablesPool) {
67 for (const auto &variablesPoolEntry : variablesPool) {
67 auto variableId = variablesPoolEntry.first;
68 auto variableId = variablesPoolEntry.first;
68 auto variable = variablesPoolEntry.second;
69 const auto &variableState = variablesPoolEntry.second;
69
70
70 for (const auto &operationsPoolEntry : operationsPool) {
71 for (const auto &operationsPoolEntry : operationsPool) {
71 auto operation = operationsPoolEntry.first;
72 auto operation = operationsPoolEntry.first;
72 auto weight = operationsPoolEntry.second;
73 auto weight = operationsPoolEntry.second;
73
74
74 // A pair is valid if the current operation can be executed on the current variable
75 // A pair is valid if the current operation can be executed on the current variable
75 if (operation->canExecute(variable)) {
76 if (operation->canExecute(variableState)) {
76 result.push_back({variableId, operation});
77 result.push_back({variableId, operation});
77 weights.push_back(weight);
78 weights.push_back(weight);
78 }
79 }
79 }
80 }
80 }
81 }
81
82
82 return {result, weights};
83 return {result, weights};
83 }
84 }
84
85
85 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
86 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
86 {
87 {
87 WeightedOperationsPool result{};
88 WeightedOperationsPool result{};
88
89
89 std::transform(
90 std::transform(
90 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
91 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
91 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
92 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
92 });
93 });
93
94
94 return result;
95 return result;
95 }
96 }
96
97
97 /**
98 /**
98 * Class to run random tests
99 * Class to run random tests
99 */
100 */
100 class FuzzingTest {
101 class FuzzingTest {
101 public:
102 public:
102 explicit FuzzingTest(VariableController &variableController, Properties properties)
103 explicit FuzzingTest(VariableController &variableController, Properties properties)
103 : m_VariableController{variableController},
104 : m_VariableController{variableController},
104 m_Properties{std::move(properties)},
105 m_Properties{std::move(properties)},
105 m_VariablesPool{}
106 m_VariablesPool{}
106 {
107 {
107 // Inits variables pool: at init, all variables are null
108 // Inits variables pool: at init, all variables are null
108 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
109 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
109 m_VariablesPool[variableId] = nullptr;
110 m_VariablesPool[variableId] = VariableState{};
110 }
111 }
111 }
112 }
112
113
113 void execute()
114 void execute()
114 {
115 {
115 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
116 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
116 << nbMaxVariables() << "variable(s)...";
117 << nbMaxVariables() << "variable(s)...";
117
118
118 auto canExecute = true;
119 auto canExecute = true;
119 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
120 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
120 // Retrieves all operations that can be executed in the current context
121 // Retrieves all operations that can be executed in the current context
121 VariablesOperations variableOperations{};
122 VariablesOperations variableOperations{};
122 Weights weights{};
123 Weights weights{};
123 std::tie(variableOperations, weights)
124 std::tie(variableOperations, weights)
124 = availableOperations(m_VariablesPool, operationsPool());
125 = availableOperations(m_VariablesPool, operationsPool());
125
126
126 canExecute = !variableOperations.empty();
127 canExecute = !variableOperations.empty();
127 if (canExecute) {
128 if (canExecute) {
128 // Of the operations available, chooses a random operation and executes it
129 // Of the operations available, chooses a random operation and executes it
129 auto variableOperation
130 auto variableOperation
130 = RandomGenerator::instance().randomChoice(variableOperations, weights);
131 = RandomGenerator::instance().randomChoice(variableOperations, weights);
131
132
132 auto variableId = variableOperation.first;
133 auto variableId = variableOperation.first;
133 auto variable = m_VariablesPool.at(variableId);
134 auto &variableState = m_VariablesPool.at(variableId);
134 auto fuzzingOperation = variableOperation.second;
135 auto fuzzingOperation = variableOperation.second;
135
136
136 fuzzingOperation->execute(variable, m_VariableController, m_Properties);
137 fuzzingOperation->execute(variableState, m_VariableController, m_Properties);
137 QTest::qWait(operationDelay());
138 QTest::qWait(operationDelay());
138
139
139 // Updates variable pool with the new state of the variable after operation
140 m_VariablesPool[variableId] = variable;
141 }
140 }
142 else {
141 else {
143 qCInfo(LOG_TestAmdaFuzzing())
142 qCInfo(LOG_TestAmdaFuzzing())
144 << "No more operations are available, the execution of the test will stop...";
143 << "No more operations are available, the execution of the test will stop...";
145 }
144 }
146 }
145 }
147
146
148 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
147 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
149 }
148 }
150
149
151 private:
150 private:
152 int nbMaxOperations() const
151 int nbMaxOperations() const
153 {
152 {
154 static auto result
153 static auto result
155 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
154 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
156 .toInt();
155 .toInt();
157 return result;
156 return result;
158 }
157 }
159
158
160 int nbMaxVariables() const
159 int nbMaxVariables() const
161 {
160 {
162 static auto result
161 static auto result
163 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
162 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
164 return result;
163 return result;
165 }
164 }
166
165
167 int operationDelay() const
166 int operationDelay() const
168 {
167 {
169 static auto result
168 static auto result
170 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
169 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
171 return result;
170 return result;
172 }
171 }
173
172
174 WeightedOperationsPool operationsPool() const
173 WeightedOperationsPool operationsPool() const
175 {
174 {
176 static auto result = createOperationsPool(
175 static auto result = createOperationsPool(
177 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
176 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
178 .value<WeightedOperationsTypes>());
177 .value<WeightedOperationsTypes>());
179 return result;
178 return result;
180 }
179 }
181
180
182 VariableController &m_VariableController;
181 VariableController &m_VariableController;
183 Properties m_Properties;
182 Properties m_Properties;
184 VariablesPool m_VariablesPool;
183 VariablesPool m_VariablesPool;
185 };
184 };
186
185
187 } // namespace
186 } // namespace
188
187
189 class TestAmdaFuzzing : public QObject {
188 class TestAmdaFuzzing : public QObject {
190 Q_OBJECT
189 Q_OBJECT
191
190
192 private slots:
191 private slots:
193 /// Input data for @sa testFuzzing()
192 /// Input data for @sa testFuzzing()
194 void testFuzzing_data();
193 void testFuzzing_data();
195 void testFuzzing();
194 void testFuzzing();
196 };
195 };
197
196
198 void TestAmdaFuzzing::testFuzzing_data()
197 void TestAmdaFuzzing::testFuzzing_data()
199 {
198 {
200 // ////////////// //
199 // ////////////// //
201 // Test structure //
200 // Test structure //
202 // ////////////// //
201 // ////////////// //
203
202
204 QTest::addColumn<Properties>("properties"); // Properties for random test
203 QTest::addColumn<Properties>("properties"); // Properties for random test
205
204
206 // ////////// //
205 // ////////// //
207 // Test cases //
206 // Test cases //
208 // ////////// //
207 // ////////// //
209
208
210 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
209 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
211 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
210 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
212
211
213 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
212 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
214 // QVariant
213 // QVariant
215 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
214 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
216
215
217 QTest::newRow("fuzzingTest") << Properties{
216 QTest::newRow("fuzzingTest") << Properties{
218 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
217 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
219 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
218 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
220 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
219 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
221 }
220 }
222
221
223 void TestAmdaFuzzing::testFuzzing()
222 void TestAmdaFuzzing::testFuzzing()
224 {
223 {
225 QFETCH(Properties, properties);
224 QFETCH(Properties, properties);
226
225
227 auto &variableController = sqpApp->variableController();
226 auto &variableController = sqpApp->variableController();
228 auto &timeController = sqpApp->timeController();
227 auto &timeController = sqpApp->timeController();
229
228
230 // Generates random initial range (bounded to max range)
229 // Generates random initial range (bounded to max range)
231 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
230 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
232 .value<SqpRange>();
231 .value<SqpRange>();
233
232
234 QVERIFY(maxRange != INVALID_RANGE);
233 QVERIFY(maxRange != INVALID_RANGE);
235
234
236 auto initialRangeStart
235 auto initialRangeStart
237 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
236 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
238 auto initialRangeEnd
237 auto initialRangeEnd
239 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
238 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
240 if (initialRangeStart > initialRangeEnd) {
239 if (initialRangeStart > initialRangeEnd) {
241 std::swap(initialRangeStart, initialRangeEnd);
240 std::swap(initialRangeStart, initialRangeEnd);
242 }
241 }
243
242
244 // Sets initial range on time controller
243 // Sets initial range on time controller
245 SqpRange initialRange{initialRangeStart, initialRangeEnd};
244 SqpRange initialRange{initialRangeStart, initialRangeEnd};
246 qCInfo(LOG_TestAmdaFuzzing()) << "Setting initial range to" << initialRange << "...";
245 qCInfo(LOG_TestAmdaFuzzing()) << "Setting initial range to" << initialRange << "...";
247 timeController.onTimeToUpdate(initialRange);
246 timeController.onTimeToUpdate(initialRange);
248
247
249 FuzzingTest test{variableController, properties};
248 FuzzingTest test{variableController, properties};
250 test.execute();
249 test.execute();
251 }
250 }
252
251
253 int main(int argc, char *argv[])
252 int main(int argc, char *argv[])
254 {
253 {
255 QLoggingCategory::setFilterRules(
254 QLoggingCategory::setFilterRules(
256 "*.warning=false\n"
255 "*.warning=false\n"
257 "*.info=false\n"
256 "*.info=false\n"
258 "*.debug=false\n"
257 "*.debug=false\n"
259 "FuzzingOperations.info=true\n"
258 "FuzzingOperations.info=true\n"
260 "TestAmdaFuzzing.info=true\n");
259 "TestAmdaFuzzing.info=true\n");
261
260
262 SqpApplication app{argc, argv};
261 SqpApplication app{argc, argv};
263 app.setAttribute(Qt::AA_Use96Dpi, true);
262 app.setAttribute(Qt::AA_Use96Dpi, true);
264 TestAmdaFuzzing testObject{};
263 TestAmdaFuzzing testObject{};
265 QTEST_SET_MAIN_SOURCE_PATH
264 QTEST_SET_MAIN_SOURCE_PATH
266 return QTest::qExec(&testObject, argc, argv);
265 return QTest::qExec(&testObject, argc, argv);
267 }
266 }
268
267
269 #include "TestAmdaFuzzing.moc"
268 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now