##// END OF EJS Templates
Modification of the test for the new vc request kernel
perrinel -
r830:8991b585417a
parent child
Show More
@@ -1,551 +1,553
1 #include <QObject>
1 #include <QObject>
2 #include <QtTest>
2 #include <QtTest>
3
3
4 #include <memory>
4 #include <memory>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/ScalarSeries.h>
8 #include <Data/ScalarSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10 #include <Variable/Variable.h>
10 #include <Variable/Variable.h>
11 #include <Variable/VariableController.h>
11 #include <Variable/VariableController.h>
12 #include <Variable/VariableModel.h>
12 #include <Variable/VariableModel.h>
13
13
14 namespace {
14 namespace {
15
15
16 /// Delay after each operation on the variable before validating it (in ms)
16 /// Delay after each operation on the variable before validating it (in ms)
17 const auto OPERATION_DELAY = 100;
17 const auto OPERATION_DELAY = 100;
18
18
19 /**
19 /**
20 * Generates values according to a range. The value generated for a time t is the number of seconds
20 * Generates values according to a range. The value generated for a time t is the number of seconds
21 * of difference between t and a reference value (which is midnight -> 00:00:00)
21 * of difference between t and a reference value (which is midnight -> 00:00:00)
22 *
22 *
23 * Example: For a range between 00:00:10 and 00:00:20, the generated values are
23 * Example: For a range between 00:00:10 and 00:00:20, the generated values are
24 * {10,11,12,13,14,15,16,17,18,19,20}
24 * {10,11,12,13,14,15,16,17,18,19,20}
25 */
25 */
26 std::vector<double> values(const SqpRange &range)
26 std::vector<double> values(const SqpRange &range)
27 {
27 {
28 QTime referenceTime{0, 0};
28 QTime referenceTime{0, 0};
29
29
30 std::vector<double> result{};
30 std::vector<double> result{};
31
31
32 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
32 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
33 auto time = DateUtils::dateTime(i).time();
33 auto time = DateUtils::dateTime(i).time();
34 result.push_back(referenceTime.secsTo(time));
34 result.push_back(referenceTime.secsTo(time));
35 }
35 }
36
36
37 return result;
37 return result;
38 }
38 }
39
39
40 /// Provider used for the tests
40 /// Provider used for the tests
41 class TestProvider : public IDataProvider {
41 class TestProvider : public IDataProvider {
42 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
42 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
43
43
44 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
44 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
45 {
45 {
46 const auto &ranges = parameters.m_Times;
46 const auto &ranges = parameters.m_Times;
47
47
48 for (const auto &range : ranges) {
48 for (const auto &range : ranges) {
49 // Generates data series
49 // Generates data series
50 auto valuesData = values(range);
50 auto valuesData = values(range);
51
51
52 std::vector<double> xAxisData{};
52 std::vector<double> xAxisData{};
53 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
53 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
54 xAxisData.push_back(i);
54 xAxisData.push_back(i);
55 }
55 }
56
56
57 auto dataSeries = std::make_shared<ScalarSeries>(
57 auto dataSeries = std::make_shared<ScalarSeries>(
58 std::move(xAxisData), std::move(valuesData), Unit{"t", true}, Unit{});
58 std::move(xAxisData), std::move(valuesData), Unit{"t", true}, Unit{});
59
59
60 emit dataProvided(acqIdentifier, dataSeries, range);
60 emit dataProvided(acqIdentifier, dataSeries, range);
61 }
61 }
62 }
62 }
63
63
64 void requestDataAborting(QUuid acqIdentifier) override
64 void requestDataAborting(QUuid acqIdentifier) override
65 {
65 {
66 // Does nothing
66 // Does nothing
67 }
67 }
68 };
68 };
69
69
70 /**
70 /**
71 * Interface representing an operation performed on a variable controller.
71 * Interface representing an operation performed on a variable controller.
72 * This interface is used in tests to apply a set of operations and check the status of the
72 * This interface is used in tests to apply a set of operations and check the status of the
73 * controller after each operation
73 * controller after each operation
74 */
74 */
75 struct IOperation {
75 struct IOperation {
76 virtual ~IOperation() = default;
76 virtual ~IOperation() = default;
77 /// Executes the operation on the variable controller
77 /// Executes the operation on the variable controller
78 virtual void exec(VariableController &variableController) const = 0;
78 virtual void exec(VariableController &variableController) const = 0;
79 };
79 };
80
80
81 /**
81 /**
82 *Variable creation operation in the controller
82 *Variable creation operation in the controller
83 */
83 */
84 struct Create : public IOperation {
84 struct Create : public IOperation {
85 explicit Create(int index) : m_Index{index} {}
85 explicit Create(int index) : m_Index{index} {}
86
86
87 void exec(VariableController &variableController) const override
87 void exec(VariableController &variableController) const override
88 {
88 {
89 auto variable = variableController.createVariable(QString::number(m_Index), {},
89 auto variable = variableController.createVariable(QString::number(m_Index), {},
90 std::make_unique<TestProvider>());
90 std::make_unique<TestProvider>());
91 }
91 }
92
92
93 int m_Index; ///< The index of the variable to create in the controller
93 int m_Index; ///< The index of the variable to create in the controller
94 };
94 };
95
95
96 /**
96 /**
97 * Variable move/shift operation in the controller
97 * Variable move/shift operation in the controller
98 */
98 */
99 struct Move : public IOperation {
99 struct Move : public IOperation {
100 explicit Move(int index, const SqpRange &newRange, bool shift = false)
100 explicit Move(int index, const SqpRange &newRange, bool shift = false)
101 : m_Index{index}, m_NewRange{newRange}, m_Shift{shift}
101 : m_Index{index}, m_NewRange{newRange}, m_Shift{shift}
102 {
102 {
103 }
103 }
104
104
105 void exec(VariableController &variableController) const override
105 void exec(VariableController &variableController) const override
106 {
106 {
107 if (auto variable = variableController.variableModel()->variable(m_Index)) {
107 if (auto variable = variableController.variableModel()->variable(m_Index)) {
108 variableController.onRequestDataLoading({variable}, m_NewRange, !m_Shift);
108 variableController.onRequestDataLoading({variable}, m_NewRange, !m_Shift);
109 }
109 }
110 }
110 }
111
111
112 int m_Index; ///< The index of the variable to move
112 int m_Index; ///< The index of the variable to move
113 SqpRange m_NewRange; ///< The new range of the variable
113 SqpRange m_NewRange; ///< The new range of the variable
114 bool m_Shift; ///< Performs a shift (
114 bool m_Shift; ///< Performs a shift (
115 };
115 };
116
116
117 /**
117 /**
118 * Variable synchronization/desynchronization operation in the controller
118 * Variable synchronization/desynchronization operation in the controller
119 */
119 */
120 struct Synchronize : public IOperation {
120 struct Synchronize : public IOperation {
121 explicit Synchronize(int index, QUuid syncId, bool synchronize = true)
121 explicit Synchronize(int index, QUuid syncId, bool synchronize = true)
122 : m_Index{index}, m_SyncId{syncId}, m_Synchronize{synchronize}
122 : m_Index{index}, m_SyncId{syncId}, m_Synchronize{synchronize}
123 {
123 {
124 }
124 }
125
125
126 void exec(VariableController &variableController) const override
126 void exec(VariableController &variableController) const override
127 {
127 {
128 if (auto variable = variableController.variableModel()->variable(m_Index)) {
128 if (auto variable = variableController.variableModel()->variable(m_Index)) {
129 if (m_Synchronize) {
129 if (m_Synchronize) {
130 variableController.onAddSynchronized(variable, m_SyncId);
130 variableController.onAddSynchronized(variable, m_SyncId);
131 }
131 }
132 else {
132 else {
133 variableController.desynchronize(variable, m_SyncId);
133 variableController.desynchronize(variable, m_SyncId);
134 }
134 }
135 }
135 }
136 }
136 }
137
137
138 int m_Index; ///< The index of the variable to sync/desync
138 int m_Index; ///< The index of the variable to sync/desync
139 QUuid m_SyncId; ///< The synchronization group of the variable
139 QUuid m_SyncId; ///< The synchronization group of the variable
140 bool m_Synchronize; ///< Performs sync or desync operation
140 bool m_Synchronize; ///< Performs sync or desync operation
141 };
141 };
142
142
143 /**
143 /**
144 * Test Iteration
144 * Test Iteration
145 *
145 *
146 * A test iteration includes an operation to be performed, and a set of expected ranges after each
146 * A test iteration includes an operation to be performed, and a set of expected ranges after each
147 * operation. Each range is tested after the operation to ensure that:
147 * operation. Each range is tested after the operation to ensure that:
148 * - the range of the variable is the expected range
148 * - the range of the variable is the expected range
149 * - the data of the variable are those generated for the expected range
149 * - the data of the variable are those generated for the expected range
150 */
150 */
151 struct Iteration {
151 struct Iteration {
152 std::shared_ptr<IOperation> m_Operation; ///< Operation to perform
152 std::shared_ptr<IOperation> m_Operation; ///< Operation to perform
153 std::map<int, SqpRange> m_ExpectedRanges; ///< Expected ranges (by variable index)
153 std::map<int, SqpRange> m_ExpectedRanges; ///< Expected ranges (by variable index)
154 };
154 };
155
155
156 using Iterations = std::vector<Iteration>;
156 using Iterations = std::vector<Iteration>;
157
157
158 } // namespace
158 } // namespace
159
159
160 Q_DECLARE_METATYPE(Iterations)
160 Q_DECLARE_METATYPE(Iterations)
161
161
162 class TestVariableSync : public QObject {
162 class TestVariableSync : public QObject {
163 Q_OBJECT
163 Q_OBJECT
164
164
165 private slots:
165 private slots:
166 /// Input data for @sa testSync()
166 /// Input data for @sa testSync()
167 void testSync_data();
167 void testSync_data();
168
168
169 /// Input data for @sa testSyncWithAborting()
169 /// Input data for @sa testSyncWithAborting()
170 void testSyncWithAborting_data();
170 void testSyncWithAborting_data();
171
171
172 /// Tests synchronization between variables through several operations with aborting
172 /// Tests synchronization between variables through several operations with aborting
173 void testSyncWithAborting();
173 void testSyncWithAborting();
174
174
175 /// Tests synchronization between variables through several operations
175 /// Tests synchronization between variables through several operations
176 void testSync();
176 void testSync();
177 };
177 };
178
178
179 namespace {
179 namespace {
180
180
181 void testSyncCase1()
181 void testSyncCase1()
182 {
182 {
183 // Id used to synchronize variables in the controller
183 // Id used to synchronize variables in the controller
184 auto syncId = QUuid::createUuid();
184 auto syncId = QUuid::createUuid();
185
185
186 /// Generates a range according to a start time and a end time (the date is the same)
186 /// Generates a range according to a start time and a end time (the date is the same)
187 auto range = [](const QTime &startTime, const QTime &endTime) {
187 auto range = [](const QTime &startTime, const QTime &endTime) {
188 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
188 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
189 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
189 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
190 };
190 };
191
191
192 auto initialRange = range({12, 0}, {13, 0});
192 auto initialRange = range({12, 0}, {13, 0});
193
193
194 Iterations iterations{};
194 Iterations iterations{};
195 // Creates variables var0, var1 and var2
195 // Creates variables var0, var1 and var2
196 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
196 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
197 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
197 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
198 iterations.push_back(
198 iterations.push_back(
199 {std::make_shared<Create>(2), {{0, initialRange}, {1, initialRange}, {2, initialRange}}});
199 {std::make_shared<Create>(2), {{0, initialRange}, {1, initialRange}, {2, initialRange}}});
200
200
201 // Adds variables into the sync group (ranges don't need to be tested here)
201 // Adds variables into the sync group (ranges don't need to be tested here)
202 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
202 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
203 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
203 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
204 iterations.push_back({std::make_shared<Synchronize>(2, syncId)});
204 iterations.push_back({std::make_shared<Synchronize>(2, syncId)});
205
205
206 // Moves var0: ranges of var0, var1 and var2 change
206 // Moves var0: ranges of var0, var1 and var2 change
207 auto newRange = range({12, 30}, {13, 30});
207 auto newRange = range({12, 30}, {13, 30});
208 iterations.push_back(
208 iterations.push_back(
209 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
209 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
210
210
211 // Moves var1: ranges of var0, var1 and var2 change
211 // Moves var1: ranges of var0, var1 and var2 change
212 newRange = range({13, 0}, {14, 0});
212 newRange = range({13, 0}, {14, 0});
213 iterations.push_back(
213 iterations.push_back(
214 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
214 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
215
215
216 // Moves var2: ranges of var0, var1 and var2 change
216 // Moves var2: ranges of var0, var1 and var2 change
217 newRange = range({13, 30}, {14, 30});
217 newRange = range({13, 30}, {14, 30});
218 iterations.push_back(
218 iterations.push_back(
219 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
219 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
220
220
221 // Desyncs var2 and moves var0:
221 // Desyncs var2 and moves var0:
222 // - ranges of var0 and var1 change
222 // - ranges of var0 and var1 change
223 // - range of var2 doesn't change anymore
223 // - range of var2 doesn't change anymore
224 auto var2Range = newRange;
224 auto var2Range = newRange;
225 newRange = range({13, 45}, {14, 45});
225 newRange = range({13, 45}, {14, 45});
226 iterations.push_back({std::make_shared<Synchronize>(2, syncId, false)});
226 iterations.push_back({std::make_shared<Synchronize>(2, syncId, false)});
227 iterations.push_back(
227 iterations.push_back(
228 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, var2Range}}});
228 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, var2Range}}});
229
229
230 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
230 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
231 auto var1Range = newRange;
231 auto var1Range = newRange;
232 newRange = range({14, 45}, {15, 45});
232 newRange = range({14, 45}, {15, 45});
233 iterations.push_back({std::make_shared<Move>(0, newRange, true),
233 iterations.push_back({std::make_shared<Move>(0, newRange, true),
234 {{0, newRange}, {1, var1Range}, {2, var2Range}}});
234 {{0, newRange}, {1, var1Range}, {2, var2Range}}});
235
235
236 // Moves var0 through several operations:
236 // Moves var0 through several operations:
237 // - range of var0 changes
237 // - range of var0 changes
238 // - range or var1 changes according to the previous shift (one hour)
238 // - range or var1 changes according to the previous shift (one hour)
239 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
239 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
240 iterations.push_back(
240 iterations.push_back(
241 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
241 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
242 };
242 };
243
243
244 // Pan left
244 // Pan left
245 moveVar0(range({14, 30}, {15, 30}), range({13, 30}, {14, 30}));
245 moveVar0(range({14, 30}, {15, 30}), range({13, 30}, {14, 30}));
246 // Pan right
246 // Pan right
247 moveVar0(range({16, 0}, {17, 0}), range({15, 0}, {16, 0}));
247 moveVar0(range({16, 0}, {17, 0}), range({15, 0}, {16, 0}));
248 // Zoom in
248 // Zoom in
249 moveVar0(range({16, 30}, {16, 45}), range({15, 30}, {15, 45}));
249 moveVar0(range({16, 30}, {16, 45}), range({15, 30}, {15, 45}));
250 // Zoom out
250 // Zoom out
251 moveVar0(range({16, 15}, {17, 0}), range({15, 15}, {16, 0}));
251 moveVar0(range({16, 15}, {17, 0}), range({15, 15}, {16, 0}));
252
252
253 QTest::newRow("sync1") << syncId << initialRange << std::move(iterations) << 200;
253 QTest::newRow("sync1") << syncId << initialRange << std::move(iterations) << 200;
254 }
254 }
255
255
256 void testSyncCase1WithAborting()
256 void testSyncCase1WithAborting()
257 {
257 {
258 // Id used to synchronize variables in the controller
258 // Id used to synchronize variables in the controller
259 auto syncId = QUuid::createUuid();
259 auto syncId = QUuid::createUuid();
260
260
261 /// Generates a range according to a start time and a end time (the date is the same)
261 /// Generates a range according to a start time and a end time (the date is the same)
262 auto range = [](const QTime &startTime, const QTime &endTime) {
262 auto range = [](const QTime &startTime, const QTime &endTime) {
263 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
263 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
264 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
264 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
265 };
265 };
266
266
267 auto initialRange = range({12, 0}, {13, 0});
267 auto initialRange = range({12, 0}, {13, 0});
268
268
269 Iterations creations{};
269 Iterations creations{};
270 // Creates variables var0, var1 and var2
270 // Creates variables var0, var1 and var2
271 creations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
271 creations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
272 creations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
272 creations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
273
273
274 // Adds variables into the sync group (ranges don't need to be tested here)
274 // Adds variables into the sync group (ranges don't need to be tested here)
275 Iterations iterations{};
275 Iterations iterations{};
276 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
276 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
277 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
277 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
278
278
279 // Moves var0: ranges of var0, var1 and var2 change
279 // Moves var0: ranges of var0, var1
280 auto newRange = range({12, 30}, {13, 30});
280 auto currentRange = range({12, 30}, {13, 30});
281 iterations.push_back({std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}}});
281 iterations.push_back(
282 {std::make_shared<Move>(0, currentRange), {{0, currentRange}, {1, currentRange}}});
282
283
283 // Moves var1: ranges of var0, var1 and var2 change
284 // Moves var0: ranges of var0, var1
284 newRange = range({13, 0}, {14, 0});
285 auto pendingRange = range({13, 0}, {14, 0});
285 iterations.push_back({std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}}});
286 iterations.push_back(
287 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
286
288
287 // Moves var2: ranges of var0, var1 and var2 change
289 // Moves var0: ranges of var0, var1
288 newRange = range({13, 30}, {14, 30});
290 pendingRange = range({13, 30}, {14, 30});
289 iterations.push_back(
291 iterations.push_back(
290 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
292 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
291
293
292 // Desyncs var2 and moves var0:
294 // moves var0:
293 // - ranges of var0 and var1 change
295 // - ranges of var0 and var1 change
294 // - range of var2 doesn't change anymore
296 auto var2Range = pendingRange;
295 auto var2Range = newRange;
297 pendingRange = range({13, 45}, {14, 45});
296 newRange = range({13, 45}, {14, 45});
298 iterations.push_back(
297 iterations.push_back({std::make_shared<Synchronize>(2, syncId, false)});
299 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
298 iterations.push_back({std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}}});
299
300
300 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
301 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
301 auto var1Range = newRange;
302 auto var1Range = pendingRange;
302 newRange = range({14, 45}, {15, 45});
303 pendingRange = range({14, 45}, {15, 45});
303 iterations.push_back(
304 iterations.push_back(
304 {std::make_shared<Move>(0, newRange, true), {{0, newRange}, {1, var1Range}}});
305 {std::make_shared<Move>(0, pendingRange, false), {{0, pendingRange}, {1, pendingRange}}});
305
306
306 // Moves var0 through several operations:
307 // Moves var0 through several operations:
307 // - range of var0 changes
308 // - range of var0 changes
308 // - range or var1 changes according to the previous shift (one hour)
309 // - range or var1 changes according to the previous shift (one hour)
309 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
310 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
310 iterations.push_back(
311 iterations.push_back(
311 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
312 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
312 };
313 };
313
314
314 // auto oldRange = newRange;
315 // auto oldRange = newRange;
315 // newRange = range({14, 30}, {15, 30});
316 // newRange = range({14, 30}, {15, 30});
316 // auto expectedRange = oldRange;
317 // auto expectedRange = oldRange;
317 // iterations.push_back(
318 // iterations.push_back(
318 // {std::make_shared<Move>(0, newRange), {{0, oldRange}, {1, expectedRange}}});
319 // {std::make_shared<Move>(0, newRange), {{0, oldRange}, {1, expectedRange}}});
319
320
320 // Pan left
321 // Pan left
321 moveVar0(range({14, 30}, {15, 30}), range({13, 30}, {14, 30}));
322 moveVar0(range({14, 30}, {15, 30}), range({14, 30}, {15, 30}));
322 // Pan right
323 // Pan right
323 moveVar0(range({16, 0}, {17, 0}), range({15, 0}, {16, 0}));
324 moveVar0(range({16, 0}, {17, 0}), range({16, 0}, {17, 0}));
324 // Zoom in
325 // Zoom in
325 moveVar0(range({16, 30}, {16, 45}), range({15, 30}, {15, 45}));
326 moveVar0(range({16, 30}, {16, 45}), range({16, 30}, {16, 45}));
326 // Zoom out
327 // Zoom out
327 moveVar0(range({16, 15}, {17, 0}), range({15, 15}, {16, 0}));
328 moveVar0(range({16, 15}, {17, 0}), range({16, 15}, {17, 0}));
328
329
329 QTest::newRow("syncWithAborting1") << syncId << initialRange << std::move(creations)
330 QTest::newRow("syncWithAborting1") << syncId << currentRange << std::move(creations)
330 << std::move(iterations) << 200;
331 << std::move(iterations) << 200;
331 }
332 }
332
333
333 void testSyncCase2()
334 void testSyncCase2()
334 {
335 {
335 // Id used to synchronize variables in the controller
336 // Id used to synchronize variables in the controller
336 auto syncId = QUuid::createUuid();
337 auto syncId = QUuid::createUuid();
337
338
338 /// Generates a range according to a start time and a end time (the date is the same)
339 /// Generates a range according to a start time and a end time (the date is the same)
339 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
340 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
340 return DateUtils::secondsSinceEpoch(
341 return DateUtils::secondsSinceEpoch(
341 QDateTime{{year, month, day}, QTime{hours, minutes, seconds}, Qt::UTC});
342 QDateTime{{year, month, day}, QTime{hours, minutes, seconds}, Qt::UTC});
342 };
343 };
343
344
344 auto initialRange = SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)};
345 auto initialRange = SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)};
345
346
346 Iterations iterations{};
347 Iterations iterations{};
347 // Creates variables var0 and var1
348 // Creates variables var0 and var1
348 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
349 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
349 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
350 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
350
351
351 // Adds variables into the sync group (ranges don't need to be tested here)
352 // Adds variables into the sync group (ranges don't need to be tested here)
352 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
353 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
353 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
354 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
354
355
355
356
356 // Moves var0 through several operations:
357 // Moves var0 through several operations:
357 // - range of var0 changes
358 // - range of var0 changes
358 // - range or var1 changes according to the previous shift (one hour)
359 // - range or var1 changes according to the previous shift (one hour)
359 auto moveVar0 = [&iterations](const auto &var0NewRange) {
360 auto moveVar0 = [&iterations](const auto &var0NewRange) {
360 iterations.push_back(
361 iterations.push_back(
361 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var0NewRange}}});
362 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var0NewRange}}});
362 };
363 };
363 moveVar0(SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)});
364 moveVar0(SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)});
364 moveVar0(SqpRange{dateTime(2017, 1, 1, 14, 0, 0), dateTime(2017, 1, 1, 15, 0, 0)});
365 moveVar0(SqpRange{dateTime(2017, 1, 1, 14, 0, 0), dateTime(2017, 1, 1, 15, 0, 0)});
365 moveVar0(SqpRange{dateTime(2017, 1, 1, 8, 0, 0), dateTime(2017, 1, 1, 9, 0, 0)});
366 moveVar0(SqpRange{dateTime(2017, 1, 1, 8, 0, 0), dateTime(2017, 1, 1, 9, 0, 0)});
366 // moveVar0(SqpRange{dateTime(2017, 1, 1, 7, 30, 0), dateTime(2017, 1, 1, 9, 30, 0)});
367 // moveVar0(SqpRange{dateTime(2017, 1, 1, 7, 30, 0), dateTime(2017, 1, 1, 9, 30, 0)});
367 moveVar0(SqpRange{dateTime(2017, 1, 1, 2, 0, 0), dateTime(2017, 1, 1, 4, 0, 0)});
368 moveVar0(SqpRange{dateTime(2017, 1, 1, 2, 0, 0), dateTime(2017, 1, 1, 4, 0, 0)});
368 moveVar0(SqpRange{dateTime(2017, 1, 1, 6, 0, 0), dateTime(2017, 1, 1, 8, 0, 0)});
369 moveVar0(SqpRange{dateTime(2017, 1, 1, 6, 0, 0), dateTime(2017, 1, 1, 8, 0, 0)});
369
370
370 moveVar0(SqpRange{dateTime(2017, 1, 10, 6, 0, 0), dateTime(2017, 1, 15, 8, 0, 0)});
371 moveVar0(SqpRange{dateTime(2017, 1, 10, 6, 0, 0), dateTime(2017, 1, 15, 8, 0, 0)});
371 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 1, 25, 8, 0, 0)});
372 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 1, 25, 8, 0, 0)});
372 moveVar0(SqpRange{dateTime(2017, 1, 2, 6, 0, 0), dateTime(2017, 1, 8, 8, 0, 0)});
373 moveVar0(SqpRange{dateTime(2017, 1, 2, 6, 0, 0), dateTime(2017, 1, 8, 8, 0, 0)});
373
374
374 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
375 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
375 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
376 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
376 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
377 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
377 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
378 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
378 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
379 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
379 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
380 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
380 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
381 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
381 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
382 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
382 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
383 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
383 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
384 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
384 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
385 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
385 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
386 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
386
387
387
388
388 QTest::newRow("sync2") << syncId << initialRange << iterations << 4000;
389 QTest::newRow("sync2") << syncId << initialRange << iterations << 4000;
389 // QTest::newRow("sync3") << syncId << initialRange << iterations << 5000;
390 // QTest::newRow("sync3") << syncId << initialRange << iterations << 5000;
390 }
391 }
391 }
392 }
392
393
393 void TestVariableSync::testSync_data()
394 void TestVariableSync::testSync_data()
394 {
395 {
395 // ////////////// //
396 // ////////////// //
396 // Test structure //
397 // Test structure //
397 // ////////////// //
398 // ////////////// //
398
399
399 QTest::addColumn<QUuid>("syncId");
400 QTest::addColumn<QUuid>("syncId");
400 QTest::addColumn<SqpRange>("initialRange");
401 QTest::addColumn<SqpRange>("initialRange");
401 QTest::addColumn<Iterations>("iterations");
402 QTest::addColumn<Iterations>("iterations");
402 QTest::addColumn<int>("operationDelay");
403 QTest::addColumn<int>("operationDelay");
403
404
404 // ////////// //
405 // ////////// //
405 // Test cases //
406 // Test cases //
406 // ////////// //
407 // ////////// //
407
408
408 testSyncCase1();
409 testSyncCase1();
409 testSyncCase2();
410 testSyncCase2();
410 }
411 }
411
412
412 void TestVariableSync::testSyncWithAborting_data()
413 void TestVariableSync::testSyncWithAborting_data()
413 {
414 {
414 // ////////////// //
415 // ////////////// //
415 // Test structure //
416 // Test structure //
416 // ////////////// //
417 // ////////////// //
417
418
418 QTest::addColumn<QUuid>("syncId");
419 QTest::addColumn<QUuid>("syncId");
419 QTest::addColumn<SqpRange>("initialRange");
420 QTest::addColumn<SqpRange>("initialRange");
420 QTest::addColumn<Iterations>("creations");
421 QTest::addColumn<Iterations>("creations");
421 QTest::addColumn<Iterations>("iterations");
422 QTest::addColumn<Iterations>("iterations");
422 QTest::addColumn<int>("operationDelay");
423 QTest::addColumn<int>("operationDelay");
423
424
424 // ////////// //
425 // ////////// //
425 // Test cases //
426 // Test cases //
426 // ////////// //
427 // ////////// //
427
428
428 testSyncCase1WithAborting();
429 testSyncCase1WithAborting();
429 }
430 }
430
431
431 void TestVariableSync::testSync()
432 void TestVariableSync::testSync()
432 {
433 {
433 return;
434 return;
434
435
435 // Inits controllers
436 // Inits controllers
436 TimeController timeController{};
437 TimeController timeController{};
437 VariableController variableController{};
438 VariableController variableController{};
438 variableController.setTimeController(&timeController);
439 variableController.setTimeController(&timeController);
439
440
440 QFETCH(QUuid, syncId);
441 QFETCH(QUuid, syncId);
441 QFETCH(SqpRange, initialRange);
442 QFETCH(SqpRange, initialRange);
442 timeController.onTimeToUpdate(initialRange);
443 timeController.onTimeToUpdate(initialRange);
443
444
444 // Synchronization group used
445 // Synchronization group used
445 variableController.onAddSynchronizationGroupId(syncId);
446 variableController.onAddSynchronizationGroupId(syncId);
446
447
447 auto validateRanges = [&variableController](const auto &expectedRanges) {
448 auto validateRanges = [&variableController](const auto &expectedRanges) {
448 for (const auto &expectedRangeEntry : expectedRanges) {
449 for (const auto &expectedRangeEntry : expectedRanges) {
449 auto variableIndex = expectedRangeEntry.first;
450 auto variableIndex = expectedRangeEntry.first;
450 auto expectedRange = expectedRangeEntry.second;
451 auto expectedRange = expectedRangeEntry.second;
451
452
452 // Gets the variable in the controller
453 // Gets the variable in the controller
453 auto variable = variableController.variableModel()->variable(variableIndex);
454 auto variable = variableController.variableModel()->variable(variableIndex);
454
455
455 // Compares variable's range to the expected range
456 // Compares variable's range to the expected range
456 QVERIFY(variable != nullptr);
457 QVERIFY(variable != nullptr);
457 auto range = variable->range();
458 auto range = variable->range();
458 QCOMPARE(range, expectedRange);
459 QCOMPARE(range, expectedRange);
459
460
460 // Compares variable's data with values expected for its range
461 // Compares variable's data with values expected for its range
461 auto dataSeries = variable->dataSeries();
462 auto dataSeries = variable->dataSeries();
462 QVERIFY(dataSeries != nullptr);
463 QVERIFY(dataSeries != nullptr);
463
464
464 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
465 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
465 auto expectedValues = values(range);
466 auto expectedValues = values(range);
466 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
467 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
467 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
468 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
468 [](const auto &dataSeriesIt, const auto &expectedValue) {
469 [](const auto &dataSeriesIt, const auto &expectedValue) {
469 return dataSeriesIt.value() == expectedValue;
470 return dataSeriesIt.value() == expectedValue;
470 }));
471 }));
471 }
472 }
472 };
473 };
473
474
474 // For each iteration:
475 // For each iteration:
475 // - execute operation
476 // - execute operation
476 // - compare the variables' state to the expected states
477 // - compare the variables' state to the expected states
477 QFETCH(Iterations, iterations);
478 QFETCH(Iterations, iterations);
478 QFETCH(int, operationDelay);
479 QFETCH(int, operationDelay);
479 for (const auto &iteration : iterations) {
480 for (const auto &iteration : iterations) {
480 iteration.m_Operation->exec(variableController);
481 iteration.m_Operation->exec(variableController);
481 QTest::qWait(operationDelay);
482 QTest::qWait(operationDelay);
482
483
483 validateRanges(iteration.m_ExpectedRanges);
484 validateRanges(iteration.m_ExpectedRanges);
484 }
485 }
485 }
486 }
486
487
487 void TestVariableSync::testSyncWithAborting()
488 void TestVariableSync::testSyncWithAborting()
488 {
489 {
489 // Inits controllers
490 // Inits controllers
490 TimeController timeController{};
491 TimeController timeController{};
491 VariableController variableController{};
492 VariableController variableController{};
492 variableController.setTimeController(&timeController);
493 variableController.setTimeController(&timeController);
493
494
494 QFETCH(QUuid, syncId);
495 QFETCH(QUuid, syncId);
495 QFETCH(SqpRange, initialRange);
496 QFETCH(SqpRange, initialRange);
496 timeController.onTimeToUpdate(initialRange);
497 timeController.onTimeToUpdate(initialRange);
497
498
498 // Synchronization group used
499 // Synchronization group used
499 variableController.onAddSynchronizationGroupId(syncId);
500 variableController.onAddSynchronizationGroupId(syncId);
500
501
501 auto validateRanges = [&variableController](const auto &expectedRanges) {
502 auto validateRanges = [&variableController](const auto &expectedRanges) {
502 for (const auto &expectedRangeEntry : expectedRanges) {
503 for (const auto &expectedRangeEntry : expectedRanges) {
503 auto variableIndex = expectedRangeEntry.first;
504 auto variableIndex = expectedRangeEntry.first;
504 auto expectedRange = expectedRangeEntry.second;
505 auto expectedRange = expectedRangeEntry.second;
505
506
506 // Gets the variable in the controller
507 // Gets the variable in the controller
507 auto variable = variableController.variableModel()->variable(variableIndex);
508 auto variable = variableController.variableModel()->variable(variableIndex);
508
509
509 // Compares variable's range to the expected range
510 // Compares variable's range to the expected range
510 QVERIFY(variable != nullptr);
511 QVERIFY(variable != nullptr);
511 auto range = variable->range();
512 auto range = variable->range();
513 qInfo() << "range vs expected range" << range << variable->range();
512 QCOMPARE(range, expectedRange);
514 QCOMPARE(range, expectedRange);
513
515
514 // Compares variable's data with values expected for its range
516 // Compares variable's data with values expected for its range
515 auto dataSeries = variable->dataSeries();
517 auto dataSeries = variable->dataSeries();
516 QVERIFY(dataSeries != nullptr);
518 QVERIFY(dataSeries != nullptr);
517
519
518 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
520 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
519 auto expectedValues = values(range);
521 auto expectedValues = values(range);
520 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
522 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
521 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
523 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
522 [](const auto &dataSeriesIt, const auto &expectedValue) {
524 [](const auto &dataSeriesIt, const auto &expectedValue) {
523 return dataSeriesIt.value() == expectedValue;
525 return dataSeriesIt.value() == expectedValue;
524 }));
526 }));
525 }
527 }
526 };
528 };
527
529
528 // For each iteration:
530 // For each iteration:
529 // - execute operation
531 // - execute operation
530 // - compare the variables' state to the expected states
532 // - compare the variables' state to the expected states
531 QFETCH(Iterations, iterations);
533 QFETCH(Iterations, iterations);
532 QFETCH(Iterations, creations);
534 QFETCH(Iterations, creations);
533 QFETCH(int, operationDelay);
535 QFETCH(int, operationDelay);
534
536
535 for (const auto &creation : creations) {
537 for (const auto &creation : creations) {
536 creation.m_Operation->exec(variableController);
538 creation.m_Operation->exec(variableController);
537 QTest::qWait(operationDelay);
539 QTest::qWait(operationDelay);
538 }
540 }
539
541
540 for (const auto &iteration : iterations) {
542 for (const auto &iteration : iterations) {
541 iteration.m_Operation->exec(variableController);
543 iteration.m_Operation->exec(variableController);
542 }
544 }
543
545
544 QTest::qWait(operationDelay);
546 QTest::qWait(operationDelay);
545 validateRanges(iterations.back().m_ExpectedRanges);
547 validateRanges(iterations.back().m_ExpectedRanges);
546 }
548 }
547
549
548
550
549 QTEST_MAIN(TestVariableSync)
551 QTEST_MAIN(TestVariableSync)
550
552
551 #include "TestVariableSync.moc"
553 #include "TestVariableSync.moc"
@@ -1,192 +1,195
1 #include "CosinusProvider.h"
1 #include "CosinusProvider.h"
2 #include "MockDefs.h"
2 #include "MockDefs.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Data/ScalarSeries.h>
5 #include <Data/ScalarSeries.h>
6 #include <SqpApplication.h>
6 #include <SqpApplication.h>
7 #include <Time/TimeController.h>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
9 #include <Variable/VariableController.h>
10
10
11 #include <QObject>
11 #include <QObject>
12 #include <QtTest>
12 #include <QtTest>
13
13
14 #include <cmath>
14 #include <cmath>
15 #include <memory>
15 #include <memory>
16
16
17 namespace {
17 namespace {
18
18
19 /// Path for the tests
19 /// Path for the tests
20 const auto TESTS_RESOURCES_PATH = QFileInfo{
20 const auto TESTS_RESOURCES_PATH = QFileInfo{
21 QString{MOCKPLUGIN_TESTS_RESOURCES_DIR},
21 QString{MOCKPLUGIN_TESTS_RESOURCES_DIR},
22 "TestCosinusAcquisition"}.absoluteFilePath();
22 "TestCosinusAcquisition"}.absoluteFilePath();
23
23
24 /// Format of dates in data files
24 /// Format of dates in data files
25 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
25 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss:zzz");
26
26
27 /**
27 /**
28 * Verifies that the data in the candidate series are identical to the data in the reference series
28 * Verifies that the data in the candidate series are identical to the data in the reference series
29 * in a specific range
29 * in a specific range
30 * @param candidate the candidate data series
30 * @param candidate the candidate data series
31 * @param range the range to check
31 * @param range the range to check
32 * @param reference the reference data series
32 * @param reference the reference data series
33 * @return true if the data of the candidate series and the reference series are identical in the
33 * @return true if the data of the candidate series and the reference series are identical in the
34 * range, false otherwise
34 * range, false otherwise
35 */
35 */
36 bool checkDataSeries(std::shared_ptr<IDataSeries> candidate, const SqpRange &range,
36 bool checkDataSeries(std::shared_ptr<IDataSeries> candidate, const SqpRange &range,
37 std::shared_ptr<IDataSeries> reference)
37 std::shared_ptr<IDataSeries> reference)
38 {
38 {
39 if (candidate == nullptr || reference == nullptr) {
39 if (candidate == nullptr || reference == nullptr) {
40 return candidate == reference;
40 return candidate == reference;
41 }
41 }
42
42
43 auto referenceIt = reference->xAxisRange(range.m_TStart, range.m_TEnd);
43 auto referenceIt = reference->xAxisRange(range.m_TStart, range.m_TEnd);
44
44
45 qInfo() << "candidateSize" << std::distance(candidate->cbegin(), candidate->cend());
45 qInfo() << "candidateSize" << std::distance(candidate->cbegin(), candidate->cend());
46 qInfo() << "refSize" << std::distance(referenceIt.first, referenceIt.second);
46 qInfo() << "refSize" << std::distance(referenceIt.first, referenceIt.second);
47
47
48 return std::equal(candidate->cbegin(), candidate->cend(), referenceIt.first, referenceIt.second,
48 return std::equal(candidate->cbegin(), candidate->cend(), referenceIt.first, referenceIt.second,
49 [](const auto &it1, const auto &it2) {
49 [](const auto &it1, const auto &it2) {
50 // - milliseconds precision for time
50 // - milliseconds precision for time
51 // - 1e-6 precision for value
51 // - 1e-6 precision for value
52 return std::abs(it1.x() - it2.x()) < 1e-3
52 return std::abs(it1.x() - it2.x()) < 1e-3
53 && std::abs(it1.value() - it2.value()) < 1e-6;
53 && std::abs(it1.value() - it2.value()) < 1e-6;
54 });
54 });
55 }
55 }
56
56
57 } // namespace
57 } // namespace
58
58
59 /**
59 /**
60 * @brief The TestCosinusAcquisition class tests acquisition in SciQlop (operations like zooms in,
60 * @brief The TestCosinusAcquisition class tests acquisition in SciQlop (operations like zooms in,
61 * zooms out, pans) of data from CosinusProvider
61 * zooms out, pans) of data from CosinusProvider
62 * @sa CosinusProvider
62 * @sa CosinusProvider
63 */
63 */
64 class TestCosinusAcquisition : public QObject {
64 class TestCosinusAcquisition : public QObject {
65 Q_OBJECT
65 Q_OBJECT
66
66
67 private slots:
67 private slots:
68 /// Input data for @sa testAcquisition()
68 /// Input data for @sa testAcquisition()
69 void testAcquisition_data();
69 void testAcquisition_data();
70 void testAcquisition();
70 void testAcquisition();
71 };
71 };
72
72
73 void TestCosinusAcquisition::testAcquisition_data()
73 void TestCosinusAcquisition::testAcquisition_data()
74 {
74 {
75 // ////////////// //
75 // ////////////// //
76 // Test structure //
76 // Test structure //
77 // ////////////// //
77 // ////////////// //
78
78
79 QTest::addColumn<SqpRange>("referenceRange"); // Range for generating reference series
79 QTest::addColumn<SqpRange>("referenceRange"); // Range for generating reference series
80 QTest::addColumn<SqpRange>("initialRange"); // First acquisition
80 QTest::addColumn<SqpRange>("initialRange"); // First acquisition
81 QTest::addColumn<int>("operationDelay"); // Acquisitions to make
81 QTest::addColumn<int>("operationDelay"); // Acquisitions to make
82 QTest::addColumn<std::vector<SqpRange> >("operations"); // Acquisitions to make
82 QTest::addColumn<std::vector<SqpRange> >("operations"); // Acquisitions to make
83
83
84 // ////////// //
84 // ////////// //
85 // Test cases //
85 // Test cases //
86 // ////////// //
86 // ////////// //
87
87
88 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
88 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
89 return DateUtils::secondsSinceEpoch(
89 return DateUtils::secondsSinceEpoch(
90 QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC});
90 QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC});
91 };
91 };
92
92
93 QTest::newRow("cosinus")
93 QTest::newRow("cosinus")
94 << SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)}
94 << SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)}
95 << SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 1, 12, 35, 1)} << 250
95 << SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 1, 12, 35, 1)} << 250
96 << std::vector<SqpRange>{
96 << std::vector<SqpRange>{
97 // Pan (jump) left
97 // Pan (jump) left
98 SqpRange{dateTime(2017, 1, 1, 12, 45, 0), dateTime(2017, 1, 1, 12, 50, 0)},
98 SqpRange{dateTime(2017, 1, 1, 12, 45, 0), dateTime(2017, 1, 1, 12, 50, 0)},
99 // Pan (jump) right
99 // Pan (jump) right
100 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
100 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
101 // Pan (overlay) right
101 // Pan (overlay) right
102 SqpRange{dateTime(2017, 1, 1, 12, 14, 0), dateTime(2017, 1, 1, 12, 19, 0)},
102 SqpRange{dateTime(2017, 1, 1, 12, 14, 0), dateTime(2017, 1, 1, 12, 19, 0)},
103 // Pan (overlay) left
103 // Pan (overlay) left
104 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
104 SqpRange{dateTime(2017, 1, 1, 12, 15, 0), dateTime(2017, 1, 1, 12, 20, 0)},
105 // Pan (overlay) left
105 // Pan (overlay) left
106 SqpRange{dateTime(2017, 1, 1, 12, 16, 0), dateTime(2017, 1, 1, 12, 21, 0)},
106 SqpRange{dateTime(2017, 1, 1, 12, 16, 0), dateTime(2017, 1, 1, 12, 21, 0)},
107 // Zoom in
107 // Zoom in
108 SqpRange{dateTime(2017, 1, 1, 12, 17, 30), dateTime(2017, 1, 1, 12, 19, 30)},
108 SqpRange{dateTime(2017, 1, 1, 12, 17, 30), dateTime(2017, 1, 1, 12, 19, 30)},
109 // Zoom out
109 // Zoom out
110 SqpRange{dateTime(2017, 1, 1, 12, 12, 30), dateTime(2017, 1, 1, 12, 24, 30)}};
110 SqpRange{dateTime(2017, 1, 1, 12, 12, 30), dateTime(2017, 1, 1, 12, 24, 30)}};
111
111
112 QTest::newRow("cosinus_big")
112 QTest::newRow("cosinus_big")
113 << SqpRange{dateTime(2017, 1, 1, 1, 0, 0), dateTime(2017, 1, 5, 13, 0, 0)}
113 << SqpRange{dateTime(2017, 1, 1, 1, 0, 0), dateTime(2017, 1, 5, 13, 0, 0)}
114 << SqpRange{dateTime(2017, 1, 2, 6, 30, 0), dateTime(2017, 1, 2, 18, 30, 0)} << 5000
114 << SqpRange{dateTime(2017, 1, 2, 6, 30, 0), dateTime(2017, 1, 2, 18, 30, 0)} << 5000
115 << std::vector<SqpRange>{
115 << std::vector<SqpRange>{
116 // Pan (jump) left
116 // Pan (jump) left
117 SqpRange{dateTime(2017, 1, 1, 13, 30, 0), dateTime(2017, 1, 1, 18, 30, 0)},
117 SqpRange{dateTime(2017, 1, 1, 13, 30, 0), dateTime(2017, 1, 1, 18, 30, 0)},
118 // Pan (jump) right
118 // Pan (jump) right
119 SqpRange{dateTime(2017, 1, 3, 4, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
119 SqpRange{dateTime(2017, 1, 3, 4, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
120 // Pan (overlay) right
120 // Pan (overlay) right
121 SqpRange{dateTime(2017, 1, 3, 8, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)},
121 SqpRange{dateTime(2017, 1, 3, 8, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)},
122 // Pan (overlay) left
122 // Pan (overlay) left
123 SqpRange{dateTime(2017, 1, 2, 8, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
123 SqpRange{dateTime(2017, 1, 2, 8, 30, 0), dateTime(2017, 1, 3, 10, 30, 0)},
124 // Pan (overlay) left
124 // Pan (overlay) left
125 SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 3, 5, 30, 0)},
125 SqpRange{dateTime(2017, 1, 1, 12, 30, 0), dateTime(2017, 1, 3, 5, 30, 0)},
126 // Zoom in
126 // Zoom in
127 SqpRange{dateTime(2017, 1, 2, 2, 30, 0), dateTime(2017, 1, 2, 8, 30, 0)},
127 SqpRange{dateTime(2017, 1, 2, 2, 30, 0), dateTime(2017, 1, 2, 8, 30, 0)},
128 // Zoom out
128 // Zoom out
129 SqpRange{dateTime(2017, 1, 1, 14, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)}};
129 SqpRange{dateTime(2017, 1, 1, 14, 30, 0), dateTime(2017, 1, 3, 12, 30, 0)}};
130 }
130 }
131
131
132 void TestCosinusAcquisition::testAcquisition()
132 void TestCosinusAcquisition::testAcquisition()
133 {
133 {
134 // Retrieves reference range
134 // Retrieves reference range
135 QFETCH(SqpRange, referenceRange);
135 QFETCH(SqpRange, referenceRange);
136 CosinusProvider referenceProvider{};
136 CosinusProvider referenceProvider{};
137 auto dataSeries = referenceProvider.provideDataSeries(
137 auto dataSeries = referenceProvider.provideDataSeries(
138 referenceRange, {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}});
138 referenceRange, {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}});
139
139
140 auto end = dataSeries->cend() - 1;
140 auto end = dataSeries->cend() - 1;
141 qInfo() << dataSeries->nbPoints() << dataSeries->cbegin()->x() << end->x();
141 qInfo() << dataSeries->nbPoints() << dataSeries->cbegin()->x() << end->x();
142
142
143 /// Lambda used to validate a variable at each step
143 /// Lambda used to validate a variable at each step
144 auto validateVariable
144 auto validateVariable
145 = [dataSeries](std::shared_ptr<Variable> variable, const SqpRange &range) {
145 = [dataSeries](std::shared_ptr<Variable> variable, const SqpRange &range) {
146 // Checks that the variable's range has changed
146 // Checks that the variable's range has changed
147 qInfo() << "range vs expected range" << variable->range() << range;
147 QCOMPARE(variable->range(), range);
148 QCOMPARE(variable->range(), range);
148
149
149 // Checks the variable's data series
150 // Checks the variable's data series
150 QVERIFY(checkDataSeries(variable->dataSeries(), variable->cacheRange(), dataSeries));
151 QVERIFY(checkDataSeries(variable->dataSeries(), variable->cacheRange(), dataSeries));
151 };
152 };
152
153
153 // Creates variable
154 // Creates variable
154 QFETCH(SqpRange, initialRange);
155 QFETCH(SqpRange, initialRange);
155 sqpApp->timeController().onTimeToUpdate(initialRange);
156 sqpApp->timeController().onTimeToUpdate(initialRange);
156 auto provider = std::make_shared<CosinusProvider>();
157 auto provider = std::make_shared<CosinusProvider>();
157 auto variable = sqpApp->variableController().createVariable(
158 auto variable = sqpApp->variableController().createVariable(
158 "MMS", {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}}, provider);
159 "MMS", {{COSINUS_TYPE_KEY, "scalar"}, {COSINUS_FREQUENCY_KEY, 100.}}, provider);
159
160
161
160 QFETCH(int, operationDelay);
162 QFETCH(int, operationDelay);
161 QTest::qWait(operationDelay);
163 QTest::qWait(operationDelay);
162 validateVariable(variable, initialRange);
164 validateVariable(variable, initialRange);
163
165
166 QTest::qWait(operationDelay);
164 // Makes operations on the variable
167 // Makes operations on the variable
165 QFETCH(std::vector<SqpRange>, operations);
168 QFETCH(std::vector<SqpRange>, operations);
166 for (const auto &operation : operations) {
169 for (const auto &operation : operations) {
167 // Asks request on the variable and waits during its execution
170 // Asks request on the variable and waits during its execution
168 sqpApp->variableController().onRequestDataLoading({variable}, operation, true);
171 sqpApp->variableController().onRequestDataLoading({variable}, operation, false);
169
172
170 QTest::qWait(operationDelay);
173 QTest::qWait(operationDelay);
171 validateVariable(variable, operation);
174 validateVariable(variable, operation);
172 }
175 }
173
176
174
177
175 for (const auto &operation : operations) {
178 for (const auto &operation : operations) {
176 // Asks request on the variable and waits during its execution
179 // Asks request on the variable and waits during its execution
177 sqpApp->variableController().onRequestDataLoading({variable}, operation, true);
180 sqpApp->variableController().onRequestDataLoading({variable}, operation, false);
178 }
181 }
179 QTest::qWait(operationDelay);
182 QTest::qWait(operationDelay);
180 validateVariable(variable, operations.back());
183 validateVariable(variable, operations.back());
181 }
184 }
182
185
183 int main(int argc, char *argv[])
186 int main(int argc, char *argv[])
184 {
187 {
185 SqpApplication app{argc, argv};
188 SqpApplication app{argc, argv};
186 app.setAttribute(Qt::AA_Use96Dpi, true);
189 app.setAttribute(Qt::AA_Use96Dpi, true);
187 TestCosinusAcquisition testObject{};
190 TestCosinusAcquisition testObject{};
188 QTEST_SET_MAIN_SOURCE_PATH
191 QTEST_SET_MAIN_SOURCE_PATH
189 return QTest::qExec(&testObject, argc, argv);
192 return QTest::qExec(&testObject, argc, argv);
190 }
193 }
191
194
192 #include "TestCosinusAcquisition.moc"
195 #include "TestCosinusAcquisition.moc"
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

Merge lasted acquisition developpement on main Sciqlop branch

You need to be logged in to leave comments. Login now