| THM1176InstrumentManager 1.2 Qt Object abstraction for Metrolab THM1176

Loading...
Searching...
No Matches
THM1176IM_Test01_Connect.cpp
Go to the documentation of this file.
1// Copyright (c) 2020 Metrolab Technology S.A., Geneva, Switzerland (www.metrolab.com)
2// See the included file LICENSE.txt for the licensing conditions.
3
7
8#include <regex>
9#include <thread>
10#include <chrono>
11#include <iostream>
12
13#include <QtTest>
14#include <QSignalSpy>
15
16#include "CTHM1176InstrumentManager.h"
17
18#define THM1176_PROMPT_TIME 10 // s
19#define THM1176_BOOT_N_SCAN_TIME 15000 // ms
20#define THM1176_CONNECT_TIME 10000 // ms
21#define THM1176_SCAN_INTERVAL 1000 // ms
22#define THM1176_SILLY_RESOURCE_NAME "Humpty_Dumpty_had_a_great_fall"
23
24 using namespace MTL;
25
26 static CTHM1176InstrumentManager Manager;
27
28//----------------------------------------------------------------------//
29// Utility functions //
30//----------------------------------------------------------------------//
31 static void PromptAndWait(std::string Prompt)
32{
33 std::string l_Space = ("" == Prompt) ? "" : " ";
34 std::string l_Message = ">>> " + Prompt + l_Space + "(Will continue in " + std::to_string(THM1176_PROMPT_TIME) + " seconds) <<<";
35 QWARN(" ");
36 QWARN(l_Message.c_str());
37 QThread::currentThread()->sleep(THM1176_PROMPT_TIME);
38}
39
40//----------------------------------------------------------------------//
41// Test class definition //
42//----------------------------------------------------------------------//
43 class THM1176IM_Test01_Connect: public QObject
44{
45 Q_OBJECT
46
47 public:
48 THM1176IM_Test01_Connect();
49 ~THM1176IM_Test01_Connect();
50
51 private slots:
53 void initTestCase(void);
54
56 void cleanupTestCase(void);
57
59 void TestNotifyInstrumentList(void);
60
62 void TestSetCurrentInstrument(void);
63
64};
65
66//----------------------------------------------------------------------//
67// Test case constructor and destructor //
68//----------------------------------------------------------------------//
69 THM1176IM_Test01_Connect::THM1176IM_Test01_Connect()
70{
71
72}
73
74 THM1176IM_Test01_Connect::~THM1176IM_Test01_Connect()
75{
76
77}
78
79//----------------------------------------------------------------------//
80// Test case initialization and cleanup //
81//----------------------------------------------------------------------//
82 void THM1176IM_Test01_Connect::initTestCase(void)
83{
84 Manager.Start();
85}
86
87 void THM1176IM_Test01_Connect::cleanupTestCase(void)
88{
89 Manager.Stop();
90}
91
100 void THM1176IM_Test01_Connect::TestNotifyInstrumentList(void)
101{
102 QSignalSpy l_NotifyInstrumentListSpy(&Manager, SIGNAL(NotifyInstrumentList(CResourceList)));
103 QSignalSpy l_NotifyErrorListSpy(&Manager, SIGNAL(NotifyErrorList(CErrorList)));
104 QList<QVariant> l_Arguments;
105 CResourceList l_ResourceList;
106
107 // Have the user plug in the first THM, and wait for it to boot.
108 PromptAndWait("Please plug in the first THM");
109 l_NotifyInstrumentListSpy.wait(THM1176_BOOT_N_SCAN_TIME);
110
111 // Make sure the signal was emitted exactly one time, and that
112 // there is exactly one resource.
113 QCOMPARE(l_NotifyInstrumentListSpy.count(), 1);
114
115 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
116 l_ResourceList = qvariant_cast<CResourceList>(l_Arguments.at(0));
117
118 QVERIFY(l_ResourceList.size() == 1);
119
120 // Have the user plug in a second THM, and wait for it to boot.
121 PromptAndWait("Please plug in the second THM");
122 l_NotifyInstrumentListSpy.wait(THM1176_BOOT_N_SCAN_TIME);
123
124 // Make sure the signal was emitted exactly one time, and that
125 // there are exactly two resources.
126 QCOMPARE(l_NotifyInstrumentListSpy.count(), 1);
127
128 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
129 l_ResourceList = qvariant_cast<CResourceList>(l_Arguments.at(0));
130 QVERIFY(l_ResourceList.size() == 2);
131
132 // Have the user unplug the THMs, and wait for one scan.
133 PromptAndWait("Please unplug both THMs");
134 l_NotifyInstrumentListSpy.wait(THM1176_SCAN_INTERVAL);
135
136 // Make sure the signal was emitted once or twice, and that there are
137 // no resources left.
138 QVERIFY(l_NotifyInstrumentListSpy.count() == 1 || l_NotifyInstrumentListSpy.count() == 2);
139 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
140 if (l_NotifyInstrumentListSpy.count() == 1)
141 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
142 l_ResourceList = qvariant_cast<CResourceList>(l_Arguments.at(0));
143 QVERIFY(l_ResourceList.size() == 0);
144
145 // Make sure we got no errors.
146 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
147
148} // THM1176IM_Test01_Connect::TestNotifyInstrumentList
149
177 void THM1176IM_Test01_Connect::TestSetCurrentInstrument(void)
178{
179 // Create Signal Spies to retrieve instrument list, instrument info, parameters and possible errors.
180 QSignalSpy l_NotifyInstrumentListSpy(&Manager, SIGNAL(NotifyInstrumentList(CResourceList)));
181 QSignalSpy l_NotifyCurrentInstrumentSpy(&Manager, SIGNAL(NotifyCurrentInstrument(tResourceName)));
182
183 QSignalSpy l_NotifyIdentificationSpy(&Manager, SIGNAL(NotifyIdentification(sIdentifier)));
184 QSignalSpy l_NotifyRangeListSpy(&Manager, SIGNAL(NotifyRangeList(CFluxList)));
185 QSignalSpy l_NotifyUnitsListSpy(&Manager, SIGNAL(NotifyUnitsList(CTHM1176UnitsList)));
186 QSignalSpy l_NotifyDivisorListSpy(&Manager, SIGNAL(NotifyDivisorList(CDivisorList)));
187 QSignalSpy l_NotifyAveragingParmBoundsSpy(&Manager, SIGNAL(NotifyAveragingParmBounds(sAveraging<sBoundedParm>)));
188 QSignalSpy l_NotifyTriggerParmBoundsSpy(&Manager, SIGNAL(NotifyTriggerParmBounds(sInputTrigger<sBoundedParm>)));
189 QSignalSpy l_NotifyRangeParmBoundsSpy(&Manager, SIGNAL(NotifyRangeParmBounds(sRange<sBoundedParm>)));
190
191 QSignalSpy l_NotifyAveragingParmsSpy(&Manager, SIGNAL(NotifyAveragingParms(sAveraging<uParm>)));
192 QSignalSpy l_NotifyTriggerParmsSpy(&Manager, SIGNAL(NotifyTriggerParms(sInputTrigger<uParm>)));
193 QSignalSpy l_NotifyOutputSelectSpy(&Manager, SIGNAL(NotifyOutputSelect(sArbitraryMeasurements)));
194 QSignalSpy l_NotifySleepParmSpy(&Manager, SIGNAL(NotifySleepParm(bool)));
195 QSignalSpy l_NotifyUnitsSpy(&Manager, SIGNAL(NotifyUnits(eTHM1176Units)));
196 QSignalSpy l_NotifyRangeParmsSpy(&Manager, SIGNAL(NotifyRangeParms(sRange<uParm>)));
197 QSignalSpy l_NotifyCommFormatSpy(&Manager, SIGNAL(NotifyCommFormat(eCommunicationFormat)));
198
199 QSignalSpy l_NotifyOperatingModeSpy(&Manager, SIGNAL(NotifyOperatingMode(eTHM1176OperatingMode)));
200 QSignalSpy l_NotifyErrorListSpy(&Manager, SIGNAL(NotifyErrorList(CErrorList)));
201
202 // Local variables.
203 QList<QVariant> l_Arguments;
204
205 CResourceList l_ResourceList;
206 tResourceName l_CurrentInstrument;
207 tResourceName l_FormerInstrument;
208 sIdentifier l_Identification;
209 CFluxList l_RangeList;
210 CTHM1176UnitsList l_UnitsList;
211 CDivisorList l_DivisorList;
212 sAveraging<sBoundedParm> l_AveragingBounds;
213 sInputTrigger<sBoundedParm> l_TriggerBounds;
214 sRange<sBoundedParm> l_RangeBounds;
215 eTHM1176OperatingMode l_CurrentOperatingMode;
216 CErrorList l_LatestErrors;
217
218 sAveraging<uParm> l_AveragingParms;
219 sInputTrigger<uParm> l_Trigger;
220 sArbitraryMeasurements l_OutputSelect;
221 bool l_SleepParm;
222 eTHM1176Units l_Units;
223 bool l_UseCalibration;
224 sRange<uParm> l_RangeParms;
225 eCommunicationFormat l_CommFormat;
226
227 // Have the user plug in two THMs, and wait for them to boot.
228 // Make sure the NotifyInstrumentList signal was emitted once or twice,
229 // and that there are two resources in the end.
230 PromptAndWait("Please plug in two THMs");
231 for (int i = 0; i < 2; i++)
232 {
233 // Wait for a signal.
234 l_NotifyInstrumentListSpy.wait(THM1176_BOOT_N_SCAN_TIME);
235
236 // Possibly we got 2 signals; take the last one.
237 QVERIFY(l_NotifyInstrumentListSpy.count() == 1 || l_NotifyInstrumentListSpy.count() == 2);
238 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
239 if (l_NotifyInstrumentListSpy.count() == 1)
240 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
241 l_ResourceList = qvariant_cast<CResourceList>(l_Arguments.at(0));
242
243 // If we got 2 VISA resources on the first try, all is well.
244 // Otherwise loop back to wait for the second THM to boot.
245 if (l_ResourceList.size() == 2) break;
246 }
247 QCOMPARE(static_cast<int>(l_ResourceList.size()), 2);
248
249 // Emit SetCurrentInstrument to select THM 1.
250 // Make sure we got all the appropriate signals, with non-null results.
251 Manager.SetCurrentInstrument(l_ResourceList[0]);
252
253 // Wait for this instrument to become idle.
254 l_NotifyOperatingModeSpy.wait(THM1176_CONNECT_TIME);
255 QCOMPARE(l_NotifyOperatingModeSpy.count(), 1);
256 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
257 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
258 QCOMPARE(l_CurrentOperatingMode, kTHM1176Idle);
259
260 // Retrieve current instrument.
261 l_FormerInstrument = l_CurrentInstrument;
262 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 1);
263 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
264 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
265 QCOMPARE(l_CurrentInstrument, l_ResourceList[0]);
266
267 // Retrieve instrument information and parameter bounds for this THM.
268 QCOMPARE(l_NotifyIdentificationSpy.count(), 1);
269 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
270 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
271 QVERIFY(!l_Identification.Manufacturer.empty() && !l_Identification.Model.empty() && l_Identification.SerialNumber != 0);
272
273 QCOMPARE(l_NotifyRangeListSpy.count(), 1);
274 l_Arguments = l_NotifyRangeListSpy.takeFirst();
275 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
276 QVERIFY(!l_RangeList.empty());
277
278 QCOMPARE(l_NotifyUnitsListSpy.count(), 1);
279 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
280 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
281 QVERIFY(!l_UnitsList.empty());
282
283 QCOMPARE(l_NotifyDivisorListSpy.count(), 1);
284 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
285 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
286 QVERIFY(!l_DivisorList.empty());
287
288 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 1);
289 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
290 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
291 QVERIFY(l_AveragingBounds.NoPoints.Val != 0 && l_AveragingBounds.NoPoints.Min != 0 &&
292 l_AveragingBounds.NoPoints.Max != 0 && l_AveragingBounds.NoPoints.Def != 0);
293
294 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 1);
295 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
296 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
297 QVERIFY(l_TriggerBounds.Period_s.Val != 0 && l_TriggerBounds.Period_s.Min != 0 &&
298 l_TriggerBounds.Period_s.Max != 0 && l_TriggerBounds.Period_s.Def != 0 &&
299 l_TriggerBounds.Count.Val != 0 && l_TriggerBounds.Count.Min != 0 &&
300 l_TriggerBounds.Count.Max != 0 && l_TriggerBounds.Count.Def != 0);
301
302 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 1);
303 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
304 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
305 QVERIFY(l_RangeBounds.Range.Val != 0 && l_RangeBounds.Range.Min != 0 &&
306 l_RangeBounds.Range.Max != 0 && l_RangeBounds.Range.Def != 0);
307
308 // Retrieve the current parameters for this instrument.
309 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 1);
310 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
311 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
312 QVERIFY(l_AveragingParms.NoPoints > 0);
313
314 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 1);
315 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
316 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
317 QVERIFY(l_Trigger.Period_s > 0. && l_Trigger.Count > 0);
318
319 QCOMPARE(l_NotifyOutputSelectSpy.count(), 1);
320 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
321 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
322
323 QCOMPARE(l_NotifySleepParmSpy.count(), 1);
324 l_Arguments = l_NotifySleepParmSpy.takeFirst();
325 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
326
327 QCOMPARE(l_NotifyUnitsSpy.count(), 1);
328 l_Arguments = l_NotifyUnitsSpy.takeFirst();
329 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
330
331 QCOMPARE(l_NotifyRangeParmsSpy.count(), 1);
332 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
333 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
334
335 QCOMPARE(l_NotifyCommFormatSpy.count(), 1);
336 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
337 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
338
339 // We expect no errors.
340 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
341
342 std::cout << "- Connected to " << l_Identification.Model << ", S/N " << l_Identification.SerialNumber << std::endl;
343
344 // Emit SetCurrentInstrument to select THM 1 again.
345 // Make sure we get none of the signals.
346 Manager.SetCurrentInstrument(l_ResourceList[0]);
347
348 l_NotifyCurrentInstrumentSpy.wait(THM1176_CONNECT_TIME);
349 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 0);
350
351 // Retrieve instrument information and parameter bounds for this THM.
352 QCOMPARE(l_NotifyIdentificationSpy.count(), 0);
353 QCOMPARE(l_NotifyRangeListSpy.count(), 0);
354 QCOMPARE(l_NotifyUnitsListSpy.count(), 0);
355 QCOMPARE(l_NotifyDivisorListSpy.count(), 0);
356 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 0);
357 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 0);
358 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 0);
359
360 // Retrieve the current parameters for this instrument.
361 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 0);
362 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 0);
363 QCOMPARE(l_NotifyOutputSelectSpy.count(), 0);
364 QCOMPARE(l_NotifySleepParmSpy.count(), 0);
365 QCOMPARE(l_NotifyUnitsSpy.count(), 0);
366 QCOMPARE(l_NotifyRangeParmsSpy.count(), 0);
367 QCOMPARE(l_NotifyCommFormatSpy.count(), 0);
368
369 // Retrieve the operating mode and error list.
370 QCOMPARE(l_NotifyOperatingModeSpy.count(), 0);
371 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
372
373 std::cout << "- Still connected to " << l_Identification.Model << ", S/N " << l_Identification.SerialNumber << std::endl;
374
375 // Emit SetCurrentInstrument for nonexistent THM.
376 // Make sure we receive a NotifyErrorList; nothing else.
377 Manager.SetCurrentInstrument(THM1176_SILLY_RESOURCE_NAME);
378
379 l_FormerInstrument = l_CurrentInstrument;
380 l_NotifyCurrentInstrumentSpy.wait(THM1176_CONNECT_TIME);
381 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 0);
382
383 // Retrieve instrument information and parameter bounds for this THM.
384 QCOMPARE(l_NotifyIdentificationSpy.count(), 0);
385 QCOMPARE(l_NotifyRangeListSpy.count(), 0);
386 QCOMPARE(l_NotifyUnitsListSpy.count(), 0);
387 QCOMPARE(l_NotifyDivisorListSpy.count(), 0);
388 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 0);
389 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 0);
390 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 0);
391
392 // Retrieve the current parameters for this instrument.
393 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 0);
394 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 0);
395 QCOMPARE(l_NotifyOutputSelectSpy.count(), 0);
396 QCOMPARE(l_NotifySleepParmSpy.count(), 0);
397 QCOMPARE(l_NotifyUnitsSpy.count(), 0);
398 QCOMPARE(l_NotifyRangeParmsSpy.count(), 0);
399 QCOMPARE(l_NotifyCommFormatSpy.count(), 0);
400
401 // Retrieve the operating mode and error list.
402 QCOMPARE(l_NotifyOperatingModeSpy.count(), 0);
403
404 // Retrieve the error list.
405 QCOMPARE(l_NotifyErrorListSpy.count(), 1);
406 l_Arguments = l_NotifyErrorListSpy.takeFirst();
407 l_LatestErrors = qvariant_cast<CErrorList>(l_Arguments.at(0));
408 QCOMPARE(static_cast<int>(l_LatestErrors.size()), 1);
409
410 std::cout << "- Invalid connection request returned error: " << l_LatestErrors[0].Code << ", " <<
411 l_LatestErrors[0].Description << ", " << l_LatestErrors[0].Context << std::endl;
412 std::cout << "- Still connected to " << l_Identification.Model << ", S/N " << l_Identification.SerialNumber << std::endl;
413
414 // Emit SetCurrentInstrument to select THM 2.
415 Manager.SetCurrentInstrument(l_ResourceList[1]);
416
417 // NotifyOperatingMode is emitted twice: once for the diconnect, once for the connect.
418 // Otherwise, we should get all the appropriate signals twice, once with null and once with non-null results.
419 l_NotifyOperatingModeSpy.wait(THM1176_CONNECT_TIME);
420 QVERIFY(l_NotifyOperatingModeSpy.count() > 0);
421 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
422 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
423 QCOMPARE(l_CurrentOperatingMode, kTHM1176NotConnected);
424 if (l_NotifyOperatingModeSpy.count() <= 0)
425 {
426 l_NotifyOperatingModeSpy.wait(THM1176_CONNECT_TIME);
427 QCOMPARE(l_NotifyOperatingModeSpy.count(), 1);
428 }
429 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
430 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
431 QCOMPARE(l_CurrentOperatingMode, kTHM1176Idle);
432
433 // Retrieve the Current Instrument.
434 l_FormerInstrument = l_CurrentInstrument;
435 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 2);
436 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
437 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
438 QVERIFY(l_CurrentInstrument.empty());
439 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
440 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
441 QVERIFY(l_CurrentInstrument == l_ResourceList[1]);
442
443 // Retrieve instrument information and parameter bounds for this THM.
444 QCOMPARE(l_NotifyIdentificationSpy.count(), 2);
445 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
446 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
447 QVERIFY(l_Identification.Manufacturer.empty() && l_Identification.Model.empty() && l_Identification.SerialNumber == 0);
448 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
449 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
450 QVERIFY(!l_Identification.Manufacturer.empty() && !l_Identification.Model.empty() && l_Identification.SerialNumber != 0);
451
452 QCOMPARE(l_NotifyRangeListSpy.count(), 2);
453 l_Arguments = l_NotifyRangeListSpy.takeFirst();
454 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
455 QVERIFY(l_RangeList.empty());
456 l_Arguments = l_NotifyRangeListSpy.takeFirst();
457 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
458 QVERIFY(!l_RangeList.empty());
459
460 QCOMPARE(l_NotifyUnitsListSpy.count(), 2);
461 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
462 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
463 QVERIFY(l_UnitsList.empty());
464 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
465 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
466 QVERIFY(!l_UnitsList.empty());
467
468 QCOMPARE(l_NotifyDivisorListSpy.count(), 2);
469 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
470 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
471 QVERIFY(l_DivisorList.empty());
472 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
473 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
474 QVERIFY(!l_DivisorList.empty());
475
476 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 2);
477 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
478 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
479 QVERIFY(l_AveragingBounds.NoPoints.Val == 0 && l_AveragingBounds.NoPoints.Min == 0 &&
480 l_AveragingBounds.NoPoints.Max == 0 && l_AveragingBounds.NoPoints.Def == 0);
481 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
482 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
483 QVERIFY(l_AveragingBounds.NoPoints.Val != 0 && l_AveragingBounds.NoPoints.Min != 0 &&
484 l_AveragingBounds.NoPoints.Max != 0 && l_AveragingBounds.NoPoints.Def != 0);
485
486 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 2);
487 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
488 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
489 QVERIFY(l_TriggerBounds.Period_s.Val == 0 && l_TriggerBounds.Period_s.Min == 0 &&
490 l_TriggerBounds.Period_s.Max == 0 && l_TriggerBounds.Period_s.Def == 0 &&
491 l_TriggerBounds.Count.Val == 0 && l_TriggerBounds.Count.Min == 0 &&
492 l_TriggerBounds.Count.Max == 0 && l_TriggerBounds.Count.Def == 0);
493 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
494 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
495 QVERIFY(l_TriggerBounds.Period_s.Val != 0 && l_TriggerBounds.Period_s.Min != 0 &&
496 l_TriggerBounds.Period_s.Max != 0 && l_TriggerBounds.Period_s.Def != 0 &&
497 l_TriggerBounds.Count.Val != 0 && l_TriggerBounds.Count.Min != 0 &&
498 l_TriggerBounds.Count.Max != 0 && l_TriggerBounds.Count.Def != 0);
499
500 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 2);
501 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
502 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
503 QVERIFY(l_RangeBounds.Range.Val == 0 && l_RangeBounds.Range.Min == 0 &&
504 l_RangeBounds.Range.Max == 0 && l_RangeBounds.Range.Def == 0);
505 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
506 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
507 QVERIFY(l_RangeBounds.Range.Val != 0 && l_RangeBounds.Range.Min != 0 &&
508 l_RangeBounds.Range.Max != 0 && l_RangeBounds.Range.Def != 0);
509
510 // Retrieve the current parameters for this instrument.
511 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 2);
512 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
513 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
514 QVERIFY(l_AveragingParms.NoPoints == 0);
515 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
516 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
517 QVERIFY(l_AveragingParms.NoPoints > 0);
518
519 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 2);
520 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
521 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
522 QVERIFY(l_Trigger.Source == kInputTrigSrcImmediate && l_Trigger.Period_s == 0. && l_Trigger.Count == 0);
523 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
524 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
525 QVERIFY(l_Trigger.Period_s > 0. && l_Trigger.Count > 0);
526
527 QCOMPARE(l_NotifyOutputSelectSpy.count(), 2);
528 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
529 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
530 QVERIFY(l_OutputSelect.Bx && l_OutputSelect.By && l_OutputSelect.Bz &&
531 l_OutputSelect.Temperature && l_OutputSelect.Timestamp && l_OutputSelect.NoMeasurements == 1);
532 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
533 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
534
535 QCOMPARE(l_NotifySleepParmSpy.count(), 2);
536 l_Arguments = l_NotifySleepParmSpy.takeFirst();
537 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
538 QVERIFY(!l_SleepParm);
539 l_Arguments = l_NotifySleepParmSpy.takeFirst();
540 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
541
542 QCOMPARE(l_NotifyUnitsSpy.count(), 2);
543 l_Arguments = l_NotifyUnitsSpy.takeFirst();
544 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
545 QVERIFY(l_Units == MTL::kT);
546 l_Arguments = l_NotifyUnitsSpy.takeFirst();
547 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
548
549 QCOMPARE(l_NotifyRangeParmsSpy.count(), 2);
550 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
551 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
552 QVERIFY(!l_RangeParms.Auto && l_RangeParms.Range == 0.f);
553 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
554 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
555
556 QCOMPARE(l_NotifyCommFormatSpy.count(), 2);
557 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
558 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
559 QVERIFY(l_CommFormat == kComFormatAscii);
560 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
561 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
562
563 // Retrieve the error list.
564 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
565
566 std::cout << "- Connected to " << l_Identification.Model << ", S/N " << l_Identification.SerialNumber << std::endl;
567
568 // Have the user unplug THM 2.
569 // Make sure we get signals with empty lists, plus a NotifyErrorList.
570 std::string l_Prompt = "Please unplug " + l_Identification.Model + ", S/N " + std::to_string(l_Identification.SerialNumber);
571 PromptAndWait(l_Prompt);
572 l_NotifyInstrumentListSpy.wait(THM1176_BOOT_N_SCAN_TIME);
573 QVERIFY(l_NotifyInstrumentListSpy.count() == 1);
574 l_Arguments = l_NotifyInstrumentListSpy.takeFirst();
575 l_ResourceList = qvariant_cast<CResourceList>(l_Arguments.at(0));
576
577 // The last signal that should arrive is NotifyCommFormat.
578 l_NotifyCommFormatSpy.wait(THM1176_CONNECT_TIME);
579 QCOMPARE(l_NotifyCommFormatSpy.count(), 1);
580 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
581 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
582 QVERIFY(l_CommFormat == kComFormatAscii);
583
584 // Retrieve the current instrument.
585 l_FormerInstrument = l_CurrentInstrument;
586 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 1);
587 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
588 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
589 QVERIFY(l_CurrentInstrument.empty());
590
591 // Retrieve instrument information and parameter bounds for this THM.
592 QCOMPARE(l_NotifyIdentificationSpy.count(), 1);
593 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
594 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
595 QVERIFY(l_Identification.Manufacturer.empty() && l_Identification.Model.empty() && l_Identification.SerialNumber == 0);
596
597 QCOMPARE(l_NotifyRangeListSpy.count(), 1);
598 l_Arguments = l_NotifyRangeListSpy.takeFirst();
599 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
600 QVERIFY(l_RangeList.empty());
601
602 QCOMPARE(l_NotifyUnitsListSpy.count(), 1);
603 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
604 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
605 QVERIFY(l_UnitsList.empty());
606
607 QCOMPARE(l_NotifyDivisorListSpy.count(), 1);
608 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
609 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
610 QVERIFY(l_DivisorList.empty());
611
612 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 1);
613 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
614 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
615 QVERIFY(l_AveragingBounds.NoPoints.Val == 0 && l_AveragingBounds.NoPoints.Min == 0 &&
616 l_AveragingBounds.NoPoints.Max == 0 && l_AveragingBounds.NoPoints.Def == 0);
617
618 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 1);
619 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
620 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
621 QVERIFY(l_TriggerBounds.Period_s.Val == 0 && l_TriggerBounds.Period_s.Min == 0 &&
622 l_TriggerBounds.Period_s.Max == 0 && l_TriggerBounds.Period_s.Def == 0 &&
623 l_TriggerBounds.Count.Val == 0 && l_TriggerBounds.Count.Min == 0 &&
624 l_TriggerBounds.Count.Max == 0 && l_TriggerBounds.Count.Def == 0);
625
626 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 1);
627 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
628 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
629 QVERIFY(l_RangeBounds.Range.Val == 0 && l_RangeBounds.Range.Min == 0 &&
630 l_RangeBounds.Range.Max == 0 && l_RangeBounds.Range.Def == 0);
631
632 // Retrieve the current parameters for this instrument.
633 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 1);
634 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
635 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
636 QVERIFY(l_AveragingParms.NoPoints == 0);
637
638 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 1);
639 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
640 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
641 QVERIFY(l_Trigger.Period_s == 0. && l_Trigger.Count == 0);
642
643 QCOMPARE(l_NotifyOutputSelectSpy.count(), 1);
644 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
645 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
646 QVERIFY(l_OutputSelect.Bx && l_OutputSelect.By && l_OutputSelect.Bz &&
647 l_OutputSelect.Temperature && l_OutputSelect.Timestamp &&
648 l_OutputSelect.NoMeasurements == 1);
649
650 QCOMPARE(l_NotifySleepParmSpy.count(), 1);
651 l_Arguments = l_NotifySleepParmSpy.takeFirst();
652 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
653 QVERIFY(!l_SleepParm);
654
655 QCOMPARE(l_NotifyUnitsSpy.count(), 1);
656 l_Arguments = l_NotifyUnitsSpy.takeFirst();
657 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
658 QVERIFY(l_Units == MTL::kT);
659
660 QCOMPARE(l_NotifyRangeParmsSpy.count(), 1);
661 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
662 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
663 QVERIFY(!l_RangeParms.Auto && l_RangeParms.Range == 0.f);
664
665 // Retrieve the operating mode and error list.
666 QCOMPARE(l_NotifyOperatingModeSpy.count(), 1);
667 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
668 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
669 QCOMPARE(l_CurrentOperatingMode, kTHM1176NotConnected);
670
671 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
672
673 std::cout << "- No longer connected" << std::endl;
674
675 // Emit SetCurrentInstrument for the now unplugged THM.
676 // Make sure we get NotifyCurrentInstrument twice, once for the requested resource, once for no resource,
677 // plus a NotifyErrorList.
678 Manager.SetCurrentInstrument(l_FormerInstrument);
679
680 l_NotifyCurrentInstrumentSpy.wait(THM1176_CONNECT_TIME);
681 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 0);
682
683 // Retrieve instrument information and parameter bounds for this THM.
684 QCOMPARE(l_NotifyIdentificationSpy.count(), 0);
685 QCOMPARE(l_NotifyRangeListSpy.count(), 0);
686 QCOMPARE(l_NotifyUnitsListSpy.count(), 0);
687 QCOMPARE(l_NotifyDivisorListSpy.count(), 0);
688 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 0);
689 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 0);
690 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 0);
691
692 // Retrieve the current parameters for this instrument.
693 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 0);
694 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 0);
695 QCOMPARE(l_NotifyOutputSelectSpy.count(), 0);
696 QCOMPARE(l_NotifySleepParmSpy.count(), 0);
697 QCOMPARE(l_NotifyUnitsSpy.count(), 0);
698 QCOMPARE(l_NotifyRangeParmsSpy.count(), 0);
699 QCOMPARE(l_NotifyCommFormatSpy.count(), 0);
700
701 // Retrieve the operating mode and error list.
702 QCOMPARE(l_NotifyOperatingModeSpy.count(), 0);
703
704 // Retrieve the error list.
705 QCOMPARE(l_NotifyErrorListSpy.count(), 1);
706 l_Arguments = l_NotifyErrorListSpy.takeFirst();
707 l_LatestErrors = qvariant_cast<CErrorList>(l_Arguments.at(0));
708 QCOMPARE(static_cast<int>(l_LatestErrors.size()), 1);
709
710 std::cout << "- Invalid connection request returned error: " << l_LatestErrors[0].Code << ", " <<
711 l_LatestErrors[0].Description << ", " << l_LatestErrors[0].Context << std::endl;
712 std::cout << "- No longer connected" << std::endl;
713
714 // Emit SetCurrentInstrument to select THM 1.
715 // Make sure we got all the appropriate signals, with non-null results.
716 Manager.SetCurrentInstrument(l_ResourceList[0]);
717
718 // Wait for the operating mode to become Idle.
719 l_NotifyOperatingModeSpy.wait(THM1176_CONNECT_TIME);
720 QCOMPARE(l_NotifyOperatingModeSpy.count(), 1);
721 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
722 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
723 QCOMPARE(l_CurrentOperatingMode, kTHM1176Idle);
724
725 // Retrieve the current instrument.
726 l_FormerInstrument = l_CurrentInstrument;
727 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 1);
728 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
729 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
730 QCOMPARE(l_CurrentInstrument, l_ResourceList[0]);
731
732 // Retrieve instrument information and parameter bounds for this THM.
733 QCOMPARE(l_NotifyIdentificationSpy.count(), 1);
734 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
735 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
736 QVERIFY(!l_Identification.Manufacturer.empty() && !l_Identification.Model.empty() && l_Identification.SerialNumber != 0);
737
738 QCOMPARE(l_NotifyRangeListSpy.count(), 1);
739 l_Arguments = l_NotifyRangeListSpy.takeFirst();
740 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
741 QVERIFY(!l_RangeList.empty());
742
743 QCOMPARE(l_NotifyUnitsListSpy.count(), 1);
744 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
745 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
746 QVERIFY(!l_UnitsList.empty());
747
748 QCOMPARE(l_NotifyDivisorListSpy.count(), 1);
749 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
750 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
751 QVERIFY(!l_DivisorList.empty());
752
753 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 1);
754 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
755 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
756 QVERIFY(l_AveragingBounds.NoPoints.Val != 0 && l_AveragingBounds.NoPoints.Min != 0 &&
757 l_AveragingBounds.NoPoints.Max != 0 && l_AveragingBounds.NoPoints.Def != 0);
758
759 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 1);
760 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
761 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
762 QVERIFY(l_TriggerBounds.Period_s.Val != 0 && l_TriggerBounds.Period_s.Min != 0 &&
763 l_TriggerBounds.Period_s.Max != 0 && l_TriggerBounds.Period_s.Def != 0 &&
764 l_TriggerBounds.Count.Val != 0 && l_TriggerBounds.Count.Min != 0 &&
765 l_TriggerBounds.Count.Max != 0 && l_TriggerBounds.Count.Def != 0);
766
767 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 1);
768 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
769 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
770 QVERIFY(l_RangeBounds.Range.Val != 0 && l_RangeBounds.Range.Min != 0 &&
771 l_RangeBounds.Range.Max != 0 && l_RangeBounds.Range.Def != 0);
772
773 // Retrieve the current parameters for this instrument.
774 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 1);
775 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
776 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
777 QVERIFY(l_AveragingParms.NoPoints > 0);
778
779 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 1);
780 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
781 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
782 QVERIFY(l_Trigger.Period_s > 0. && l_Trigger.Count > 0);
783
784 QCOMPARE(l_NotifyOutputSelectSpy.count(), 1);
785 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
786 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
787
788 QCOMPARE(l_NotifySleepParmSpy.count(), 1);
789 l_Arguments = l_NotifySleepParmSpy.takeFirst();
790 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
791
792 QCOMPARE(l_NotifyUnitsSpy.count(), 1);
793 l_Arguments = l_NotifyUnitsSpy.takeFirst();
794 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
795
796 QCOMPARE(l_NotifyRangeParmsSpy.count(), 1);
797 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
798 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
799
800 QCOMPARE(l_NotifyCommFormatSpy.count(), 1);
801 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
802 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
803
804 // Retrieve the error list.
805 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
806
807 std::cout << "- Connected to " << l_Identification.Model << ", S/N " << l_Identification.SerialNumber << std::endl;
808
809 // - Emit SetOperatingMode to diconnect THM:
810 // Make sure we get signals with empty lists.
811 Manager.SetOperatingMode(kTHM1176NotConnected);
812
813 // The last signal should be NotifyCommFormat.
814 l_NotifyCommFormatSpy.wait(THM1176_CONNECT_TIME);
815 QCOMPARE(l_NotifyCommFormatSpy.count(), 1);
816 l_Arguments = l_NotifyCommFormatSpy.takeFirst();
817 l_CommFormat = qvariant_cast<eCommunicationFormat>(l_Arguments.at(0));
818 QVERIFY(l_CommFormat == kComFormatAscii);
819
820 // Retrieve the current instrument.
821 l_FormerInstrument = l_CurrentInstrument;
822 QCOMPARE(l_NotifyCurrentInstrumentSpy.count(), 1);
823 l_Arguments = l_NotifyCurrentInstrumentSpy.takeFirst();
824 l_CurrentInstrument = qvariant_cast<tResourceName>(l_Arguments.at(0));
825 QVERIFY(l_CurrentInstrument.empty());
826
827 // Retrieve instrument information and parameter bounds for this THM.
828 QCOMPARE(l_NotifyIdentificationSpy.count(), 1);
829 l_Arguments = l_NotifyIdentificationSpy.takeFirst();
830 l_Identification = qvariant_cast<sIdentifier>(l_Arguments.at(0));
831 QVERIFY(l_Identification.Manufacturer.empty() && l_Identification.Model.empty() && l_Identification.SerialNumber == 0);
832
833 QCOMPARE(l_NotifyRangeListSpy.count(), 1);
834 l_Arguments = l_NotifyRangeListSpy.takeFirst();
835 l_RangeList = qvariant_cast<CFluxList>(l_Arguments.at(0));
836 QVERIFY(l_RangeList.empty());
837
838 QCOMPARE(l_NotifyUnitsListSpy.count(), 1);
839 l_Arguments = l_NotifyUnitsListSpy.takeFirst();
840 l_UnitsList = qvariant_cast<CTHM1176UnitsList>(l_Arguments.at(0));
841 QVERIFY(l_UnitsList.empty());
842
843 QCOMPARE(l_NotifyDivisorListSpy.count(), 1);
844 l_Arguments = l_NotifyDivisorListSpy.takeFirst();
845 l_DivisorList = qvariant_cast<CDivisorList>(l_Arguments.at(0));
846 QVERIFY(l_DivisorList.empty());
847
848 QCOMPARE(l_NotifyAveragingParmBoundsSpy.count(), 1);
849 l_Arguments = l_NotifyAveragingParmBoundsSpy.takeFirst();
850 l_AveragingBounds = qvariant_cast<sAveraging<sBoundedParm>>(l_Arguments.at(0));
851 QVERIFY(l_AveragingBounds.NoPoints.Val == 0 && l_AveragingBounds.NoPoints.Min == 0 &&
852 l_AveragingBounds.NoPoints.Max == 0 && l_AveragingBounds.NoPoints.Def == 0);
853
854 QCOMPARE(l_NotifyTriggerParmBoundsSpy.count(), 1);
855 l_Arguments = l_NotifyTriggerParmBoundsSpy.takeFirst();
856 l_TriggerBounds = qvariant_cast<sInputTrigger<sBoundedParm>>(l_Arguments.at(0));
857 QVERIFY(l_TriggerBounds.Period_s.Val == 0 && l_TriggerBounds.Period_s.Min == 0 &&
858 l_TriggerBounds.Period_s.Max == 0 && l_TriggerBounds.Period_s.Def == 0 &&
859 l_TriggerBounds.Count.Val == 0 && l_TriggerBounds.Count.Min == 0 &&
860 l_TriggerBounds.Count.Max == 0 && l_TriggerBounds.Count.Def == 0);
861
862 QCOMPARE(l_NotifyRangeParmBoundsSpy.count(), 1);
863 l_Arguments = l_NotifyRangeParmBoundsSpy.takeFirst();
864 l_RangeBounds = qvariant_cast<sRange<sBoundedParm>>(l_Arguments.at(0));
865 QVERIFY(l_RangeBounds.Range.Val == 0 && l_RangeBounds.Range.Min == 0 &&
866 l_RangeBounds.Range.Max == 0 && l_RangeBounds.Range.Def == 0);
867
868 // Retrieve the current parameters for this instrument.
869 QCOMPARE(l_NotifyAveragingParmsSpy.count(), 1);
870 l_Arguments = l_NotifyAveragingParmsSpy.takeFirst();
871 l_AveragingParms = qvariant_cast<sAveraging<uParm>>(l_Arguments.at(0));
872 QVERIFY(l_AveragingParms.NoPoints == 0);
873
874 QCOMPARE(l_NotifyTriggerParmsSpy.count(), 1);
875 l_Arguments = l_NotifyTriggerParmsSpy.takeFirst();
876 l_Trigger = qvariant_cast<sInputTrigger<uParm>>(l_Arguments.at(0));
877 QVERIFY(l_Trigger.Period_s == 0. && l_Trigger.Count == 0);
878
879 QCOMPARE(l_NotifyOutputSelectSpy.count(), 1);
880 l_Arguments = l_NotifyOutputSelectSpy.takeFirst();
881 l_OutputSelect = qvariant_cast<sArbitraryMeasurements>(l_Arguments.at(0));
882 QVERIFY(l_OutputSelect.Bx && l_OutputSelect.By && l_OutputSelect.Bz &&
883 l_OutputSelect.Temperature && l_OutputSelect.Timestamp &&
884 l_OutputSelect.NoMeasurements == 1);
885
886 QCOMPARE(l_NotifySleepParmSpy.count(), 1);
887 l_Arguments = l_NotifySleepParmSpy.takeFirst();
888 l_SleepParm = qvariant_cast<bool>(l_Arguments.at(0));
889 QVERIFY(!l_SleepParm);
890
891 QCOMPARE(l_NotifyUnitsSpy.count(), 1);
892 l_Arguments = l_NotifyUnitsSpy.takeFirst();
893 l_Units = qvariant_cast<eTHM1176Units>(l_Arguments.at(0));
894 QVERIFY(l_Units == MTL::kT);
895
896 QCOMPARE(l_NotifyRangeParmsSpy.count(), 1);
897 l_Arguments = l_NotifyRangeParmsSpy.takeFirst();
898 l_RangeParms = qvariant_cast<sRange<uParm>>(l_Arguments.at(0));
899 QVERIFY(!l_RangeParms.Auto && l_RangeParms.Range == 0.f);
900
901 // Retrieve the operating mode and error list.
902 QCOMPARE(l_NotifyOperatingModeSpy.count(), 1);
903 l_Arguments = l_NotifyOperatingModeSpy.takeFirst();
904 l_CurrentOperatingMode = qvariant_cast<eTHM1176OperatingMode>(l_Arguments.at(0));
905 QCOMPARE(l_CurrentOperatingMode, kTHM1176NotConnected);
906
907 QCOMPARE(l_NotifyErrorListSpy.count(), 0);
908
909 std::cout << "- No longer connected" << std::endl;
910
911} // THM1176IM_Test01_Connect::TestSetCurrentInstrument
912
913//----------------------------------------------------------------------//
914// main() //
915//----------------------------------------------------------------------//
916QTEST_MAIN(THM1176IM_Test01_Connect)
917
918#include "THM1176IM_Test01_Connect.moc"
CTHM1176InstrumentManager.h
Interface definition for Metrolab THM1176/TFM1186 Instrument Manager.
THM1176_SILLY_RESOURCE_NAME
#define THM1176_SILLY_RESOURCE_NAME
Definition THM1176IM_Test01_Connect.cpp:22
THM1176_PROMPT_TIME
#define THM1176_PROMPT_TIME
Definition THM1176IM_Test01_Connect.cpp:18
Manager
static CTHM1176InstrumentManager Manager
Definition THM1176IM_Test01_Connect.cpp:26
THM1176_CONNECT_TIME
#define THM1176_CONNECT_TIME
Definition THM1176IM_Test01_Connect.cpp:20
THM1176_BOOT_N_SCAN_TIME
#define THM1176_BOOT_N_SCAN_TIME
Definition THM1176IM_Test01_Connect.cpp:19
THM1176_SCAN_INTERVAL
#define THM1176_SCAN_INTERVAL
Definition THM1176IM_Test01_Connect.cpp:21
PromptAndWait
static void PromptAndWait(std::string Prompt)
Definition THM1176IM_Test01_Connect.cpp:31
MTL::CTHM1176InstrumentManager
THM1176 Instrument Manager class: public interface.
Definition CTHM1176InstrumentManager.h:539
MTL::CTHM1176InstrumentManager::SetOperatingMode
void SetOperatingMode(eTHM1176OperatingMode OperatingMode)
Set a new operating mode, for example to start measuring.
Definition CTHM1176InstrumentManager.cpp:1650
MTL::CTHM1176InstrumentManager::Stop
void Stop(void)
Shut down the THM1176 Instrument Manager.
Definition CTHM1176InstrumentManager.cpp:1181
MTL::CTHM1176InstrumentManager::SetCurrentInstrument
void SetCurrentInstrument(tResourceName CurrentInstrument)
Connect a new instrument.
Definition CTHM1176InstrumentManager.cpp:1626
THM1176IM_Test01_Connect
Definition THM1176IM_Test01_Connect.cpp:44
THM1176IM_Test01_Connect::~THM1176IM_Test01_Connect
~THM1176IM_Test01_Connect()
Definition THM1176IM_Test01_Connect.cpp:74
THM1176IM_Test01_Connect::THM1176IM_Test01_Connect
THM1176IM_Test01_Connect()
Definition THM1176IM_Test01_Connect.cpp:69
MTL::Instrument::THM1176Types::eCommunicationFormat
eCommunicationFormat
Enumeration of possible formats for returned data.
Definition THM1176Types.h:466
MTL::Instrument::THM1176Types::kComFormatAscii
@ kComFormatAscii
Human-legible text.
Definition THM1176Types.h:467
MTL::Instrument::THM1176Types::kInputTrigSrcImmediate
@ kInputTrigSrcImmediate
Immediate trigger: start measurement immediately after previous one completes.
Definition THM1176Types.h:418
MTL::Instrument::tResourceName
std::string tResourceName
IEEE488 resource name.
Definition IEEE488InstrumentTypes.h:22
MTL
Definition CTHM1176InstrumentManager.h:179
MTL::eTHM1176OperatingMode
eTHM1176OperatingMode
Operating modes used to initiate actions or provide status.
Definition THM1176InstrumentManagerTypes.h:17
MTL::kTHM1176NotConnected
@ kTHM1176NotConnected
Disconnect instrument.
Definition THM1176InstrumentManagerTypes.h:18
MTL::kTHM1176Idle
@ kTHM1176Idle
Place the instrument in idle mode.
Definition THM1176InstrumentManagerTypes.h:20
MTL::eTHM1176Units
eTHM1176Units
Enumeration of possible measurement units, including "ADC".
Definition THM1176InstrumentManagerTypes.h:29
MTL::kT
@ kT
Tesla.
Definition THM1176InstrumentManagerTypes.h:30
MTL::Instrument::THM1176Types::sArbitraryMeasurements::Bx
bool Bx
Return the flux density X-component.
Definition THM1176Types.h:594
MTL::Instrument::THM1176Types::sArbitraryMeasurements::Temperature
bool Temperature
Return the sensor temperature.
Definition THM1176Types.h:597
MTL::Instrument::THM1176Types::sArbitraryMeasurements::By
bool By
Return the flux density Y-component.
Definition THM1176Types.h:595
MTL::Instrument::THM1176Types::sArbitraryMeasurements::Bz
bool Bz
Return the flux density Z-component.
Definition THM1176Types.h:596
MTL::Instrument::THM1176Types::sArbitraryMeasurements::Timestamp
bool Timestamp
Return the timestamp.
Definition THM1176Types.h:598
MTL::Instrument::THM1176Types::sArbitraryMeasurements::NoMeasurements
U32 NoMeasurements
Return this number of measurements.
Definition THM1176Types.h:599
MTL::Instrument::THM1176Types::sAveraging::NoPoints
ParmType< U16 > NoPoints
Number of points in block average.
Definition THM1176Types.h:389
MTL::Instrument::THM1176Types::sIdentifier::Manufacturer
std::string Manufacturer
Manufacturer name ("Metrolab Technology SA").
Definition THM1176Types.h:354
MTL::Instrument::THM1176Types::sIdentifier::SerialNumber
U32 SerialNumber
Serial number.
Definition THM1176Types.h:356
MTL::Instrument::THM1176Types::sIdentifier::Model
std::string Model
Model name (e.g. "THM1176-MF").
Definition THM1176Types.h:355
MTL::Instrument::THM1176Types::sInputTrigger::Count
ParmType< U16 > Count
Trigger count: take this many measurements before sending results.
Definition THM1176Types.h:429
MTL::Instrument::THM1176Types::sInputTrigger::Source
eInputTriggerSource Source
Trigger source.
Definition THM1176Types.h:427
MTL::Instrument::THM1176Types::sInputTrigger::Period_s
ParmType< F64 > Period_s
Trigger period, for timed trigger.
Definition THM1176Types.h:428
MTL::Instrument::THM1176Types::sRange::Auto
bool Auto
Auto-ranging enabled.
Definition THM1176Types.h:480
MTL::Instrument::THM1176Types::sRange::Range
ParmType< tFlux > Range
Measurement range, if auto-ranging is not enabled.
Definition THM1176Types.h:481