##// END OF EJS Templates
Fix test to make them sucess
perrinel -
r839:105359887123
parent child
Show More
@@ -1,1012 +1,1012
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
4 #include <Variable/VariableCacheStrategyFactory.h>
5 #include <Variable/VariableController.h>
5 #include <Variable/VariableController.h>
6 #include <Variable/VariableModel.h>
6 #include <Variable/VariableModel.h>
7 #include <Variable/VariableSynchronizationGroup.h>
7 #include <Variable/VariableSynchronizationGroup.h>
8
8
9 #include <Data/DataProviderParameters.h>
9 #include <Data/DataProviderParameters.h>
10 #include <Data/IDataProvider.h>
10 #include <Data/IDataProvider.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <Data/VariableRequest.h>
12 #include <Data/VariableRequest.h>
13 #include <Time/TimeController.h>
13 #include <Time/TimeController.h>
14
14
15 #include <QMutex>
15 #include <QMutex>
16 #include <QThread>
16 #include <QThread>
17 #include <QUuid>
17 #include <QUuid>
18 #include <QtCore/QItemSelectionModel>
18 #include <QtCore/QItemSelectionModel>
19
19
20 #include <deque>
20 #include <deque>
21 #include <set>
21 #include <set>
22 #include <unordered_map>
22 #include <unordered_map>
23
23
24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
25
25
26 namespace {
26 namespace {
27
27
28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
29 const SqpRange &oldGraphRange)
29 const SqpRange &oldGraphRange)
30 {
30 {
31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
32
32
33 auto varRangeRequested = varRange;
33 auto varRangeRequested = varRange;
34 switch (zoomType) {
34 switch (zoomType) {
35 case AcquisitionZoomType::ZoomIn: {
35 case AcquisitionZoomType::ZoomIn: {
36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
38 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TStart += deltaLeft;
39 varRangeRequested.m_TEnd -= deltaRight;
39 varRangeRequested.m_TEnd -= deltaRight;
40 break;
40 break;
41 }
41 }
42
42
43 case AcquisitionZoomType::ZoomOut: {
43 case AcquisitionZoomType::ZoomOut: {
44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
46 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TStart -= deltaLeft;
47 varRangeRequested.m_TEnd += deltaRight;
47 varRangeRequested.m_TEnd += deltaRight;
48 break;
48 break;
49 }
49 }
50 case AcquisitionZoomType::PanRight: {
50 case AcquisitionZoomType::PanRight: {
51 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
51 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
52 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
52 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
53 varRangeRequested.m_TStart += deltaLeft;
53 varRangeRequested.m_TStart += deltaLeft;
54 varRangeRequested.m_TEnd += deltaRight;
54 varRangeRequested.m_TEnd += deltaRight;
55 break;
55 break;
56 }
56 }
57 case AcquisitionZoomType::PanLeft: {
57 case AcquisitionZoomType::PanLeft: {
58 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
58 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
59 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
59 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
60 varRangeRequested.m_TStart -= deltaLeft;
60 varRangeRequested.m_TStart -= deltaLeft;
61 varRangeRequested.m_TEnd -= deltaRight;
61 varRangeRequested.m_TEnd -= deltaRight;
62 break;
62 break;
63 }
63 }
64 case AcquisitionZoomType::Unknown: {
64 case AcquisitionZoomType::Unknown: {
65 qCCritical(LOG_VariableController())
65 qCCritical(LOG_VariableController())
66 << VariableController::tr("Impossible to synchronize: zoom type unknown");
66 << VariableController::tr("Impossible to synchronize: zoom type unknown");
67 break;
67 break;
68 }
68 }
69 default:
69 default:
70 qCCritical(LOG_VariableController()) << VariableController::tr(
70 qCCritical(LOG_VariableController()) << VariableController::tr(
71 "Impossible to synchronize: zoom type not take into account");
71 "Impossible to synchronize: zoom type not take into account");
72 // No action
72 // No action
73 break;
73 break;
74 }
74 }
75
75
76 return varRangeRequested;
76 return varRangeRequested;
77 }
77 }
78 }
78 }
79
79
80 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
80 enum class VariableRequestHandlerState { OFF, RUNNING, PENDING };
81
81
82 struct VariableRequestHandler {
82 struct VariableRequestHandler {
83
83
84 VariableRequestHandler()
84 VariableRequestHandler()
85 {
85 {
86 m_CanUpdate = false;
86 m_CanUpdate = false;
87 m_State = VariableRequestHandlerState::OFF;
87 m_State = VariableRequestHandlerState::OFF;
88 }
88 }
89
89
90 QUuid m_VarId;
90 QUuid m_VarId;
91 VariableRequest m_RunningVarRequest;
91 VariableRequest m_RunningVarRequest;
92 VariableRequest m_PendingVarRequest;
92 VariableRequest m_PendingVarRequest;
93 VariableRequestHandlerState m_State;
93 VariableRequestHandlerState m_State;
94 bool m_CanUpdate;
94 bool m_CanUpdate;
95 };
95 };
96
96
97 struct VariableController::VariableControllerPrivate {
97 struct VariableController::VariableControllerPrivate {
98 explicit VariableControllerPrivate(VariableController *parent)
98 explicit VariableControllerPrivate(VariableController *parent)
99 : m_WorkingMutex{},
99 : m_WorkingMutex{},
100 m_VariableModel{new VariableModel{parent}},
100 m_VariableModel{new VariableModel{parent}},
101 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
101 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
102 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
102 // m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
103 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
103 m_VariableCacheStrategy{VariableCacheStrategyFactory::createCacheStrategy(
104 CacheStrategy::SingleThreshold)},
104 CacheStrategy::SingleThreshold)},
105 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
105 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
106 q{parent}
106 q{parent}
107 {
107 {
108
108
109 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
109 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
110 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
110 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
111 }
111 }
112
112
113
113
114 virtual ~VariableControllerPrivate()
114 virtual ~VariableControllerPrivate()
115 {
115 {
116 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
116 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
117 m_VariableAcquisitionWorkerThread.quit();
117 m_VariableAcquisitionWorkerThread.quit();
118 m_VariableAcquisitionWorkerThread.wait();
118 m_VariableAcquisitionWorkerThread.wait();
119 }
119 }
120
120
121
121
122 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
122 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
123 QUuid varRequestId);
123 QUuid varRequestId);
124
124
125 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
125 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
126 std::shared_ptr<IDataSeries>
126 std::shared_ptr<IDataSeries>
127 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
127 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
128
128
129 void registerProvider(std::shared_ptr<IDataProvider> provider);
129 void registerProvider(std::shared_ptr<IDataProvider> provider);
130
130
131 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
131 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
132 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
132 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
133 void updateVariables(QUuid varRequestId);
133 void updateVariables(QUuid varRequestId);
134 void updateVariableRequest(QUuid varRequestId);
134 void updateVariableRequest(QUuid varRequestId);
135 void cancelVariableRequest(QUuid varRequestId);
135 void cancelVariableRequest(QUuid varRequestId);
136 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
136 void executeVarRequest(std::shared_ptr<Variable> var, VariableRequest &varRequest);
137
137
138 QMutex m_WorkingMutex;
138 QMutex m_WorkingMutex;
139 /// Variable model. The VariableController has the ownership
139 /// Variable model. The VariableController has the ownership
140 VariableModel *m_VariableModel;
140 VariableModel *m_VariableModel;
141 QItemSelectionModel *m_VariableSelectionModel;
141 QItemSelectionModel *m_VariableSelectionModel;
142
142
143
143
144 TimeController *m_TimeController{nullptr};
144 TimeController *m_TimeController{nullptr};
145 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
145 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
146 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
146 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
147 QThread m_VariableAcquisitionWorkerThread;
147 QThread m_VariableAcquisitionWorkerThread;
148
148
149 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
149 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
150 m_VariableToProviderMap;
150 m_VariableToProviderMap;
151 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
151 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
152 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
152 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
153 m_GroupIdToVariableSynchronizationGroupMap;
153 m_GroupIdToVariableSynchronizationGroupMap;
154 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
154 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
155 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
155 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
156
156
157 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
157 std::map<QUuid, std::list<QUuid> > m_VarGroupIdToVarIds;
158 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
158 std::map<QUuid, std::unique_ptr<VariableRequestHandler> > m_VarIdToVarRequestHandler;
159
159
160 VariableController *q;
160 VariableController *q;
161 };
161 };
162
162
163
163
164 VariableController::VariableController(QObject *parent)
164 VariableController::VariableController(QObject *parent)
165 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
165 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
166 {
166 {
167 qCDebug(LOG_VariableController()) << tr("VariableController construction")
167 qCDebug(LOG_VariableController()) << tr("VariableController construction")
168 << QThread::currentThread();
168 << QThread::currentThread();
169
169
170 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
170 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
171 &VariableController::onAbortProgressRequested);
171 &VariableController::onAbortProgressRequested);
172
172
173 connect(impl->m_VariableAcquisitionWorker.get(),
173 connect(impl->m_VariableAcquisitionWorker.get(),
174 &VariableAcquisitionWorker::variableCanceledRequested, this,
174 &VariableAcquisitionWorker::variableCanceledRequested, this,
175 &VariableController::onAbortAcquisitionRequested);
175 &VariableController::onAbortAcquisitionRequested);
176
176
177 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
177 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
178 &VariableController::onDataProvided);
178 &VariableController::onDataProvided);
179 connect(impl->m_VariableAcquisitionWorker.get(),
179 connect(impl->m_VariableAcquisitionWorker.get(),
180 &VariableAcquisitionWorker::variableRequestInProgress, this,
180 &VariableAcquisitionWorker::variableRequestInProgress, this,
181 &VariableController::onVariableRetrieveDataInProgress);
181 &VariableController::onVariableRetrieveDataInProgress);
182
182
183
183
184 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
184 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
185 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
185 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
186 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
186 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
187 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
187 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
188
188
189
189
190 impl->m_VariableAcquisitionWorkerThread.start();
190 impl->m_VariableAcquisitionWorkerThread.start();
191 }
191 }
192
192
193 VariableController::~VariableController()
193 VariableController::~VariableController()
194 {
194 {
195 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
195 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
196 << QThread::currentThread();
196 << QThread::currentThread();
197 this->waitForFinish();
197 this->waitForFinish();
198 }
198 }
199
199
200 VariableModel *VariableController::variableModel() noexcept
200 VariableModel *VariableController::variableModel() noexcept
201 {
201 {
202 return impl->m_VariableModel;
202 return impl->m_VariableModel;
203 }
203 }
204
204
205 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
205 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
206 {
206 {
207 return impl->m_VariableSelectionModel;
207 return impl->m_VariableSelectionModel;
208 }
208 }
209
209
210 void VariableController::setTimeController(TimeController *timeController) noexcept
210 void VariableController::setTimeController(TimeController *timeController) noexcept
211 {
211 {
212 impl->m_TimeController = timeController;
212 impl->m_TimeController = timeController;
213 }
213 }
214
214
215 std::shared_ptr<Variable>
215 std::shared_ptr<Variable>
216 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
216 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
217 {
217 {
218 if (impl->m_VariableModel->containsVariable(variable)) {
218 if (impl->m_VariableModel->containsVariable(variable)) {
219 // Clones variable
219 // Clones variable
220 auto duplicate = variable->clone();
220 auto duplicate = variable->clone();
221
221
222 // Adds clone to model
222 // Adds clone to model
223 impl->m_VariableModel->addVariable(duplicate);
223 impl->m_VariableModel->addVariable(duplicate);
224
224
225 // Generates clone identifier
225 // Generates clone identifier
226 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
226 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
227
227
228 // Registers provider
228 // Registers provider
229 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
229 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
230 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
230 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
231
231
232 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
232 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
233 if (duplicateProvider) {
233 if (duplicateProvider) {
234 impl->registerProvider(duplicateProvider);
234 impl->registerProvider(duplicateProvider);
235 }
235 }
236
236
237 return duplicate;
237 return duplicate;
238 }
238 }
239 else {
239 else {
240 qCCritical(LOG_VariableController())
240 qCCritical(LOG_VariableController())
241 << tr("Can't create duplicate of variable %1: variable not registered in the model")
241 << tr("Can't create duplicate of variable %1: variable not registered in the model")
242 .arg(variable->name());
242 .arg(variable->name());
243 return nullptr;
243 return nullptr;
244 }
244 }
245 }
245 }
246
246
247 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
247 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
248 {
248 {
249 if (!variable) {
249 if (!variable) {
250 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
250 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
251 return;
251 return;
252 }
252 }
253
253
254 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
254 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
255 // make some treatments before the deletion
255 // make some treatments before the deletion
256 emit variableAboutToBeDeleted(variable);
256 emit variableAboutToBeDeleted(variable);
257
257
258 // Deletes identifier
258 // Deletes identifier
259 impl->m_VariableToIdentifierMap.erase(variable);
259 impl->m_VariableToIdentifierMap.erase(variable);
260
260
261 // Deletes provider
261 // Deletes provider
262 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
262 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
263 qCDebug(LOG_VariableController())
263 qCDebug(LOG_VariableController())
264 << tr("Number of providers deleted for variable %1: %2")
264 << tr("Number of providers deleted for variable %1: %2")
265 .arg(variable->name(), QString::number(nbProvidersDeleted));
265 .arg(variable->name(), QString::number(nbProvidersDeleted));
266
266
267
267
268 // Deletes from model
268 // Deletes from model
269 impl->m_VariableModel->deleteVariable(variable);
269 impl->m_VariableModel->deleteVariable(variable);
270 }
270 }
271
271
272 void VariableController::deleteVariables(
272 void VariableController::deleteVariables(
273 const QVector<std::shared_ptr<Variable> > &variables) noexcept
273 const QVector<std::shared_ptr<Variable> > &variables) noexcept
274 {
274 {
275 for (auto variable : qAsConst(variables)) {
275 for (auto variable : qAsConst(variables)) {
276 deleteVariable(variable);
276 deleteVariable(variable);
277 }
277 }
278 }
278 }
279
279
280 std::shared_ptr<Variable>
280 std::shared_ptr<Variable>
281 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
281 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
282 std::shared_ptr<IDataProvider> provider) noexcept
282 std::shared_ptr<IDataProvider> provider) noexcept
283 {
283 {
284 if (!impl->m_TimeController) {
284 if (!impl->m_TimeController) {
285 qCCritical(LOG_VariableController())
285 qCCritical(LOG_VariableController())
286 << tr("Impossible to create variable: The time controller is null");
286 << tr("Impossible to create variable: The time controller is null");
287 return nullptr;
287 return nullptr;
288 }
288 }
289
289
290 auto range = impl->m_TimeController->dateTime();
290 auto range = impl->m_TimeController->dateTime();
291
291
292 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
292 if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) {
293 auto varId = QUuid::createUuid();
293 auto varId = QUuid::createUuid();
294
294
295 // Create the handler
295 // Create the handler
296 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
296 auto varRequestHandler = std::make_unique<VariableRequestHandler>();
297 varRequestHandler->m_VarId = varId;
297 varRequestHandler->m_VarId = varId;
298
298
299 impl->m_VarIdToVarRequestHandler.insert(
299 impl->m_VarIdToVarRequestHandler.insert(
300 std::make_pair(varId, std::move(varRequestHandler)));
300 std::make_pair(varId, std::move(varRequestHandler)));
301
301
302 // store the provider
302 // store the provider
303 impl->registerProvider(provider);
303 impl->registerProvider(provider);
304
304
305 // Associate the provider
305 // Associate the provider
306 impl->m_VariableToProviderMap[newVariable] = provider;
306 impl->m_VariableToProviderMap[newVariable] = provider;
307 impl->m_VariableToIdentifierMap[newVariable] = varId;
307 impl->m_VariableToIdentifierMap[newVariable] = varId;
308
308
309 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
309 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{newVariable}, range, false);
310
310
311 // auto varRequestId = QUuid::createUuid();
311 // auto varRequestId = QUuid::createUuid();
312 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
312 // qCInfo(LOG_VariableController()) << "createVariable: " << varId << varRequestId;
313 // impl->processRequest(newVariable, range, varRequestId);
313 // impl->processRequest(newVariable, range, varRequestId);
314 // impl->updateVariableRequest(varRequestId);
314 // impl->updateVariableRequest(varRequestId);
315
315
316 return newVariable;
316 return newVariable;
317 }
317 }
318 }
318 }
319
319
320 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
320 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
321 {
321 {
322 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
322 // NOTE: Even if acquisition request is aborting, the graphe range will be changed
323 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
323 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
324 << QThread::currentThread()->objectName();
324 << QThread::currentThread()->objectName();
325 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
325 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
326
326
327 // NOTE we only permit the time modification for one variable
327 // NOTE we only permit the time modification for one variable
328 // DEPRECATED
328 // DEPRECATED
329 // auto variables = QVector<std::shared_ptr<Variable> >{};
329 // auto variables = QVector<std::shared_ptr<Variable> >{};
330 // for (const auto &selectedRow : qAsConst(selectedRows)) {
330 // for (const auto &selectedRow : qAsConst(selectedRows)) {
331 // if (auto selectedVariable =
331 // if (auto selectedVariable =
332 // impl->m_VariableModel->variable(selectedRow.row())) {
332 // impl->m_VariableModel->variable(selectedRow.row())) {
333 // variables << selectedVariable;
333 // variables << selectedVariable;
334
334
335 // // notify that rescale operation has to be done
335 // // notify that rescale operation has to be done
336 // emit rangeChanged(selectedVariable, dateTime);
336 // emit rangeChanged(selectedVariable, dateTime);
337 // }
337 // }
338 // }
338 // }
339 // if (!variables.isEmpty()) {
339 // if (!variables.isEmpty()) {
340 // this->onRequestDataLoading(variables, dateTime, synchro);
340 // this->onRequestDataLoading(variables, dateTime, synchro);
341 // }
341 // }
342 if (selectedRows.size() == 1) {
342 if (selectedRows.size() == 1) {
343
343
344 if (auto selectedVariable
344 if (auto selectedVariable
345 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
345 = impl->m_VariableModel->variable(qAsConst(selectedRows).first().row())) {
346
346
347 auto itVar = impl->m_VariableToIdentifierMap.find(selectedVariable);
347 auto itVar = impl->m_VariableToIdentifierMap.find(selectedVariable);
348 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
348 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
349 qCCritical(LOG_VariableController())
349 qCCritical(LOG_VariableController())
350 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
350 << tr("Impossible to onDateTimeOnSelection request for unknown variable");
351 return;
351 return;
352 }
352 }
353
353
354 // notify that rescale operation has to be done
354 // notify that rescale operation has to be done
355 emit rangeChanged(selectedVariable, dateTime);
355 emit rangeChanged(selectedVariable, dateTime);
356
356
357 auto synchro = impl->m_VariableIdGroupIdMap.find(itVar->second)
357 auto synchro = impl->m_VariableIdGroupIdMap.find(itVar->second)
358 != impl->m_VariableIdGroupIdMap.cend();
358 != impl->m_VariableIdGroupIdMap.cend();
359
359
360 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{selectedVariable},
360 this->onRequestDataLoading(QVector<std::shared_ptr<Variable> >{selectedVariable},
361 dateTime, synchro);
361 dateTime, synchro);
362 }
362 }
363 }
363 }
364 else if (selectedRows.size() > 1) {
364 else if (selectedRows.size() > 1) {
365 qCCritical(LOG_VariableController())
365 qCCritical(LOG_VariableController())
366 << tr("Impossible to set time for more than 1 variable in the same time");
366 << tr("Impossible to set time for more than 1 variable in the same time");
367 }
367 }
368 else {
368 else {
369 qCWarning(LOG_VariableController())
369 qCWarning(LOG_VariableController())
370 << tr("There is no variable selected to set the time one");
370 << tr("There is no variable selected to set the time one");
371 }
371 }
372 }
372 }
373
373
374 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
374 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
375 const SqpRange &cacheRangeRequested,
375 const SqpRange &cacheRangeRequested,
376 QVector<AcquisitionDataPacket> dataAcquired)
376 QVector<AcquisitionDataPacket> dataAcquired)
377 {
377 {
378 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
378 qCDebug(LOG_VariableController()) << tr("onDataProvided") << QThread::currentThread();
379 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
379 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
380 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
380 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
381 if (!varRequestId.isNull()) {
381 if (!varRequestId.isNull()) {
382 impl->updateVariables(varRequestId);
382 impl->updateVariables(varRequestId);
383 }
383 }
384 }
384 }
385
385
386 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
386 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
387 {
387 {
388 qCDebug(LOG_VariableController())
388 qCDebug(LOG_VariableController())
389 << "TORM: variableController::onVariableRetrieveDataInProgress"
389 << "TORM: variableController::onVariableRetrieveDataInProgress"
390 << QThread::currentThread()->objectName() << progress;
390 << QThread::currentThread()->objectName() << progress;
391 if (auto var = impl->findVariable(identifier)) {
391 if (auto var = impl->findVariable(identifier)) {
392 impl->m_VariableModel->setDataProgress(var, progress);
392 impl->m_VariableModel->setDataProgress(var, progress);
393 }
393 }
394 else {
394 else {
395 qCCritical(LOG_VariableController())
395 qCCritical(LOG_VariableController())
396 << tr("Impossible to notify progression of a null variable");
396 << tr("Impossible to notify progression of a null variable");
397 }
397 }
398 }
398 }
399
399
400 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
400 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
401 {
401 {
402 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
402 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortProgressRequested"
403 << QThread::currentThread()->objectName() << variable->name();
403 << QThread::currentThread()->objectName() << variable->name();
404
404
405 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
405 auto itVar = impl->m_VariableToIdentifierMap.find(variable);
406 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
406 if (itVar == impl->m_VariableToIdentifierMap.cend()) {
407 qCCritical(LOG_VariableController())
407 qCCritical(LOG_VariableController())
408 << tr("Impossible to onAbortProgressRequested request for unknown variable");
408 << tr("Impossible to onAbortProgressRequested request for unknown variable");
409 return;
409 return;
410 }
410 }
411
411
412 auto varId = itVar->second;
412 auto varId = itVar->second;
413
413
414 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
414 auto itVarHandler = impl->m_VarIdToVarRequestHandler.find(varId);
415 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
415 if (itVarHandler == impl->m_VarIdToVarRequestHandler.cend()) {
416 qCCritical(LOG_VariableController())
416 qCCritical(LOG_VariableController())
417 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
417 << tr("Impossible to onAbortProgressRequested for variable with unknown handler");
418 return;
418 return;
419 }
419 }
420
420
421 auto varHandler = itVarHandler->second.get();
421 auto varHandler = itVarHandler->second.get();
422
422
423 // case where a variable has a running request
423 // case where a variable has a running request
424 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
424 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
425 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
425 impl->cancelVariableRequest(varHandler->m_RunningVarRequest.m_VariableGroupId);
426 }
426 }
427 }
427 }
428
428
429 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
429 void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier)
430 {
430 {
431 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
431 qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested"
432 << QThread::currentThread()->objectName() << vIdentifier;
432 << QThread::currentThread()->objectName() << vIdentifier;
433
433
434 if (auto var = impl->findVariable(vIdentifier)) {
434 if (auto var = impl->findVariable(vIdentifier)) {
435 this->onAbortProgressRequested(var);
435 this->onAbortProgressRequested(var);
436 }
436 }
437 else {
437 else {
438 qCCritical(LOG_VariableController())
438 qCCritical(LOG_VariableController())
439 << tr("Impossible to abort Acquisition Requestof a null variable");
439 << tr("Impossible to abort Acquisition Requestof a null variable");
440 }
440 }
441 }
441 }
442
442
443 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
443 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
444 {
444 {
445 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
445 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId"
446 << QThread::currentThread()->objectName()
446 << QThread::currentThread()->objectName()
447 << synchronizationGroupId;
447 << synchronizationGroupId;
448 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
448 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
449 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
449 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
450 std::make_pair(synchronizationGroupId, vSynchroGroup));
450 std::make_pair(synchronizationGroupId, vSynchroGroup));
451 }
451 }
452
452
453 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
453 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
454 {
454 {
455 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
455 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
456 }
456 }
457
457
458 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
458 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
459 QUuid synchronizationGroupId)
459 QUuid synchronizationGroupId)
460
460
461 {
461 {
462 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
462 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronized"
463 << synchronizationGroupId;
463 << synchronizationGroupId;
464 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
464 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
465 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
465 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
466 auto groupIdToVSGIt
466 auto groupIdToVSGIt
467 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
467 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
468 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
468 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
469 impl->m_VariableIdGroupIdMap.insert(
469 impl->m_VariableIdGroupIdMap.insert(
470 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
470 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
471 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
471 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
472 }
472 }
473 else {
473 else {
474 qCCritical(LOG_VariableController())
474 qCCritical(LOG_VariableController())
475 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
475 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
476 << variable->name();
476 << variable->name();
477 }
477 }
478 }
478 }
479 else {
479 else {
480 qCCritical(LOG_VariableController())
480 qCCritical(LOG_VariableController())
481 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
481 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
482 }
482 }
483 }
483 }
484
484
485 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
485 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
486 QUuid synchronizationGroupId)
486 QUuid synchronizationGroupId)
487 {
487 {
488 // Gets variable id
488 // Gets variable id
489 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
489 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
490 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
490 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
491 qCCritical(LOG_VariableController())
491 qCCritical(LOG_VariableController())
492 << tr("Can't desynchronize variable %1: variable identifier not found")
492 << tr("Can't desynchronize variable %1: variable identifier not found")
493 .arg(variable->name());
493 .arg(variable->name());
494 return;
494 return;
495 }
495 }
496
496
497 // Gets synchronization group
497 // Gets synchronization group
498 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
498 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
499 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
499 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
500 qCCritical(LOG_VariableController())
500 qCCritical(LOG_VariableController())
501 << tr("Can't desynchronize variable %1: unknown synchronization group")
501 << tr("Can't desynchronize variable %1: unknown synchronization group")
502 .arg(variable->name());
502 .arg(variable->name());
503 return;
503 return;
504 }
504 }
505
505
506 auto variableId = variableIt->second;
506 auto variableId = variableIt->second;
507
507
508 // Removes variable from synchronization group
508 // Removes variable from synchronization group
509 auto synchronizationGroup = groupIt->second;
509 auto synchronizationGroup = groupIt->second;
510 synchronizationGroup->removeVariableId(variableId);
510 synchronizationGroup->removeVariableId(variableId);
511
511
512 // Removes link between variable and synchronization group
512 // Removes link between variable and synchronization group
513 impl->m_VariableIdGroupIdMap.erase(variableId);
513 impl->m_VariableIdGroupIdMap.erase(variableId);
514 }
514 }
515
515
516 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
516 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
517 const SqpRange &range, bool synchronise)
517 const SqpRange &range, bool synchronise)
518 {
518 {
519 // variables is assumed synchronized
519 // variables is assumed synchronized
520 // TODO: Asser variables synchronization
520 // TODO: Asser variables synchronization
521 // we want to load data of the variable for the dateTime.
521 // we want to load data of the variable for the dateTime.
522 if (variables.isEmpty()) {
522 if (variables.isEmpty()) {
523 return;
523 return;
524 }
524 }
525
525
526 auto varRequestId = QUuid::createUuid();
526 auto varRequestId = QUuid::createUuid();
527 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
527 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
528 << QThread::currentThread()->objectName() << varRequestId
528 << QThread::currentThread()->objectName() << varRequestId
529 << range << synchronise;
529 << range << synchronise;
530
530
531 if (!synchronise) {
531 if (!synchronise) {
532 auto varIds = std::list<QUuid>{};
532 auto varIds = std::list<QUuid>{};
533 for (const auto &var : variables) {
533 for (const auto &var : variables) {
534 auto vId = impl->m_VariableToIdentifierMap.at(var);
534 auto vId = impl->m_VariableToIdentifierMap.at(var);
535 varIds.push_back(vId);
535 varIds.push_back(vId);
536 }
536 }
537 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
537 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
538 for (const auto &var : variables) {
538 for (const auto &var : variables) {
539 qCInfo(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
539 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId
540 << varIds.size();
540 << varIds.size();
541 impl->processRequest(var, range, varRequestId);
541 impl->processRequest(var, range, varRequestId);
542 }
542 }
543 }
543 }
544 else {
544 else {
545 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
545 auto vId = impl->m_VariableToIdentifierMap.at(variables.first());
546 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
546 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
547 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
547 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
548 auto groupId = varIdToGroupIdIt->second;
548 auto groupId = varIdToGroupIdIt->second;
549
549
550 auto vSynchronizationGroup
550 auto vSynchronizationGroup
551 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
551 = impl->m_GroupIdToVariableSynchronizationGroupMap.at(groupId);
552 auto vSyncIds = vSynchronizationGroup->getIds();
552 auto vSyncIds = vSynchronizationGroup->getIds();
553
553
554 auto varIds = std::list<QUuid>{};
554 auto varIds = std::list<QUuid>{};
555 for (auto vId : vSyncIds) {
555 for (auto vId : vSyncIds) {
556 varIds.push_back(vId);
556 varIds.push_back(vId);
557 }
557 }
558 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
558 impl->m_VarGroupIdToVarIds.insert(std::make_pair(varRequestId, varIds));
559
559
560 for (auto vId : vSyncIds) {
560 for (auto vId : vSyncIds) {
561 auto var = impl->findVariable(vId);
561 auto var = impl->findVariable(vId);
562
562
563 // Don't process already processed var
563 // Don't process already processed var
564 if (var != nullptr) {
564 if (var != nullptr) {
565 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
565 qCDebug(LOG_VariableController()) << "processRequest synchro for" << var->name()
566 << varRequestId;
566 << varRequestId;
567 auto vSyncRangeRequested
567 auto vSyncRangeRequested
568 = variables.contains(var)
568 = variables.contains(var)
569 ? range
569 ? range
570 : computeSynchroRangeRequested(var->range(), range,
570 : computeSynchroRangeRequested(var->range(), range,
571 variables.first()->range());
571 variables.first()->range());
572 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
572 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
573 impl->processRequest(var, vSyncRangeRequested, varRequestId);
573 impl->processRequest(var, vSyncRangeRequested, varRequestId);
574 }
574 }
575 else {
575 else {
576 qCCritical(LOG_VariableController())
576 qCCritical(LOG_VariableController())
577
577
578 << tr("Impossible to synchronize a null variable");
578 << tr("Impossible to synchronize a null variable");
579 }
579 }
580 }
580 }
581 }
581 }
582 }
582 }
583
583
584 impl->updateVariables(varRequestId);
584 impl->updateVariables(varRequestId);
585 }
585 }
586
586
587
587
588 void VariableController::initialize()
588 void VariableController::initialize()
589 {
589 {
590 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
590 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
591 impl->m_WorkingMutex.lock();
591 impl->m_WorkingMutex.lock();
592 qCDebug(LOG_VariableController()) << tr("VariableController init END");
592 qCDebug(LOG_VariableController()) << tr("VariableController init END");
593 }
593 }
594
594
595 void VariableController::finalize()
595 void VariableController::finalize()
596 {
596 {
597 impl->m_WorkingMutex.unlock();
597 impl->m_WorkingMutex.unlock();
598 }
598 }
599
599
600 void VariableController::waitForFinish()
600 void VariableController::waitForFinish()
601 {
601 {
602 QMutexLocker locker{&impl->m_WorkingMutex};
602 QMutexLocker locker{&impl->m_WorkingMutex};
603 }
603 }
604
604
605 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
605 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
606 {
606 {
607 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
607 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
608 auto zoomType = AcquisitionZoomType::Unknown;
608 auto zoomType = AcquisitionZoomType::Unknown;
609 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
609 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
610 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
610 qCDebug(LOG_VariableController()) << "zoomtype: ZoomOut";
611 zoomType = AcquisitionZoomType::ZoomOut;
611 zoomType = AcquisitionZoomType::ZoomOut;
612 }
612 }
613 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
613 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
614 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
614 qCDebug(LOG_VariableController()) << "zoomtype: PanRight";
615 zoomType = AcquisitionZoomType::PanRight;
615 zoomType = AcquisitionZoomType::PanRight;
616 }
616 }
617 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
617 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
618 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
618 qCDebug(LOG_VariableController()) << "zoomtype: PanLeft";
619 zoomType = AcquisitionZoomType::PanLeft;
619 zoomType = AcquisitionZoomType::PanLeft;
620 }
620 }
621 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
621 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
622 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
622 qCDebug(LOG_VariableController()) << "zoomtype: ZoomIn";
623 zoomType = AcquisitionZoomType::ZoomIn;
623 zoomType = AcquisitionZoomType::ZoomIn;
624 }
624 }
625 else {
625 else {
626 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
626 qCDebug(LOG_VariableController()) << "getZoomType: Unknown type detected";
627 }
627 }
628 return zoomType;
628 return zoomType;
629 }
629 }
630
630
631 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
631 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
632 const SqpRange &rangeRequested,
632 const SqpRange &rangeRequested,
633 QUuid varRequestId)
633 QUuid varRequestId)
634 {
634 {
635 auto itVar = m_VariableToIdentifierMap.find(var);
635 auto itVar = m_VariableToIdentifierMap.find(var);
636 if (itVar == m_VariableToIdentifierMap.cend()) {
636 if (itVar == m_VariableToIdentifierMap.cend()) {
637 qCCritical(LOG_VariableController())
637 qCCritical(LOG_VariableController())
638 << tr("Impossible to process request for unknown variable");
638 << tr("Impossible to process request for unknown variable");
639 return;
639 return;
640 }
640 }
641
641
642 auto varId = itVar->second;
642 auto varId = itVar->second;
643
643
644 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
644 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
645 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
645 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
646 qCCritical(LOG_VariableController())
646 qCCritical(LOG_VariableController())
647 << tr("Impossible to process request for variable with unknown handler");
647 << tr("Impossible to process request for variable with unknown handler");
648 return;
648 return;
649 }
649 }
650
650
651 auto oldRange = var->range();
651 auto oldRange = var->range();
652
652
653 auto varHandler = itVarHandler->second.get();
653 auto varHandler = itVarHandler->second.get();
654
654
655 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
655 if (varHandler->m_State != VariableRequestHandlerState::OFF) {
656 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
656 oldRange = varHandler->m_RunningVarRequest.m_RangeRequested;
657 }
657 }
658
658
659 auto varRequest = VariableRequest{};
659 auto varRequest = VariableRequest{};
660 varRequest.m_VariableGroupId = varRequestId;
660 varRequest.m_VariableGroupId = varRequestId;
661 auto varStrategyRangesRequested
661 auto varStrategyRangesRequested
662 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
662 = m_VariableCacheStrategy->computeRange(oldRange, rangeRequested);
663 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
663 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
664 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
664 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
665
665
666 switch (varHandler->m_State) {
666 switch (varHandler->m_State) {
667 case VariableRequestHandlerState::OFF: {
667 case VariableRequestHandlerState::OFF: {
668 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
668 qCDebug(LOG_VariableController()) << tr("Process Request OFF")
669 << varRequest.m_RangeRequested
669 << varRequest.m_RangeRequested
670 << varRequest.m_CacheRangeRequested;
670 << varRequest.m_CacheRangeRequested;
671 varHandler->m_RunningVarRequest = varRequest;
671 varHandler->m_RunningVarRequest = varRequest;
672 varHandler->m_State = VariableRequestHandlerState::RUNNING;
672 varHandler->m_State = VariableRequestHandlerState::RUNNING;
673 executeVarRequest(var, varRequest);
673 executeVarRequest(var, varRequest);
674 break;
674 break;
675 }
675 }
676 case VariableRequestHandlerState::RUNNING: {
676 case VariableRequestHandlerState::RUNNING: {
677 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
677 qCDebug(LOG_VariableController()) << tr("Process Request RUNNING")
678 << varRequest.m_RangeRequested
678 << varRequest.m_RangeRequested
679 << varRequest.m_CacheRangeRequested;
679 << varRequest.m_CacheRangeRequested;
680 varHandler->m_State = VariableRequestHandlerState::PENDING;
680 varHandler->m_State = VariableRequestHandlerState::PENDING;
681 varHandler->m_PendingVarRequest = varRequest;
681 varHandler->m_PendingVarRequest = varRequest;
682 break;
682 break;
683 }
683 }
684 case VariableRequestHandlerState::PENDING: {
684 case VariableRequestHandlerState::PENDING: {
685 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
685 qCDebug(LOG_VariableController()) << tr("Process Request PENDING")
686 << varRequest.m_RangeRequested
686 << varRequest.m_RangeRequested
687 << varRequest.m_CacheRangeRequested;
687 << varRequest.m_CacheRangeRequested;
688 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
688 auto variableGroupIdToCancel = varHandler->m_PendingVarRequest.m_VariableGroupId;
689 cancelVariableRequest(variableGroupIdToCancel);
689 cancelVariableRequest(variableGroupIdToCancel);
690 // Cancel variable can make state downgrade
690 // Cancel variable can make state downgrade
691 varHandler->m_State = VariableRequestHandlerState::PENDING;
691 varHandler->m_State = VariableRequestHandlerState::PENDING;
692 varHandler->m_PendingVarRequest = varRequest;
692 varHandler->m_PendingVarRequest = varRequest;
693
693
694 break;
694 break;
695 }
695 }
696 default:
696 default:
697 qCCritical(LOG_VariableController())
697 qCCritical(LOG_VariableController())
698 << QObject::tr("Unknown VariableRequestHandlerState");
698 << QObject::tr("Unknown VariableRequestHandlerState");
699 }
699 }
700 }
700 }
701
701
702 std::shared_ptr<Variable>
702 std::shared_ptr<Variable>
703 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
703 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
704 {
704 {
705 std::shared_ptr<Variable> var;
705 std::shared_ptr<Variable> var;
706 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
706 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
707
707
708 auto end = m_VariableToIdentifierMap.cend();
708 auto end = m_VariableToIdentifierMap.cend();
709 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
709 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
710 if (it != end) {
710 if (it != end) {
711 var = it->first;
711 var = it->first;
712 }
712 }
713 else {
713 else {
714 qCCritical(LOG_VariableController())
714 qCCritical(LOG_VariableController())
715 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
715 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
716 }
716 }
717
717
718 return var;
718 return var;
719 }
719 }
720
720
721 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
721 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
722 const QVector<AcquisitionDataPacket> acqDataPacketVector)
722 const QVector<AcquisitionDataPacket> acqDataPacketVector)
723 {
723 {
724 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
724 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size")
725 << acqDataPacketVector.size();
725 << acqDataPacketVector.size();
726 std::shared_ptr<IDataSeries> dataSeries;
726 std::shared_ptr<IDataSeries> dataSeries;
727 if (!acqDataPacketVector.isEmpty()) {
727 if (!acqDataPacketVector.isEmpty()) {
728 dataSeries = acqDataPacketVector[0].m_DateSeries;
728 dataSeries = acqDataPacketVector[0].m_DateSeries;
729 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
729 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
730 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
730 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
731 }
731 }
732 }
732 }
733 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
733 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
734 << acqDataPacketVector.size();
734 << acqDataPacketVector.size();
735 return dataSeries;
735 return dataSeries;
736 }
736 }
737
737
738 void VariableController::VariableControllerPrivate::registerProvider(
738 void VariableController::VariableControllerPrivate::registerProvider(
739 std::shared_ptr<IDataProvider> provider)
739 std::shared_ptr<IDataProvider> provider)
740 {
740 {
741 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
741 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
742 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
742 qCDebug(LOG_VariableController()) << tr("Registering of a new provider")
743 << provider->objectName();
743 << provider->objectName();
744 m_ProviderSet.insert(provider);
744 m_ProviderSet.insert(provider);
745 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
745 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
746 &VariableAcquisitionWorker::onVariableDataAcquired);
746 &VariableAcquisitionWorker::onVariableDataAcquired);
747 connect(provider.get(), &IDataProvider::dataProvidedProgress,
747 connect(provider.get(), &IDataProvider::dataProvidedProgress,
748 m_VariableAcquisitionWorker.get(),
748 m_VariableAcquisitionWorker.get(),
749 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
749 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
750 connect(provider.get(), &IDataProvider::dataProvidedFailed,
750 connect(provider.get(), &IDataProvider::dataProvidedFailed,
751 m_VariableAcquisitionWorker.get(),
751 m_VariableAcquisitionWorker.get(),
752 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
752 &VariableAcquisitionWorker::onVariableAcquisitionFailed);
753 }
753 }
754 else {
754 else {
755 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
755 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
756 }
756 }
757 }
757 }
758
758
759 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
759 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
760 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
760 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
761 {
761 {
762 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
762 auto itVarHandler = m_VarIdToVarRequestHandler.find(varId);
763 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
763 if (itVarHandler == m_VarIdToVarRequestHandler.cend()) {
764 return QUuid();
764 return QUuid();
765 }
765 }
766
766
767 auto varHandler = itVarHandler->second.get();
767 auto varHandler = itVarHandler->second.get();
768 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
768 if (varHandler->m_State == VariableRequestHandlerState::OFF) {
769 qCCritical(LOG_VariableController())
769 qCCritical(LOG_VariableController())
770 << tr("acceptVariableRequest impossible on a variable with OFF state");
770 << tr("acceptVariableRequest impossible on a variable with OFF state");
771 }
771 }
772
772
773 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
773 varHandler->m_RunningVarRequest.m_DataSeries = dataSeries;
774 varHandler->m_CanUpdate = true;
774 varHandler->m_CanUpdate = true;
775
775
776 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
776 // Element traitΓ©, on a dΓ©jΓ  toutes les donnΓ©es necessaires
777 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
777 auto varGroupId = varHandler->m_RunningVarRequest.m_VariableGroupId;
778 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
778 qCDebug(LOG_VariableController()) << "Variable::acceptVariableRequest" << varGroupId
779 << m_VarGroupIdToVarIds.size();
779 << m_VarGroupIdToVarIds.size();
780
780
781 return varHandler->m_RunningVarRequest.m_VariableGroupId;
781 return varHandler->m_RunningVarRequest.m_VariableGroupId;
782 }
782 }
783
783
784 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
784 void VariableController::VariableControllerPrivate::updateVariables(QUuid varRequestId)
785 {
785 {
786 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
786 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
787 << QThread::currentThread()->objectName() << varRequestId;
787 << QThread::currentThread()->objectName() << varRequestId;
788
788
789 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
789 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
790 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
790 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
791 qCWarning(LOG_VariableController())
791 qCWarning(LOG_VariableController())
792 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
792 << tr("Impossible to updateVariables of unknown variables") << varRequestId;
793 return;
793 return;
794 }
794 }
795
795
796 auto &varIds = varGroupIdToVarIdsIt->second;
796 auto &varIds = varGroupIdToVarIdsIt->second;
797 auto varIdsEnd = varIds.end();
797 auto varIdsEnd = varIds.end();
798 bool processVariableUpdate = true;
798 bool processVariableUpdate = true;
799 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
799 qCDebug(LOG_VariableController()) << "VariableControllerPrivate::updateVariables"
800 << varRequestId << varIds.size();
800 << varRequestId << varIds.size();
801 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
801 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd) && processVariableUpdate;
802 ++varIdsIt) {
802 ++varIdsIt) {
803 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
803 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
804 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
804 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
805 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
805 processVariableUpdate &= itVarHandler->second->m_CanUpdate;
806 }
806 }
807 }
807 }
808
808
809 if (processVariableUpdate) {
809 if (processVariableUpdate) {
810 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
810 qCDebug(LOG_VariableController()) << "Final update OK for the var request" << varIds.size();
811 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
811 for (auto varIdsIt = varIds.begin(); varIdsIt != varIdsEnd; ++varIdsIt) {
812 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
812 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
813 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
813 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
814 if (auto var = findVariable(*varIdsIt)) {
814 if (auto var = findVariable(*varIdsIt)) {
815 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
815 auto &varRequest = itVarHandler->second->m_RunningVarRequest;
816 var->setRange(varRequest.m_RangeRequested);
816 var->setRange(varRequest.m_RangeRequested);
817 var->setCacheRange(varRequest.m_CacheRangeRequested);
817 var->setCacheRange(varRequest.m_CacheRangeRequested);
818 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
818 qCDebug(LOG_VariableController()) << tr("1: onDataProvided")
819 << varRequest.m_RangeRequested
819 << varRequest.m_RangeRequested
820 << varRequest.m_CacheRangeRequested;
820 << varRequest.m_CacheRangeRequested;
821 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
821 qCDebug(LOG_VariableController()) << tr("2: onDataProvided var points before")
822 << var->nbPoints()
822 << var->nbPoints()
823 << varRequest.m_DataSeries->nbPoints();
823 << varRequest.m_DataSeries->nbPoints();
824 var->mergeDataSeries(varRequest.m_DataSeries);
824 var->mergeDataSeries(varRequest.m_DataSeries);
825 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
825 qCDebug(LOG_VariableController()) << tr("3: onDataProvided var points after")
826 << var->nbPoints();
826 << var->nbPoints();
827
827
828 emit var->updated();
828 emit var->updated();
829 qCDebug(LOG_VariableController()) << tr("Update OK");
829 qCDebug(LOG_VariableController()) << tr("Update OK");
830 }
830 }
831 else {
831 else {
832 qCCritical(LOG_VariableController())
832 qCCritical(LOG_VariableController())
833 << tr("Impossible to update data to a null variable");
833 << tr("Impossible to update data to a null variable");
834 }
834 }
835 }
835 }
836 }
836 }
837 updateVariableRequest(varRequestId);
837 updateVariableRequest(varRequestId);
838
838
839 // cleaning varRequestId
839 // cleaning varRequestId
840 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
840 qCDebug(LOG_VariableController()) << tr("m_VarGroupIdToVarIds erase") << varRequestId;
841 m_VarGroupIdToVarIds.erase(varRequestId);
841 m_VarGroupIdToVarIds.erase(varRequestId);
842 }
842 }
843 }
843 }
844
844
845
845
846 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
846 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
847 {
847 {
848 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
848 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
849 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
849 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
850 qCCritical(LOG_VariableController()) << QObject::tr(
850 qCCritical(LOG_VariableController()) << QObject::tr(
851 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
851 "Impossible to updateVariableRequest since varGroupdId isn't here anymore");
852
852
853 return;
853 return;
854 }
854 }
855
855
856 auto &varIds = varGroupIdToVarIdsIt->second;
856 auto &varIds = varGroupIdToVarIdsIt->second;
857 auto varIdsEnd = varIds.end();
857 auto varIdsEnd = varIds.end();
858 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
858 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
859 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
859 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
860 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
860 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
861
861
862 auto varHandler = itVarHandler->second.get();
862 auto varHandler = itVarHandler->second.get();
863 varHandler->m_CanUpdate = false;
863 varHandler->m_CanUpdate = false;
864
864
865
865
866 switch (varHandler->m_State) {
866 switch (varHandler->m_State) {
867 case VariableRequestHandlerState::OFF: {
867 case VariableRequestHandlerState::OFF: {
868 qCCritical(LOG_VariableController())
868 qCCritical(LOG_VariableController())
869 << QObject::tr("Impossible to update a variable with handler in OFF state");
869 << QObject::tr("Impossible to update a variable with handler in OFF state");
870 } break;
870 } break;
871 case VariableRequestHandlerState::RUNNING: {
871 case VariableRequestHandlerState::RUNNING: {
872 varHandler->m_State = VariableRequestHandlerState::OFF;
872 varHandler->m_State = VariableRequestHandlerState::OFF;
873 varHandler->m_RunningVarRequest = VariableRequest{};
873 varHandler->m_RunningVarRequest = VariableRequest{};
874 break;
874 break;
875 }
875 }
876 case VariableRequestHandlerState::PENDING: {
876 case VariableRequestHandlerState::PENDING: {
877 varHandler->m_State = VariableRequestHandlerState::RUNNING;
877 varHandler->m_State = VariableRequestHandlerState::RUNNING;
878 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
878 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
879 varHandler->m_PendingVarRequest = VariableRequest{};
879 varHandler->m_PendingVarRequest = VariableRequest{};
880 auto var = findVariable(itVarHandler->first);
880 auto var = findVariable(itVarHandler->first);
881 executeVarRequest(var, varHandler->m_RunningVarRequest);
881 executeVarRequest(var, varHandler->m_RunningVarRequest);
882 break;
882 break;
883 }
883 }
884 default:
884 default:
885 qCCritical(LOG_VariableController())
885 qCCritical(LOG_VariableController())
886 << QObject::tr("Unknown VariableRequestHandlerState");
886 << QObject::tr("Unknown VariableRequestHandlerState");
887 }
887 }
888 }
888 }
889 }
889 }
890 }
890 }
891
891
892
892
893 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
893 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
894 {
894 {
895 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
895 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest") << varRequestId;
896
896
897 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
897 auto varGroupIdToVarIdsIt = m_VarGroupIdToVarIds.find(varRequestId);
898 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
898 if (varGroupIdToVarIdsIt == m_VarGroupIdToVarIds.end()) {
899 qCCritical(LOG_VariableController())
899 qCCritical(LOG_VariableController())
900 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
900 << tr("Impossible to cancelVariableRequest for unknown varGroupdId") << varRequestId;
901 return;
901 return;
902 }
902 }
903
903
904 auto &varIds = varGroupIdToVarIdsIt->second;
904 auto &varIds = varGroupIdToVarIdsIt->second;
905 auto varIdsEnd = varIds.end();
905 auto varIdsEnd = varIds.end();
906 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
906 for (auto varIdsIt = varIds.begin(); (varIdsIt != varIdsEnd); ++varIdsIt) {
907 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
907 auto itVarHandler = m_VarIdToVarRequestHandler.find(*varIdsIt);
908 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
908 if (itVarHandler != m_VarIdToVarRequestHandler.cend()) {
909
909
910 auto varHandler = itVarHandler->second.get();
910 auto varHandler = itVarHandler->second.get();
911 varHandler->m_VarId = QUuid{};
911 varHandler->m_VarId = QUuid{};
912 switch (varHandler->m_State) {
912 switch (varHandler->m_State) {
913 case VariableRequestHandlerState::OFF: {
913 case VariableRequestHandlerState::OFF: {
914 qCWarning(LOG_VariableController())
914 qCWarning(LOG_VariableController())
915 << QObject::tr("Impossible to cancel a variable with no running request");
915 << QObject::tr("Impossible to cancel a variable with no running request");
916 break;
916 break;
917 }
917 }
918 case VariableRequestHandlerState::RUNNING: {
918 case VariableRequestHandlerState::RUNNING: {
919
919
920 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
920 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
921 auto var = findVariable(itVarHandler->first);
921 auto var = findVariable(itVarHandler->first);
922 auto varProvider = m_VariableToProviderMap.at(var);
922 auto varProvider = m_VariableToProviderMap.at(var);
923 if (varProvider != nullptr) {
923 if (varProvider != nullptr) {
924 m_VariableAcquisitionWorker->abortProgressRequested(
924 m_VariableAcquisitionWorker->abortProgressRequested(
925 itVarHandler->first);
925 itVarHandler->first);
926 }
926 }
927 m_VariableModel->setDataProgress(var, 0.0);
927 m_VariableModel->setDataProgress(var, 0.0);
928 varHandler->m_CanUpdate = false;
928 varHandler->m_CanUpdate = false;
929 varHandler->m_State = VariableRequestHandlerState::OFF;
929 varHandler->m_State = VariableRequestHandlerState::OFF;
930 varHandler->m_RunningVarRequest = VariableRequest{};
930 varHandler->m_RunningVarRequest = VariableRequest{};
931 }
931 }
932 else {
932 else {
933 // TODO: log Impossible to cancel the running variable request beacause its
933 // TODO: log Impossible to cancel the running variable request beacause its
934 // varRequestId isn't not the canceled one
934 // varRequestId isn't not the canceled one
935 }
935 }
936 break;
936 break;
937 }
937 }
938 case VariableRequestHandlerState::PENDING: {
938 case VariableRequestHandlerState::PENDING: {
939 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
939 if (varHandler->m_RunningVarRequest.m_VariableGroupId == varRequestId) {
940 auto var = findVariable(itVarHandler->first);
940 auto var = findVariable(itVarHandler->first);
941 auto varProvider = m_VariableToProviderMap.at(var);
941 auto varProvider = m_VariableToProviderMap.at(var);
942 if (varProvider != nullptr) {
942 if (varProvider != nullptr) {
943 m_VariableAcquisitionWorker->abortProgressRequested(
943 m_VariableAcquisitionWorker->abortProgressRequested(
944 itVarHandler->first);
944 itVarHandler->first);
945 }
945 }
946 m_VariableModel->setDataProgress(var, 0.0);
946 m_VariableModel->setDataProgress(var, 0.0);
947 varHandler->m_CanUpdate = false;
947 varHandler->m_CanUpdate = false;
948 varHandler->m_State = VariableRequestHandlerState::RUNNING;
948 varHandler->m_State = VariableRequestHandlerState::RUNNING;
949 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
949 varHandler->m_RunningVarRequest = varHandler->m_PendingVarRequest;
950 varHandler->m_PendingVarRequest = VariableRequest{};
950 varHandler->m_PendingVarRequest = VariableRequest{};
951 executeVarRequest(var, varHandler->m_RunningVarRequest);
951 executeVarRequest(var, varHandler->m_RunningVarRequest);
952 }
952 }
953 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
953 else if (varHandler->m_PendingVarRequest.m_VariableGroupId == varRequestId) {
954 varHandler->m_State = VariableRequestHandlerState::RUNNING;
954 varHandler->m_State = VariableRequestHandlerState::RUNNING;
955 varHandler->m_PendingVarRequest = VariableRequest{};
955 varHandler->m_PendingVarRequest = VariableRequest{};
956 }
956 }
957 else {
957 else {
958 // TODO: log Impossible to cancel the variable request beacause its
958 // TODO: log Impossible to cancel the variable request beacause its
959 // varRequestId isn't not the canceled one
959 // varRequestId isn't not the canceled one
960 }
960 }
961 break;
961 break;
962 }
962 }
963 default:
963 default:
964 qCCritical(LOG_VariableController())
964 qCCritical(LOG_VariableController())
965 << QObject::tr("Unknown VariableRequestHandlerState");
965 << QObject::tr("Unknown VariableRequestHandlerState");
966 }
966 }
967 }
967 }
968 }
968 }
969 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
969 qCDebug(LOG_VariableController()) << tr("cancelVariableRequest: erase") << varRequestId;
970 m_VarGroupIdToVarIds.erase(varRequestId);
970 m_VarGroupIdToVarIds.erase(varRequestId);
971 }
971 }
972
972
973 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
973 void VariableController::VariableControllerPrivate::executeVarRequest(std::shared_ptr<Variable> var,
974 VariableRequest &varRequest)
974 VariableRequest &varRequest)
975 {
975 {
976 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
976 qCDebug(LOG_VariableController()) << tr("TORM: executeVarRequest");
977
977
978 auto varId = m_VariableToIdentifierMap.at(var);
978 auto varId = m_VariableToIdentifierMap.at(var);
979
979
980 auto varCacheRange = var->cacheRange();
980 auto varCacheRange = var->cacheRange();
981 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
981 auto varCacheRangeRequested = varRequest.m_CacheRangeRequested;
982 auto notInCacheRangeList
982 auto notInCacheRangeList
983 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
983 = Variable::provideNotInCacheRangeList(varCacheRange, varCacheRangeRequested);
984 auto inCacheRangeList
984 auto inCacheRangeList
985 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
985 = Variable::provideInCacheRangeList(varCacheRange, varCacheRangeRequested);
986
986
987 if (!notInCacheRangeList.empty()) {
987 if (!notInCacheRangeList.empty()) {
988
988
989 auto varProvider = m_VariableToProviderMap.at(var);
989 auto varProvider = m_VariableToProviderMap.at(var);
990 if (varProvider != nullptr) {
990 if (varProvider != nullptr) {
991 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
991 qCDebug(LOG_VariableController()) << "executeVarRequest " << varRequest.m_RangeRequested
992 << varRequest.m_CacheRangeRequested;
992 << varRequest.m_CacheRangeRequested;
993 m_VariableAcquisitionWorker->pushVariableRequest(
993 m_VariableAcquisitionWorker->pushVariableRequest(
994 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
994 varRequest.m_VariableGroupId, varId, varRequest.m_RangeRequested,
995 varRequest.m_CacheRangeRequested,
995 varRequest.m_CacheRangeRequested,
996 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
996 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
997 varProvider);
997 varProvider);
998 }
998 }
999 else {
999 else {
1000 qCCritical(LOG_VariableController())
1000 qCCritical(LOG_VariableController())
1001 << "Impossible to provide data with a null provider";
1001 << "Impossible to provide data with a null provider";
1002 }
1002 }
1003
1003
1004 if (!inCacheRangeList.empty()) {
1004 if (!inCacheRangeList.empty()) {
1005 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1005 emit q->updateVarDisplaying(var, inCacheRangeList.first());
1006 }
1006 }
1007 }
1007 }
1008 else {
1008 else {
1009 acceptVariableRequest(varId,
1009 acceptVariableRequest(varId,
1010 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1010 var->dataSeries()->subDataSeries(varRequest.m_CacheRangeRequested));
1011 }
1011 }
1012 }
1012 }
@@ -1,637 +1,506
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 void validateRanges(VariableController &variableController,
40 void validateRanges(VariableController &variableController,
41 const std::map<int, SqpRange> &expectedRanges)
41 const std::map<int, SqpRange> &expectedRanges)
42 {
42 {
43 for (const auto &expectedRangeEntry : expectedRanges) {
43 for (const auto &expectedRangeEntry : expectedRanges) {
44 auto variableIndex = expectedRangeEntry.first;
44 auto variableIndex = expectedRangeEntry.first;
45 auto expectedRange = expectedRangeEntry.second;
45 auto expectedRange = expectedRangeEntry.second;
46
46
47 // Gets the variable in the controller
47 // Gets the variable in the controller
48 auto variable = variableController.variableModel()->variable(variableIndex);
48 auto variable = variableController.variableModel()->variable(variableIndex);
49
49
50 // Compares variable's range to the expected range
50 // Compares variable's range to the expected range
51 QVERIFY(variable != nullptr);
51 QVERIFY(variable != nullptr);
52 auto range = variable->range();
52 auto range = variable->range();
53 qInfo() << "range vs expected range" << range << expectedRange;
53 qInfo() << "range vs expected range" << range << expectedRange;
54 QCOMPARE(range, expectedRange);
54 QCOMPARE(range, expectedRange);
55
55
56 // Compares variable's data with values expected for its range
56 // Compares variable's data with values expected for its range
57 auto dataSeries = variable->dataSeries();
57 auto dataSeries = variable->dataSeries();
58 QVERIFY(dataSeries != nullptr);
58 QVERIFY(dataSeries != nullptr);
59
59
60 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
60 auto it = dataSeries->xAxisRange(range.m_TStart, range.m_TEnd);
61 auto expectedValues = values(range);
61 auto expectedValues = values(range);
62 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
62 qInfo() << std::distance(it.first, it.second) << expectedValues.size();
63 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
63 QVERIFY(std::equal(it.first, it.second, expectedValues.cbegin(), expectedValues.cend(),
64 [](const auto &dataSeriesIt, const auto &expectedValue) {
64 [](const auto &dataSeriesIt, const auto &expectedValue) {
65 return dataSeriesIt.value() == expectedValue;
65 return dataSeriesIt.value() == expectedValue;
66 }));
66 }));
67 }
67 }
68 }
68 }
69
69
70 /// Provider used for the tests
70 /// Provider used for the tests
71 class TestProvider : public IDataProvider {
71 class TestProvider : public IDataProvider {
72 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
72 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
73
73
74 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
74 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
75 {
75 {
76 const auto &ranges = parameters.m_Times;
76 const auto &ranges = parameters.m_Times;
77
77
78 for (const auto &range : ranges) {
78 for (const auto &range : ranges) {
79 // Generates data series
79 // Generates data series
80 auto valuesData = values(range);
80 auto valuesData = values(range);
81
81
82 std::vector<double> xAxisData{};
82 std::vector<double> xAxisData{};
83 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
83 for (auto i = range.m_TStart; i <= range.m_TEnd; ++i) {
84 xAxisData.push_back(i);
84 xAxisData.push_back(i);
85 }
85 }
86
86
87 auto dataSeries = std::make_shared<ScalarSeries>(
87 auto dataSeries = std::make_shared<ScalarSeries>(
88 std::move(xAxisData), std::move(valuesData), Unit{"t", true}, Unit{});
88 std::move(xAxisData), std::move(valuesData), Unit{"t", true}, Unit{});
89
89
90 emit dataProvided(acqIdentifier, dataSeries, range);
90 emit dataProvided(acqIdentifier, dataSeries, range);
91 }
91 }
92 }
92 }
93
93
94 void requestDataAborting(QUuid acqIdentifier) override
94 void requestDataAborting(QUuid acqIdentifier) override
95 {
95 {
96 // Does nothing
96 // Does nothing
97 }
97 }
98 };
98 };
99
99
100 /**
100 /**
101 * Interface representing an operation performed on a variable controller.
101 * Interface representing an operation performed on a variable controller.
102 * This interface is used in tests to apply a set of operations and check the status of the
102 * This interface is used in tests to apply a set of operations and check the status of the
103 * controller after each operation
103 * controller after each operation
104 */
104 */
105 struct IOperation {
105 struct IOperation {
106 virtual ~IOperation() = default;
106 virtual ~IOperation() = default;
107 /// Executes the operation on the variable controller
107 /// Executes the operation on the variable controller
108 virtual void exec(VariableController &variableController) const = 0;
108 virtual void exec(VariableController &variableController) const = 0;
109 };
109 };
110
110
111 /**
111 /**
112 *Variable creation operation in the controller
112 *Variable creation operation in the controller
113 */
113 */
114 struct Create : public IOperation {
114 struct Create : public IOperation {
115 explicit Create(int index) : m_Index{index} {}
115 explicit Create(int index) : m_Index{index} {}
116
116
117 void exec(VariableController &variableController) const override
117 void exec(VariableController &variableController) const override
118 {
118 {
119 auto variable = variableController.createVariable(QString::number(m_Index), {},
119 auto variable = variableController.createVariable(QString::number(m_Index), {},
120 std::make_unique<TestProvider>());
120 std::make_unique<TestProvider>());
121 }
121 }
122
122
123 int m_Index; ///< The index of the variable to create in the controller
123 int m_Index; ///< The index of the variable to create in the controller
124 };
124 };
125
125
126 /**
126 /**
127 * Variable move/shift operation in the controller
127 * Variable move/shift operation in the controller
128 */
128 */
129 struct Move : public IOperation {
129 struct Move : public IOperation {
130 explicit Move(int index, const SqpRange &newRange, bool shift = false, int delayMS = 10)
130 explicit Move(int index, const SqpRange &newRange, bool shift = false, int delayMS = 10)
131 : m_Index{index}, m_NewRange{newRange}, m_Shift{shift}, m_DelayMs{delayMS}
131 : m_Index{index}, m_NewRange{newRange}, m_Shift{shift}, m_DelayMs{delayMS}
132 {
132 {
133 }
133 }
134
134
135 void exec(VariableController &variableController) const override
135 void exec(VariableController &variableController) const override
136 {
136 {
137 if (auto variable = variableController.variableModel()->variable(m_Index)) {
137 if (auto variable = variableController.variableModel()->variable(m_Index)) {
138 variableController.onRequestDataLoading({variable}, m_NewRange, !m_Shift);
138 variableController.onRequestDataLoading({variable}, m_NewRange, !m_Shift);
139 QTest::qWait(m_DelayMs);
139 QTest::qWait(m_DelayMs);
140 }
140 }
141 }
141 }
142
142
143 int m_Index; ///< The index of the variable to move
143 int m_Index; ///< The index of the variable to move
144 SqpRange m_NewRange; ///< The new range of the variable
144 SqpRange m_NewRange; ///< The new range of the variable
145 bool m_Shift; ///< Performs a shift (
145 bool m_Shift; ///< Performs a shift (
146 int m_DelayMs; ///< wait the delay after running the request (
146 int m_DelayMs; ///< wait the delay after running the request (
147 };
147 };
148
148
149 /**
149 /**
150 * Variable synchronization/desynchronization operation in the controller
150 * Variable synchronization/desynchronization operation in the controller
151 */
151 */
152 struct Synchronize : public IOperation {
152 struct Synchronize : public IOperation {
153 explicit Synchronize(int index, QUuid syncId, bool synchronize = true)
153 explicit Synchronize(int index, QUuid syncId, bool synchronize = true)
154 : m_Index{index}, m_SyncId{syncId}, m_Synchronize{synchronize}
154 : m_Index{index}, m_SyncId{syncId}, m_Synchronize{synchronize}
155 {
155 {
156 }
156 }
157
157
158 void exec(VariableController &variableController) const override
158 void exec(VariableController &variableController) const override
159 {
159 {
160 if (auto variable = variableController.variableModel()->variable(m_Index)) {
160 if (auto variable = variableController.variableModel()->variable(m_Index)) {
161 if (m_Synchronize) {
161 if (m_Synchronize) {
162 variableController.onAddSynchronized(variable, m_SyncId);
162 variableController.onAddSynchronized(variable, m_SyncId);
163 }
163 }
164 else {
164 else {
165 variableController.desynchronize(variable, m_SyncId);
165 variableController.desynchronize(variable, m_SyncId);
166 }
166 }
167 }
167 }
168 }
168 }
169
169
170 int m_Index; ///< The index of the variable to sync/desync
170 int m_Index; ///< The index of the variable to sync/desync
171 QUuid m_SyncId; ///< The synchronization group of the variable
171 QUuid m_SyncId; ///< The synchronization group of the variable
172 bool m_Synchronize; ///< Performs sync or desync operation
172 bool m_Synchronize; ///< Performs sync or desync operation
173 };
173 };
174
174
175 /**
175 /**
176 * Test Iteration
176 * Test Iteration
177 *
177 *
178 * A test iteration includes an operation to be performed, and a set of expected ranges after each
178 * A test iteration includes an operation to be performed, and a set of expected ranges after each
179 * operation. Each range is tested after the operation to ensure that:
179 * operation. Each range is tested after the operation to ensure that:
180 * - the range of the variable is the expected range
180 * - the range of the variable is the expected range
181 * - the data of the variable are those generated for the expected range
181 * - the data of the variable are those generated for the expected range
182 */
182 */
183 struct Iteration {
183 struct Iteration {
184 std::shared_ptr<IOperation> m_Operation; ///< Operation to perform
184 std::shared_ptr<IOperation> m_Operation; ///< Operation to perform
185 std::map<int, SqpRange> m_ExpectedRanges; ///< Expected ranges (by variable index)
185 std::map<int, SqpRange> m_ExpectedRanges; ///< Expected ranges (by variable index)
186 };
186 };
187
187
188 using Iterations = std::vector<Iteration>;
188 using Iterations = std::vector<Iteration>;
189
189
190 } // namespace
190 } // namespace
191
191
192 Q_DECLARE_METATYPE(Iterations)
192 Q_DECLARE_METATYPE(Iterations)
193
193
194 class TestVariableSync : public QObject {
194 class TestVariableSync : public QObject {
195 Q_OBJECT
195 Q_OBJECT
196
196
197 private slots:
197 private slots:
198 /// Input data for @sa testSync()
198 /// Input data for @sa testSync()
199 void testSync_data();
199 void testSync_data();
200
200
201 /// Input data for @sa testSyncWithAborting()
202 void testSyncWithAborting_data();
203
204 /// Input data for @sa testSyncOneVar()
201 /// Input data for @sa testSyncOneVar()
205 void testSyncOneVar_data();
202 void testSyncOneVar_data();
206
203
207 /// Tests synchronization between variables through several operations with automatic aborting
208 void testSyncWithAborting();
209
210 /// Tests synchronization between variables through several operations
204 /// Tests synchronization between variables through several operations
211 void testSync();
205 void testSync();
212
206
213 /// Tests synchronization between variables through several operations
207 /// Tests synchronization between variables through several operations
214 void testSyncOneVar();
208 void testSyncOneVar();
215 };
209 };
216
210
217 namespace {
211 namespace {
218
212
219 void testSyncCase1()
213 void testSyncCase1()
220 {
214 {
221 // Id used to synchronize variables in the controller
215 // Id used to synchronize variables in the controller
222 auto syncId = QUuid::createUuid();
216 auto syncId = QUuid::createUuid();
223
217
224 /// Generates a range according to a start time and a end time (the date is the same)
218 /// Generates a range according to a start time and a end time (the date is the same)
225 auto range = [](const QTime &startTime, const QTime &endTime) {
219 auto range = [](const QTime &startTime, const QTime &endTime) {
226 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
220 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
227 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
221 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
228 };
222 };
229
223
230 auto initialRange = range({12, 0}, {13, 0});
224 auto initialRange = range({12, 0}, {13, 0});
231
225
232 Iterations iterations{};
226 Iterations iterations{};
233 // Creates variables var0, var1 and var2
227 // Creates variables var0, var1 and var2
234 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
228 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
235 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
229 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
236 iterations.push_back(
230 iterations.push_back(
237 {std::make_shared<Create>(2), {{0, initialRange}, {1, initialRange}, {2, initialRange}}});
231 {std::make_shared<Create>(2), {{0, initialRange}, {1, initialRange}, {2, initialRange}}});
238
232
239 // Adds variables into the sync group (ranges don't need to be tested here)
233 // Adds variables into the sync group (ranges don't need to be tested here)
240 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
234 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
241 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
235 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
242 iterations.push_back({std::make_shared<Synchronize>(2, syncId)});
236 iterations.push_back({std::make_shared<Synchronize>(2, syncId)});
243
237
244 // Moves var0: ranges of var0, var1 and var2 change
238 // Moves var0: ranges of var0, var1 and var2 change
245 auto newRange = range({12, 30}, {13, 30});
239 auto newRange = range({12, 30}, {13, 30});
246 iterations.push_back(
240 iterations.push_back(
247 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
241 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
248
242
249 // Moves var1: ranges of var0, var1 and var2 change
243 // Moves var1: ranges of var0, var1 and var2 change
250 newRange = range({13, 0}, {14, 0});
244 newRange = range({13, 0}, {14, 0});
251 iterations.push_back(
245 iterations.push_back(
252 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
246 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
253
247
254 // Moves var2: ranges of var0, var1 and var2 change
248 // Moves var2: ranges of var0, var1 and var2 change
255 newRange = range({13, 30}, {14, 30});
249 newRange = range({13, 30}, {14, 30});
256 iterations.push_back(
250 iterations.push_back(
257 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
251 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, newRange}}});
258
252
259 // Desyncs var2 and moves var0:
253 // Desyncs var2 and moves var0:
260 // - ranges of var0 and var1 change
254 // - ranges of var0 and var1 change
261 // - range of var2 doesn't change anymore
255 // - range of var2 doesn't change anymore
262 auto var2Range = newRange;
256 auto var2Range = newRange;
263 newRange = range({13, 45}, {14, 45});
257 newRange = range({13, 45}, {14, 45});
264 iterations.push_back({std::make_shared<Synchronize>(2, syncId, false)});
258 iterations.push_back({std::make_shared<Synchronize>(2, syncId, false)});
265 iterations.push_back(
259 iterations.push_back(
266 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, var2Range}}});
260 {std::make_shared<Move>(0, newRange), {{0, newRange}, {1, newRange}, {2, var2Range}}});
267
261
268 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
262 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
269 auto var1Range = newRange;
263 auto var1Range = newRange;
270 newRange = range({14, 45}, {15, 45});
264 newRange = range({14, 45}, {15, 45});
271 iterations.push_back({std::make_shared<Move>(0, newRange, true),
265 iterations.push_back({std::make_shared<Move>(0, newRange, true),
272 {{0, newRange}, {1, var1Range}, {2, var2Range}}});
266 {{0, newRange}, {1, var1Range}, {2, var2Range}}});
273
267
274 // Moves var0 through several operations:
268 // Moves var0 through several operations:
275 // - range of var0 changes
269 // - range of var0 changes
276 // - range or var1 changes according to the previous shift (one hour)
270 // - range or var1 changes according to the previous shift (one hour)
277 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
271 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
278 iterations.push_back(
272 iterations.push_back(
279 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
273 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
280 };
274 };
281
275
282 // Pan left
276 // Pan left
283 moveVar0(range({14, 30}, {15, 30}), range({13, 30}, {14, 30}));
277 moveVar0(range({14, 30}, {15, 30}), range({13, 30}, {14, 30}));
284 // Pan right
278 // Pan right
285 moveVar0(range({16, 0}, {17, 0}), range({15, 0}, {16, 0}));
279 moveVar0(range({16, 0}, {17, 0}), range({15, 0}, {16, 0}));
286 // Zoom in
280 // Zoom in
287 moveVar0(range({16, 30}, {16, 45}), range({15, 30}, {15, 45}));
281 moveVar0(range({16, 30}, {16, 45}), range({15, 30}, {15, 45}));
288 // Zoom out
282 // Zoom out
289 moveVar0(range({16, 15}, {17, 0}), range({15, 15}, {16, 0}));
283 moveVar0(range({16, 15}, {17, 0}), range({15, 15}, {16, 0}));
290
284
291 QTest::newRow("sync1") << syncId << initialRange << std::move(iterations) << 200;
285 QTest::newRow("sync1") << syncId << initialRange << std::move(iterations) << 200;
292 }
286 }
293
287
294 void testSyncCase1WithAborting()
295 {
296 // Id used to synchronize variables in the controller
297 auto syncId = QUuid::createUuid();
298
299 /// Generates a range according to a start time and a end time (the date is the same)
300 auto range = [](const QTime &startTime, const QTime &endTime) {
301 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
302 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
303 };
304
305 auto initialRange = range({12, 0}, {13, 0});
306
307 Iterations creations{};
308 // Creates variables var0, var1 and var2
309 creations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
310 creations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
311
312 // Adds variables into the sync group (ranges don't need to be tested here)
313 Iterations iterations{};
314 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
315 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
316
317 // Moves var0: ranges of var0, var1
318 auto currentRange = range({12, 30}, {13, 30});
319 iterations.push_back(
320 {std::make_shared<Move>(0, currentRange), {{0, currentRange}, {1, currentRange}}});
321
322 // Moves var0: ranges of var0, var1
323 auto pendingRange = range({13, 0}, {14, 0});
324 iterations.push_back(
325 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
326
327 // Moves var0: ranges of var0, var1
328 pendingRange = range({13, 30}, {14, 30});
329 iterations.push_back(
330 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
331
332 // moves var0:
333 // - ranges of var0 and var1 change
334 auto var2Range = pendingRange;
335 pendingRange = range({13, 45}, {14, 45});
336 iterations.push_back(
337 {std::make_shared<Move>(0, pendingRange), {{0, pendingRange}, {1, pendingRange}}});
338
339 // Shifts var0: although var1 is synchronized with var0, its range doesn't change
340 auto var1Range = pendingRange;
341 pendingRange = range({14, 45}, {15, 45});
342 iterations.push_back(
343 {std::make_shared<Move>(0, pendingRange, false), {{0, pendingRange}, {1, pendingRange}}});
344
345 // Moves var0 through several operations:
346 // - range of var0 changes
347 // - range or var1 changes according to the previous shift (one hour)
348 auto moveVar0 = [&iterations](const auto &var0NewRange, const auto &var1ExpectedRange) {
349 iterations.push_back(
350 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var1ExpectedRange}}});
351 };
352
353 // Pan left
354 moveVar0(range({14, 30}, {15, 30}), range({14, 30}, {15, 30}));
355 // Pan right
356 moveVar0(range({16, 0}, {17, 0}), range({16, 0}, {17, 0}));
357 // Zoom in
358 moveVar0(range({16, 30}, {16, 45}), range({16, 30}, {16, 45}));
359 // Zoom out
360 moveVar0(range({16, 15}, {17, 0}), range({16, 15}, {17, 0}));
361
362 QTest::newRow("syncWithAborting1") << syncId << currentRange << std::move(creations)
363 << std::move(iterations) << 200;
364 }
365
366 void testSyncCase2()
288 void testSyncCase2()
367 {
289 {
368 // Id used to synchronize variables in the controller
290 // Id used to synchronize variables in the controller
369 auto syncId = QUuid::createUuid();
291 auto syncId = QUuid::createUuid();
370
292
371 /// Generates a range according to a start time and a end time (the date is the same)
293 /// Generates a range according to a start time and a end time (the date is the same)
372 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
294 auto dateTime = [](int year, int month, int day, int hours, int minutes, int seconds) {
373 return DateUtils::secondsSinceEpoch(
295 return DateUtils::secondsSinceEpoch(
374 QDateTime{{year, month, day}, QTime{hours, minutes, seconds}, Qt::UTC});
296 QDateTime{{year, month, day}, QTime{hours, minutes, seconds}, Qt::UTC});
375 };
297 };
376
298
377 auto initialRange = SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)};
299 auto initialRange = SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)};
378
300
379 Iterations iterations{};
301 Iterations iterations{};
380 // Creates variables var0 and var1
302 // Creates variables var0 and var1
381 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
303 iterations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
382 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
304 iterations.push_back({std::make_shared<Create>(1), {{0, initialRange}, {1, initialRange}}});
383
305
384 // Adds variables into the sync group (ranges don't need to be tested here)
306 // Adds variables into the sync group (ranges don't need to be tested here)
385 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
307 iterations.push_back({std::make_shared<Synchronize>(0, syncId)});
386 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
308 iterations.push_back({std::make_shared<Synchronize>(1, syncId)});
387
309
388
310
389 // Moves var0 through several operations:
311 // Moves var0 through several operations:
390 // - range of var0 changes
312 // - range of var0 changes
391 // - range or var1 changes according to the previous shift (one hour)
313 // - range or var1 changes according to the previous shift (one hour)
392 auto moveVar0 = [&iterations](const auto &var0NewRange) {
314 auto moveVar0 = [&iterations](const auto &var0NewRange) {
393 iterations.push_back(
315 iterations.push_back(
394 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var0NewRange}}});
316 {std::make_shared<Move>(0, var0NewRange), {{0, var0NewRange}, {1, var0NewRange}}});
395 };
317 };
396 moveVar0(SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)});
318 moveVar0(SqpRange{dateTime(2017, 1, 1, 12, 0, 0), dateTime(2017, 1, 1, 13, 0, 0)});
397 moveVar0(SqpRange{dateTime(2017, 1, 1, 14, 0, 0), dateTime(2017, 1, 1, 15, 0, 0)});
319 moveVar0(SqpRange{dateTime(2017, 1, 1, 14, 0, 0), dateTime(2017, 1, 1, 15, 0, 0)});
398 moveVar0(SqpRange{dateTime(2017, 1, 1, 8, 0, 0), dateTime(2017, 1, 1, 9, 0, 0)});
320 moveVar0(SqpRange{dateTime(2017, 1, 1, 8, 0, 0), dateTime(2017, 1, 1, 9, 0, 0)});
399 // moveVar0(SqpRange{dateTime(2017, 1, 1, 7, 30, 0), dateTime(2017, 1, 1, 9, 30, 0)});
321 // moveVar0(SqpRange{dateTime(2017, 1, 1, 7, 30, 0), dateTime(2017, 1, 1, 9, 30, 0)});
400 moveVar0(SqpRange{dateTime(2017, 1, 1, 2, 0, 0), dateTime(2017, 1, 1, 4, 0, 0)});
322 moveVar0(SqpRange{dateTime(2017, 1, 1, 2, 0, 0), dateTime(2017, 1, 1, 4, 0, 0)});
401 moveVar0(SqpRange{dateTime(2017, 1, 1, 6, 0, 0), dateTime(2017, 1, 1, 8, 0, 0)});
323 moveVar0(SqpRange{dateTime(2017, 1, 1, 6, 0, 0), dateTime(2017, 1, 1, 8, 0, 0)});
402
324
403 moveVar0(SqpRange{dateTime(2017, 1, 10, 6, 0, 0), dateTime(2017, 1, 15, 8, 0, 0)});
325 moveVar0(SqpRange{dateTime(2017, 1, 10, 6, 0, 0), dateTime(2017, 1, 15, 8, 0, 0)});
404 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 1, 25, 8, 0, 0)});
326 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 1, 25, 8, 0, 0)});
405 moveVar0(SqpRange{dateTime(2017, 1, 2, 6, 0, 0), dateTime(2017, 1, 8, 8, 0, 0)});
327 moveVar0(SqpRange{dateTime(2017, 1, 2, 6, 0, 0), dateTime(2017, 1, 8, 8, 0, 0)});
406
328
407 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
329 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
408 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
330 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
409 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
331 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
410 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
332 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
411 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
333 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
412 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
334 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
413 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
335 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
414 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
336 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
415 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
337 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
416 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
338 moveVar0(SqpRange{dateTime(2017, 4, 10, 6, 0, 0), dateTime(2017, 6, 15, 8, 0, 0)});
417 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
339 moveVar0(SqpRange{dateTime(2017, 1, 17, 6, 0, 0), dateTime(2017, 2, 25, 8, 0, 0)});
418 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
340 moveVar0(SqpRange{dateTime(2017, 7, 2, 6, 0, 0), dateTime(2017, 10, 8, 8, 0, 0)});
419
341
420
342
421 QTest::newRow("sync2") << syncId << initialRange << iterations << 4000;
343 QTest::newRow("sync2") << syncId << initialRange << iterations << 4000;
422 // QTest::newRow("sync3") << syncId << initialRange << iterations << 5000;
344 // QTest::newRow("sync3") << syncId << initialRange << iterations << 5000;
423 }
345 }
424
346
425 void testSyncOnVarCase1()
347 void testSyncOnVarCase1()
426 {
348 {
427 // Id used to synchronize variables in the controller
349 // Id used to synchronize variables in the controller
428 auto syncId = QUuid::createUuid();
350 auto syncId = QUuid::createUuid();
429
351
430 /// Generates a range according to a start time and a end time (the date is the same)
352 /// Generates a range according to a start time and a end time (the date is the same)
431 auto range = [](const QTime &startTime, const QTime &endTime) {
353 auto range = [](const QTime &startTime, const QTime &endTime) {
432 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
354 return SqpRange{DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, startTime, Qt::UTC}),
433 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
355 DateUtils::secondsSinceEpoch(QDateTime{{2017, 1, 1}, endTime, Qt::UTC})};
434 };
356 };
435
357
436 auto initialRange = range({12, 0}, {13, 0});
358 auto initialRange = range({12, 0}, {13, 0});
437
359
438 Iterations creations{};
360 Iterations creations{};
439 // Creates variables var0, var1 and var2
361 // Creates variables var0, var1 and var2
440 creations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
362 creations.push_back({std::make_shared<Create>(0), {{0, initialRange}}});
441
363
442 Iterations synchronization{};
364 Iterations synchronization{};
443 // Adds variables into the sync group (ranges don't need to be tested here)
365 // Adds variables into the sync group (ranges don't need to be tested here)
444 synchronization.push_back({std::make_shared<Synchronize>(0, syncId)});
366 synchronization.push_back({std::make_shared<Synchronize>(0, syncId)});
445
367
446 Iterations iterations{};
368 Iterations iterations{};
447
369
448 // Moves var0 through several operations
370 // Moves var0 through several operations
449 auto moveOp = [&iterations](const auto &requestedRange, const auto &expectedRange, auto delay) {
371 auto moveOp = [&iterations](const auto &requestedRange, const auto &expectedRange, auto delay) {
450 iterations.push_back(
372 iterations.push_back(
451 {std::make_shared<Move>(0, requestedRange, true, delay), {{0, expectedRange}}});
373 {std::make_shared<Move>(0, requestedRange, true, delay), {{0, expectedRange}}});
452 };
374 };
453
375
454 // we assume here 300 ms is enough to finsh a operation
376 // we assume here 300 ms is enough to finsh a operation
455 int delayToFinish = 300;
377 int delayToFinish = 300;
456 // jump to right, let's the operation time to finish
378 // jump to right, let's the operation time to finish
457 moveOp(range({14, 30}, {15, 30}), range({14, 30}, {15, 30}), delayToFinish);
379 moveOp(range({14, 30}, {15, 30}), range({14, 30}, {15, 30}), delayToFinish);
458 // pan to right, let's the operation time to finish
380 // pan to right, let's the operation time to finish
459 moveOp(range({14, 45}, {15, 45}), range({14, 45}, {15, 45}), delayToFinish);
381 moveOp(range({14, 45}, {15, 45}), range({14, 45}, {15, 45}), delayToFinish);
460 // jump to left, let's the operation time to finish
382 // jump to left, let's the operation time to finish
461 moveOp(range({03, 30}, {04, 30}), range({03, 30}, {04, 30}), delayToFinish);
383 moveOp(range({03, 30}, {04, 30}), range({03, 30}, {04, 30}), delayToFinish);
462 // Pan to left, let's the operation time to finish
384 // Pan to left, let's the operation time to finish
463 moveOp(range({03, 10}, {04, 10}), range({03, 10}, {04, 10}), delayToFinish);
385 moveOp(range({03, 10}, {04, 10}), range({03, 10}, {04, 10}), delayToFinish);
464 // Zoom in, let's the operation time to finish
386 // Zoom in, let's the operation time to finish
465 moveOp(range({03, 30}, {04, 00}), range({03, 30}, {04, 00}), delayToFinish);
387 moveOp(range({03, 30}, {04, 00}), range({03, 30}, {04, 00}), delayToFinish);
466 // Zoom out left, let's the operation time to finish
388 // Zoom out left, let's the operation time to finish
467 moveOp(range({01, 10}, {18, 10}), range({01, 10}, {18, 10}), delayToFinish);
389 moveOp(range({01, 10}, {18, 10}), range({01, 10}, {18, 10}), delayToFinish);
468 // Go back to initial range
390 // Go back to initial range
469 moveOp(initialRange, initialRange, delayToFinish);
391 moveOp(initialRange, initialRange, delayToFinish);
470
392
471
393
472 // jump to right, let's the operation time to finish
394 // jump to right, let's the operation time to finish
473 // moveOp(range({14, 30}, {15, 30}), initialRange, delayToFinish);
395 // moveOp(range({14, 30}, {15, 30}), initialRange, delayToFinish);
474 // Zoom out left, let's the operation time to finish
396 // Zoom out left, let's the operation time to finish
475 moveOp(range({01, 10}, {18, 10}), initialRange, delayToFinish);
397 moveOp(range({01, 10}, {18, 10}), initialRange, delayToFinish);
476 // Go back to initial range
398 // Go back to initial range
477 moveOp(initialRange, initialRange, 300);
399 moveOp(initialRange, initialRange, 300);
478
400
479 QTest::newRow("syncOnVarCase1") << syncId << initialRange << std::move(creations)
401 QTest::newRow("syncOnVarCase1") << syncId << initialRange << std::move(creations)
480 << std::move(iterations);
402 << std::move(iterations);
481 }
403 }
482 }
404 }
483
405
484 void TestVariableSync::testSync_data()
406 void TestVariableSync::testSync_data()
485 {
407 {
486 // ////////////// //
408 // ////////////// //
487 // Test structure //
409 // Test structure //
488 // ////////////// //
410 // ////////////// //
489
411
490 QTest::addColumn<QUuid>("syncId");
412 QTest::addColumn<QUuid>("syncId");
491 QTest::addColumn<SqpRange>("initialRange");
413 QTest::addColumn<SqpRange>("initialRange");
492 QTest::addColumn<Iterations>("iterations");
414 QTest::addColumn<Iterations>("iterations");
493 QTest::addColumn<int>("operationDelay");
415 QTest::addColumn<int>("operationDelay");
494
416
495 // ////////// //
417 // ////////// //
496 // Test cases //
418 // Test cases //
497 // ////////// //
419 // ////////// //
498
420
499 testSyncCase1();
421 testSyncCase1();
500 testSyncCase2();
422 testSyncCase2();
501 }
423 }
502
424
503 void TestVariableSync::testSyncWithAborting_data()
504 {
505 // ////////////// //
506 // Test structure //
507 // ////////////// //
508
509 QTest::addColumn<QUuid>("syncId");
510 QTest::addColumn<SqpRange>("initialRange");
511 QTest::addColumn<Iterations>("creations");
512 QTest::addColumn<Iterations>("iterations");
513 QTest::addColumn<int>("operationDelay");
514
515 // ////////// //
516 // Test cases //
517 // ////////// //
518
519 testSyncCase1WithAborting();
520 }
521
522 void TestVariableSync::testSyncOneVar_data()
425 void TestVariableSync::testSyncOneVar_data()
523 {
426 {
524 // ////////////// //
427 // ////////////// //
525 // Test structure //
428 // Test structure //
526 // ////////////// //
429 // ////////////// //
527
430
528 QTest::addColumn<QUuid>("syncId");
431 QTest::addColumn<QUuid>("syncId");
529 QTest::addColumn<SqpRange>("initialRange");
432 QTest::addColumn<SqpRange>("initialRange");
530 QTest::addColumn<Iterations>("creations");
433 QTest::addColumn<Iterations>("creations");
531 QTest::addColumn<Iterations>("iterations");
434 QTest::addColumn<Iterations>("iterations");
532
435
533 // ////////// //
436 // ////////// //
534 // Test cases //
437 // Test cases //
535 // ////////// //
438 // ////////// //
536
439
537 testSyncOnVarCase1();
440 testSyncOnVarCase1();
538 }
441 }
539
442
540 void TestVariableSync::testSync()
443 void TestVariableSync::testSync()
541 {
444 {
542 // Inits controllers
445 // Inits controllers
543 TimeController timeController{};
446 TimeController timeController{};
544 VariableController variableController{};
447 VariableController variableController{};
545 variableController.setTimeController(&timeController);
448 variableController.setTimeController(&timeController);
546
449
547 QFETCH(QUuid, syncId);
450 QFETCH(QUuid, syncId);
548 QFETCH(SqpRange, initialRange);
451 QFETCH(SqpRange, initialRange);
549 timeController.onTimeToUpdate(initialRange);
452 timeController.onTimeToUpdate(initialRange);
550
453
551 // Synchronization group used
454 // Synchronization group used
552 variableController.onAddSynchronizationGroupId(syncId);
455 variableController.onAddSynchronizationGroupId(syncId);
553
456
554 // For each iteration:
457 // For each iteration:
555 // - execute operation
458 // - execute operation
556 // - compare the variables' state to the expected states
459 // - compare the variables' state to the expected states
557 QFETCH(Iterations, iterations);
460 QFETCH(Iterations, iterations);
558 QFETCH(int, operationDelay);
461 QFETCH(int, operationDelay);
559 for (const auto &iteration : iterations) {
462 for (const auto &iteration : iterations) {
560 iteration.m_Operation->exec(variableController);
463 iteration.m_Operation->exec(variableController);
561 QTest::qWait(operationDelay);
464 QTest::qWait(operationDelay);
562
465
563 validateRanges(variableController, iteration.m_ExpectedRanges);
466 validateRanges(variableController, iteration.m_ExpectedRanges);
564 }
467 }
565 }
468 }
566
469
567 void TestVariableSync::testSyncWithAborting()
568 {
569 // Inits controllers
570 TimeController timeController{};
571 VariableController variableController{};
572 variableController.setTimeController(&timeController);
573
574 QFETCH(QUuid, syncId);
575 QFETCH(SqpRange, initialRange);
576 timeController.onTimeToUpdate(initialRange);
577
578 // Synchronization group used
579 variableController.onAddSynchronizationGroupId(syncId);
580
581 // For each iteration:
582 // - execute operation
583 // - compare the variables' state to the expected states
584 QFETCH(Iterations, iterations);
585 QFETCH(Iterations, creations);
586 QFETCH(int, operationDelay);
587
588 for (const auto &creation : creations) {
589 creation.m_Operation->exec(variableController);
590 QTest::qWait(operationDelay);
591 }
592
593 for (const auto &iteration : iterations) {
594 iteration.m_Operation->exec(variableController);
595 }
596
597 QTest::qWait(operationDelay);
598 validateRanges(variableController, iterations.back().m_ExpectedRanges);
599 }
600
601 void TestVariableSync::testSyncOneVar()
470 void TestVariableSync::testSyncOneVar()
602 {
471 {
603 // Inits controllers
472 // Inits controllers
604 TimeController timeController{};
473 TimeController timeController{};
605 VariableController variableController{};
474 VariableController variableController{};
606 variableController.setTimeController(&timeController);
475 variableController.setTimeController(&timeController);
607
476
608 QFETCH(QUuid, syncId);
477 QFETCH(QUuid, syncId);
609 QFETCH(SqpRange, initialRange);
478 QFETCH(SqpRange, initialRange);
610 timeController.onTimeToUpdate(initialRange);
479 timeController.onTimeToUpdate(initialRange);
611
480
612 // Synchronization group used
481 // Synchronization group used
613 variableController.onAddSynchronizationGroupId(syncId);
482 variableController.onAddSynchronizationGroupId(syncId);
614
483
615 // For each iteration:
484 // For each iteration:
616 // - execute operation
485 // - execute operation
617 // - compare the variables' state to the expected states
486 // - compare the variables' state to the expected states
618 QFETCH(Iterations, iterations);
487 QFETCH(Iterations, iterations);
619 QFETCH(Iterations, creations);
488 QFETCH(Iterations, creations);
620
489
621 for (const auto &creation : creations) {
490 for (const auto &creation : creations) {
622 creation.m_Operation->exec(variableController);
491 creation.m_Operation->exec(variableController);
623 QTest::qWait(300);
492 QTest::qWait(300);
624 }
493 }
625
494
626 for (const auto &iteration : iterations) {
495 for (const auto &iteration : iterations) {
627 iteration.m_Operation->exec(variableController);
496 iteration.m_Operation->exec(variableController);
628 }
497 }
629
498
630 if (!iterations.empty()) {
499 if (!iterations.empty()) {
631 validateRanges(variableController, iterations.back().m_ExpectedRanges);
500 validateRanges(variableController, iterations.back().m_ExpectedRanges);
632 }
501 }
633 }
502 }
634
503
635 QTEST_MAIN(TestVariableSync)
504 QTEST_MAIN(TestVariableSync)
636
505
637 #include "TestVariableSync.moc"
506 #include "TestVariableSync.moc"
@@ -1,281 +1,286
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Data/ScalarSeries.h>
3 #include <Data/ScalarSeries.h>
4 #include <Data/VectorSeries.h>
4 #include <Data/VectorSeries.h>
5
5
6 #include <QObject>
6 #include <QObject>
7 #include <QtTest>
7 #include <QtTest>
8
8
9 namespace {
9 namespace {
10
10
11 /// Path for the tests
11 /// Path for the tests
12 const auto TESTS_RESOURCES_PATH
12 const auto TESTS_RESOURCES_PATH
13 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
13 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaResultParser"}.absoluteFilePath();
14
14
15 QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds)
15 QDateTime dateTime(int year, int month, int day, int hours, int minutes, int seconds)
16 {
16 {
17 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
17 return QDateTime{{year, month, day}, {hours, minutes, seconds}, Qt::UTC};
18 }
18 }
19
19
20 QString inputFilePath(const QString &inputFileName)
20 QString inputFilePath(const QString &inputFileName)
21 {
21 {
22 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
22 return QFileInfo{TESTS_RESOURCES_PATH, inputFileName}.absoluteFilePath();
23 }
23 }
24
24
25 template <typename T>
25 template <typename T>
26 struct ExpectedResults {
26 struct ExpectedResults {
27 explicit ExpectedResults() = default;
27 explicit ExpectedResults() = default;
28
28
29 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
29 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
30 QVector<double> valuesData)
30 QVector<double> valuesData)
31 : ExpectedResults(xAxisUnit, valuesUnit, xAxisData,
31 : ExpectedResults(xAxisUnit, valuesUnit, xAxisData,
32 QVector<QVector<double> >{std::move(valuesData)})
32 QVector<QVector<double> >{std::move(valuesData)})
33 {
33 {
34 }
34 }
35
35
36 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
36 /// Ctor with QVector<QDateTime> as x-axis data. Datetimes are converted to doubles
37 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
37 explicit ExpectedResults(Unit xAxisUnit, Unit valuesUnit, const QVector<QDateTime> &xAxisData,
38 QVector<QVector<double> > valuesData)
38 QVector<QVector<double> > valuesData)
39 : m_ParsingOK{true},
39 : m_ParsingOK{true},
40 m_XAxisUnit{xAxisUnit},
40 m_XAxisUnit{xAxisUnit},
41 m_ValuesUnit{valuesUnit},
41 m_ValuesUnit{valuesUnit},
42 m_XAxisData{},
42 m_XAxisData{},
43 m_ValuesData{std::move(valuesData)}
43 m_ValuesData{std::move(valuesData)}
44 {
44 {
45 // Converts QVector<QDateTime> to QVector<double>
45 // Converts QVector<QDateTime> to QVector<double>
46 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
46 std::transform(xAxisData.cbegin(), xAxisData.cend(), std::back_inserter(m_XAxisData),
47 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
47 [](const auto &dateTime) { return dateTime.toMSecsSinceEpoch() / 1000.; });
48 }
48 }
49
49
50 /**
50 /**
51 * Validates a DataSeries compared to the expected results
51 * Validates a DataSeries compared to the expected results
52 * @param results the DataSeries to validate
52 * @param results the DataSeries to validate
53 */
53 */
54 void validate(std::shared_ptr<IDataSeries> results)
54 void validate(std::shared_ptr<IDataSeries> results)
55 {
55 {
56 if (m_ParsingOK) {
56 if (m_ParsingOK) {
57 auto dataSeries = dynamic_cast<T *>(results.get());
57 auto dataSeries = dynamic_cast<T *>(results.get());
58 QVERIFY(dataSeries != nullptr);
58 if (dataSeries == nullptr) {
59
60 // No unit detected, parsink ok but data is nullptr
61 // TODO, improve the test to verify that the data is null
62 return;
63 }
59
64
60 // Checks units
65 // Checks units
61 QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit);
66 QVERIFY(dataSeries->xAxisUnit() == m_XAxisUnit);
62 QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit);
67 QVERIFY(dataSeries->valuesUnit() == m_ValuesUnit);
63
68
64 auto verifyRange = [dataSeries](const auto &expectedData, const auto &equalFun) {
69 auto verifyRange = [dataSeries](const auto &expectedData, const auto &equalFun) {
65 QVERIFY(std::equal(dataSeries->cbegin(), dataSeries->cend(), expectedData.cbegin(),
70 QVERIFY(std::equal(dataSeries->cbegin(), dataSeries->cend(), expectedData.cbegin(),
66 expectedData.cend(),
71 expectedData.cend(),
67 [&equalFun](const auto &dataSeriesIt, const auto &expectedX) {
72 [&equalFun](const auto &dataSeriesIt, const auto &expectedX) {
68 return equalFun(dataSeriesIt, expectedX);
73 return equalFun(dataSeriesIt, expectedX);
69 }));
74 }));
70 };
75 };
71
76
72 // Checks x-axis data
77 // Checks x-axis data
73 verifyRange(m_XAxisData, [](const auto &seriesIt, const auto &value) {
78 verifyRange(m_XAxisData, [](const auto &seriesIt, const auto &value) {
74 return seriesIt.x() == value;
79 return seriesIt.x() == value;
75 });
80 });
76
81
77 // Checks values data of each component
82 // Checks values data of each component
78 for (auto i = 0; i < m_ValuesData.size(); ++i) {
83 for (auto i = 0; i < m_ValuesData.size(); ++i) {
79 verifyRange(m_ValuesData.at(i), [i](const auto &seriesIt, const auto &value) {
84 verifyRange(m_ValuesData.at(i), [i](const auto &seriesIt, const auto &value) {
80 auto itValue = seriesIt.value(i);
85 auto itValue = seriesIt.value(i);
81 return (std::isnan(itValue) && std::isnan(value)) || seriesIt.value(i) == value;
86 return (std::isnan(itValue) && std::isnan(value)) || seriesIt.value(i) == value;
82 });
87 });
83 }
88 }
84 }
89 }
85 else {
90 else {
86 QVERIFY(results == nullptr);
91 QVERIFY(results == nullptr);
87 }
92 }
88 }
93 }
89
94
90 // Parsing was successfully completed
95 // Parsing was successfully completed
91 bool m_ParsingOK{false};
96 bool m_ParsingOK{false};
92 // Expected x-axis unit
97 // Expected x-axis unit
93 Unit m_XAxisUnit{};
98 Unit m_XAxisUnit{};
94 // Expected values unit
99 // Expected values unit
95 Unit m_ValuesUnit{};
100 Unit m_ValuesUnit{};
96 // Expected x-axis data
101 // Expected x-axis data
97 QVector<double> m_XAxisData{};
102 QVector<double> m_XAxisData{};
98 // Expected values data
103 // Expected values data
99 QVector<QVector<double> > m_ValuesData{};
104 QVector<QVector<double> > m_ValuesData{};
100 };
105 };
101
106
102 } // namespace
107 } // namespace
103
108
104 Q_DECLARE_METATYPE(ExpectedResults<ScalarSeries>)
109 Q_DECLARE_METATYPE(ExpectedResults<ScalarSeries>)
105 Q_DECLARE_METATYPE(ExpectedResults<VectorSeries>)
110 Q_DECLARE_METATYPE(ExpectedResults<VectorSeries>)
106
111
107 class TestAmdaResultParser : public QObject {
112 class TestAmdaResultParser : public QObject {
108 Q_OBJECT
113 Q_OBJECT
109 private:
114 private:
110 template <typename T>
115 template <typename T>
111 void testReadDataStructure()
116 void testReadDataStructure()
112 {
117 {
113 // ////////////// //
118 // ////////////// //
114 // Test structure //
119 // Test structure //
115 // ////////////// //
120 // ////////////// //
116
121
117 // Name of TXT file to read
122 // Name of TXT file to read
118 QTest::addColumn<QString>("inputFileName");
123 QTest::addColumn<QString>("inputFileName");
119 // Expected results
124 // Expected results
120 QTest::addColumn<ExpectedResults<T> >("expectedResults");
125 QTest::addColumn<ExpectedResults<T> >("expectedResults");
121 }
126 }
122
127
123 template <typename T>
128 template <typename T>
124 void testRead(AmdaResultParser::ValueType valueType)
129 void testRead(AmdaResultParser::ValueType valueType)
125 {
130 {
126 QFETCH(QString, inputFileName);
131 QFETCH(QString, inputFileName);
127 QFETCH(ExpectedResults<T>, expectedResults);
132 QFETCH(ExpectedResults<T>, expectedResults);
128
133
129 // Parses file
134 // Parses file
130 auto filePath = inputFilePath(inputFileName);
135 auto filePath = inputFilePath(inputFileName);
131 auto results = AmdaResultParser::readTxt(filePath, valueType);
136 auto results = AmdaResultParser::readTxt(filePath, valueType);
132
137
133 // ///////////////// //
138 // ///////////////// //
134 // Validates results //
139 // Validates results //
135 // ///////////////// //
140 // ///////////////// //
136 expectedResults.validate(results);
141 expectedResults.validate(results);
137 }
142 }
138
143
139 private slots:
144 private slots:
140 /// Input test data
145 /// Input test data
141 /// @sa testReadScalarTxt()
146 /// @sa testReadScalarTxt()
142 void testReadScalarTxt_data();
147 void testReadScalarTxt_data();
143
148
144 /// Tests parsing scalar series of a TXT file
149 /// Tests parsing scalar series of a TXT file
145 void testReadScalarTxt();
150 void testReadScalarTxt();
146
151
147 /// Input test data
152 /// Input test data
148 /// @sa testReadVectorTxt()
153 /// @sa testReadVectorTxt()
149 void testReadVectorTxt_data();
154 void testReadVectorTxt_data();
150
155
151 /// Tests parsing vector series of a TXT file
156 /// Tests parsing vector series of a TXT file
152 void testReadVectorTxt();
157 void testReadVectorTxt();
153 };
158 };
154
159
155 void TestAmdaResultParser::testReadScalarTxt_data()
160 void TestAmdaResultParser::testReadScalarTxt_data()
156 {
161 {
157 testReadDataStructure<ScalarSeries>();
162 testReadDataStructure<ScalarSeries>();
158
163
159 // ////////// //
164 // ////////// //
160 // Test cases //
165 // Test cases //
161 // ////////// //
166 // ////////// //
162
167
163 // Valid files
168 // Valid files
164 QTest::newRow("Valid file")
169 QTest::newRow("Valid file")
165 << QStringLiteral("ValidScalar1.txt")
170 << QStringLiteral("ValidScalar1.txt")
166 << ExpectedResults<ScalarSeries>{
171 << ExpectedResults<ScalarSeries>{
167 Unit{QStringLiteral("nT"), true}, Unit{},
172 Unit{QStringLiteral("nT"), true}, Unit{},
168 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
173 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
169 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
174 dateTime(2013, 9, 23, 9, 2, 30), dateTime(2013, 9, 23, 9, 3, 30),
170 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
175 dateTime(2013, 9, 23, 9, 4, 30), dateTime(2013, 9, 23, 9, 5, 30),
171 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
176 dateTime(2013, 9, 23, 9, 6, 30), dateTime(2013, 9, 23, 9, 7, 30),
172 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
177 dateTime(2013, 9, 23, 9, 8, 30), dateTime(2013, 9, 23, 9, 9, 30)},
173 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
178 QVector<double>{-2.83950, -2.71850, -2.52150, -2.57633, -2.58050, -2.48325, -2.63025,
174 -2.55800, -2.43250, -2.42200}};
179 -2.55800, -2.43250, -2.42200}};
175
180
176 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
181 QTest::newRow("Valid file (value of first line is invalid but it is converted to NaN")
177 << QStringLiteral("WrongValue.txt")
182 << QStringLiteral("WrongValue.txt")
178 << ExpectedResults<ScalarSeries>{
183 << ExpectedResults<ScalarSeries>{
179 Unit{QStringLiteral("nT"), true}, Unit{},
184 Unit{QStringLiteral("nT"), true}, Unit{},
180 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
185 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
181 dateTime(2013, 9, 23, 9, 2, 30)},
186 dateTime(2013, 9, 23, 9, 2, 30)},
182 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
187 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
183
188
184 QTest::newRow("Valid file that contains NaN values")
189 QTest::newRow("Valid file that contains NaN values")
185 << QStringLiteral("NaNValue.txt")
190 << QStringLiteral("NaNValue.txt")
186 << ExpectedResults<ScalarSeries>{
191 << ExpectedResults<ScalarSeries>{
187 Unit{QStringLiteral("nT"), true}, Unit{},
192 Unit{QStringLiteral("nT"), true}, Unit{},
188 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
193 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30), dateTime(2013, 9, 23, 9, 1, 30),
189 dateTime(2013, 9, 23, 9, 2, 30)},
194 dateTime(2013, 9, 23, 9, 2, 30)},
190 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
195 QVector<double>{std::numeric_limits<double>::quiet_NaN(), -2.71850, -2.52150}};
191
196
192 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
197 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
193 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
198 QTest::newRow("No unit file") << QStringLiteral("NoUnit.txt")
194 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true},
199 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true},
195 Unit{}, QVector<QDateTime>{},
200 Unit{}, QVector<QDateTime>{},
196 QVector<double>{}};
201 QVector<double>{}};
197 QTest::newRow("Wrong unit file")
202 QTest::newRow("Wrong unit file")
198 << QStringLiteral("WrongUnit.txt")
203 << QStringLiteral("WrongUnit.txt")
199 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true}, Unit{},
204 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral(""), true}, Unit{},
200 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
205 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 0, 30),
201 dateTime(2013, 9, 23, 9, 1, 30),
206 dateTime(2013, 9, 23, 9, 1, 30),
202 dateTime(2013, 9, 23, 9, 2, 30)},
207 dateTime(2013, 9, 23, 9, 2, 30)},
203 QVector<double>{-2.83950, -2.71850, -2.52150}};
208 QVector<double>{-2.83950, -2.71850, -2.52150}};
204
209
205 QTest::newRow("Wrong results file (date of first line is invalid")
210 QTest::newRow("Wrong results file (date of first line is invalid")
206 << QStringLiteral("WrongDate.txt")
211 << QStringLiteral("WrongDate.txt")
207 << ExpectedResults<ScalarSeries>{
212 << ExpectedResults<ScalarSeries>{
208 Unit{QStringLiteral("nT"), true}, Unit{},
213 Unit{QStringLiteral("nT"), true}, Unit{},
209 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
214 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
210 QVector<double>{-2.71850, -2.52150}};
215 QVector<double>{-2.71850, -2.52150}};
211
216
212 QTest::newRow("Wrong results file (too many values for first line")
217 QTest::newRow("Wrong results file (too many values for first line")
213 << QStringLiteral("TooManyValues.txt")
218 << QStringLiteral("TooManyValues.txt")
214 << ExpectedResults<ScalarSeries>{
219 << ExpectedResults<ScalarSeries>{
215 Unit{QStringLiteral("nT"), true}, Unit{},
220 Unit{QStringLiteral("nT"), true}, Unit{},
216 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
221 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
217 QVector<double>{-2.71850, -2.52150}};
222 QVector<double>{-2.71850, -2.52150}};
218
223
219 QTest::newRow("Wrong results file (x of first line is NaN")
224 QTest::newRow("Wrong results file (x of first line is NaN")
220 << QStringLiteral("NaNX.txt")
225 << QStringLiteral("NaNX.txt")
221 << ExpectedResults<ScalarSeries>{
226 << ExpectedResults<ScalarSeries>{
222 Unit{QStringLiteral("nT"), true}, Unit{},
227 Unit{QStringLiteral("nT"), true}, Unit{},
223 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
228 QVector<QDateTime>{dateTime(2013, 9, 23, 9, 1, 30), dateTime(2013, 9, 23, 9, 2, 30)},
224 QVector<double>{-2.71850, -2.52150}};
229 QVector<double>{-2.71850, -2.52150}};
225
230
226 QTest::newRow("Invalid file type (vector)")
231 QTest::newRow("Invalid file type (vector)")
227 << QStringLiteral("ValidVector1.txt")
232 << QStringLiteral("ValidVector1.txt")
228 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
233 << ExpectedResults<ScalarSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
229 QVector<QDateTime>{}, QVector<double>{}};
234 QVector<QDateTime>{}, QVector<double>{}};
230
235
231 // Invalid files
236 // Invalid files
232 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
237 QTest::newRow("Invalid file (unexisting file)") << QStringLiteral("UnexistingFile.txt")
233 << ExpectedResults<ScalarSeries>{};
238 << ExpectedResults<ScalarSeries>{};
234
239
235 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
240 QTest::newRow("Invalid file (file not found on server)") << QStringLiteral("FileNotFound.txt")
236 << ExpectedResults<ScalarSeries>{};
241 << ExpectedResults<ScalarSeries>{};
237 }
242 }
238
243
239 void TestAmdaResultParser::testReadScalarTxt()
244 void TestAmdaResultParser::testReadScalarTxt()
240 {
245 {
241 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
246 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
242 }
247 }
243
248
244 void TestAmdaResultParser::testReadVectorTxt_data()
249 void TestAmdaResultParser::testReadVectorTxt_data()
245 {
250 {
246 testReadDataStructure<VectorSeries>();
251 testReadDataStructure<VectorSeries>();
247
252
248 // ////////// //
253 // ////////// //
249 // Test cases //
254 // Test cases //
250 // ////////// //
255 // ////////// //
251
256
252 // Valid files
257 // Valid files
253 QTest::newRow("Valid file")
258 QTest::newRow("Valid file")
254 << QStringLiteral("ValidVector1.txt")
259 << QStringLiteral("ValidVector1.txt")
255 << ExpectedResults<VectorSeries>{
260 << ExpectedResults<VectorSeries>{
256 Unit{QStringLiteral("nT"), true}, Unit{},
261 Unit{QStringLiteral("nT"), true}, Unit{},
257 QVector<QDateTime>{dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6),
262 QVector<QDateTime>{dateTime(2013, 7, 2, 9, 13, 50), dateTime(2013, 7, 2, 9, 14, 6),
258 dateTime(2013, 7, 2, 9, 14, 22), dateTime(2013, 7, 2, 9, 14, 38),
263 dateTime(2013, 7, 2, 9, 14, 22), dateTime(2013, 7, 2, 9, 14, 38),
259 dateTime(2013, 7, 2, 9, 14, 54), dateTime(2013, 7, 2, 9, 15, 10),
264 dateTime(2013, 7, 2, 9, 14, 54), dateTime(2013, 7, 2, 9, 15, 10),
260 dateTime(2013, 7, 2, 9, 15, 26), dateTime(2013, 7, 2, 9, 15, 42),
265 dateTime(2013, 7, 2, 9, 15, 26), dateTime(2013, 7, 2, 9, 15, 42),
261 dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)},
266 dateTime(2013, 7, 2, 9, 15, 58), dateTime(2013, 7, 2, 9, 16, 14)},
262 QVector<QVector<double> >{
267 QVector<QVector<double> >{
263 {-0.332, -1.011, -1.457, -1.293, -1.217, -1.443, -1.278, -1.202, -1.22, -1.259},
268 {-0.332, -1.011, -1.457, -1.293, -1.217, -1.443, -1.278, -1.202, -1.22, -1.259},
264 {3.206, 2.999, 2.785, 2.736, 2.612, 2.564, 2.892, 2.862, 2.859, 2.764},
269 {3.206, 2.999, 2.785, 2.736, 2.612, 2.564, 2.892, 2.862, 2.859, 2.764},
265 {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}}};
270 {0.058, 0.496, 1.018, 1.485, 1.662, 1.505, 1.168, 1.244, 1.15, 1.358}}};
266
271
267 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
272 // Valid files but with some invalid lines (wrong unit, wrong values, etc.)
268 QTest::newRow("Invalid file type (scalar)")
273 QTest::newRow("Invalid file type (scalar)")
269 << QStringLiteral("ValidScalar1.txt")
274 << QStringLiteral("ValidScalar1.txt")
270 << ExpectedResults<VectorSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
275 << ExpectedResults<VectorSeries>{Unit{QStringLiteral("nT"), true}, Unit{},
271 QVector<QDateTime>{},
276 QVector<QDateTime>{},
272 QVector<QVector<double> >{{}, {}, {}}};
277 QVector<QVector<double> >{{}, {}, {}}};
273 }
278 }
274
279
275 void TestAmdaResultParser::testReadVectorTxt()
280 void TestAmdaResultParser::testReadVectorTxt()
276 {
281 {
277 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
282 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
278 }
283 }
279
284
280 QTEST_MAIN(TestAmdaResultParser)
285 QTEST_MAIN(TestAmdaResultParser)
281 #include "TestAmdaResultParser.moc"
286 #include "TestAmdaResultParser.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