Coverage Report

Created: 2021-08-28 18:14

D:\git\skunkworks\herald-for-cpp\herald-tests\blecoordinator-tests.cpp
Line
Count
Source (jump to first uncovered line)
1
//  Copyright 2021 Herald Project Contributors
2
//  SPDX-License-Identifier: Apache-2.0
3
//
4
5
#include <memory>
6
#include <vector>
7
#include <iostream>
8
9
#include "test-templates.h"
10
11
#include "catch.hpp"
12
13
#include "herald/herald.h"
14
15
template <typename ContextT, typename BLEDBT>
16
class NoOpHeraldV1ProtocolProvider : public herald::ble::HeraldProtocolV1Provider {
17
public:
18
  NoOpHeraldV1ProtocolProvider(ContextT& context,BLEDBT& bledb)
19
    : ctx(context) 
20
      HLOGGERINIT(ctx,"TESTS","NoOpProvider")
21
7
  {}
22
7
  ~NoOpHeraldV1ProtocolProvider() = default;
23
  
24
  // FOR PLATFORMS WITH STD::ASYNC
25
  // void openConnection(const herald::datatype::TargetIdentifier& toTarget,
26
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
27
  //   connCallback(toTarget, true);
28
  // }
29
  // void closeConnection(const herald::datatype::TargetIdentifier& toTarget,
30
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
31
  //   connCallback(toTarget,false);
32
  // }
33
34
  // void serviceDiscovery(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
35
  //   HTDBG("serviceDiscovery called");
36
  //   cb(act,{});
37
  // }
38
39
  // void readPayload(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
40
  //   HTDBG("readPayload called");
41
  //   cb(act,{});
42
  // }
43
44
  // void immediateSend(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
45
  //   HTDBG("immediateSend called");
46
  //   cb(act,{});
47
  // }
48
49
  // void immediateSendAll(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
50
  //   HTDBG("immediateSendAll called");
51
  //   cb(act,{});
52
  // }
53
54
  // FOR PLATFORMS WITHOUT STD::SYNC
55
0
  bool openConnection(const herald::datatype::TargetIdentifier& toTarget) override {
56
0
    return true;
57
0
  }
58
0
  bool closeConnection(const herald::datatype::TargetIdentifier& toTarget) override {
59
0
    return false;
60
0
  }
61
  
62
2
  void restartScanningAndAdvertising() override {}
63
64
0
  std::optional<herald::engine::Activity> serviceDiscovery(herald::engine::Activity act) override {
65
0
    HTDBG("serviceDiscovery called");
66
0
    return {};
67
0
  }
68
69
0
  std::optional<herald::engine::Activity> readPayload(herald::engine::Activity act) override {
70
0
    HTDBG("readPayload called");
71
0
    return {};
72
0
  }
73
74
  // std::optional<herald::engine::Activity> immediateSend(herald::engine::Activity act) override {
75
  //   HTDBG("immediateSend called");
76
  //   return {};
77
  // }
78
79
  // std::optional<herald::engine::Activity> immediateSendAll(herald::engine::Activity act) override {
80
  //   HTDBG("immediateSendAll called");
81
  //   return {};
82
  // }
83
84
  ContextT& ctx;
85
  HLOGGER(ContextT);
86
};
87
88
1
TEST_CASE("blecoordinator-ctor", "[coordinator][ctor][basic]") {
89
1
  SECTION("blecoordinator-ctor") {
90
1
    DummyLoggingSink dls;
91
1
    DummyBluetoothStateManager dbsm;
92
1
    herald::DefaultPlatformType dpt;
93
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
94
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
95
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
96
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
97
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
98
1
99
1
    std::vector<herald::engine::FeatureTag> provided = coord.connectionsProvided();
100
1
    REQUIRE(provided.size() == 1); // Herald BLE protocol
101
1
    auto prot = provided.front();
102
1
    REQUIRE(prot == herald::engine::Features::HeraldBluetoothProtocolConnection);
103
1
104
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
105
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
106
1
      coord.requiredConnections();
107
1
    REQUIRE(conns.size() == 0);
108
1
109
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
110
1
    REQUIRE(acts.size() == 0);
111
1
  }
112
1
}
113
114
115
1
TEST_CASE("blecoordinator-unseen-device", "[coordinator][unseen-device][basic]") {
116
1
  SECTION("blecoordinator-unseen-device") {
117
1
    DummyLoggingSink dls;
118
1
    DummyBluetoothStateManager dbsm;
119
1
    herald::DefaultPlatformType dpt;
120
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
121
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
122
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
123
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
124
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
125
1
126
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
127
1
    herald::datatype::TargetIdentifier device1(devMac1);
128
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
129
1
130
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
131
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
132
1
      coord.requiredConnections();
133
1
    REQUIRE(conns.size() == 1);
134
1
    auto firstConn = conns.front();
135
1
    REQUIRE(std::get<0>(firstConn) == herald::engine::Features::HeraldBluetoothProtocolConnection);
136
1
    REQUIRE(std::get<1>(firstConn) > 0);
137
1
    REQUIRE(std::get<2>(firstConn).has_value());
138
1
    REQUIRE(std::get<2>(firstConn).value() == device1);
139
1
140
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
141
1
    REQUIRE(acts.size() == 1); // determine if herald only (read payload is at a later state)
142
1
    auto firstAct = acts.front();
143
1
    REQUIRE(firstAct.prerequisites.size() == 1);
144
1
  }
145
1
}
146
147
148
1
TEST_CASE("blecoordinator-android-no-id", "[coordinator][android-no-id][basic]") {
149
1
  SECTION("blecoordinator-android-no-id") {
150
1
    DummyLoggingSink dls;
151
1
    DummyBluetoothStateManager dbsm;
152
1
    herald::DefaultPlatformType dpt;
153
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
154
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
155
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
156
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
157
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
158
1
159
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
160
1
    herald::datatype::TargetIdentifier device1(devMac1);
161
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
162
1
163
1
    // Specify that some activity has already happened with the device
164
1
    std::vector<herald::datatype::UUID> heraldServiceList;
165
1
    heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
166
1
    devPtr1.services(heraldServiceList);
167
1
    devPtr1.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
168
1
169
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
170
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
171
1
      coord.requiredConnections();
172
1
    REQUIRE(conns.size() == 1);
173
1
    auto firstConn = conns.front();
174
1
    REQUIRE(std::get<0>(firstConn) == herald::engine::Features::HeraldBluetoothProtocolConnection);
175
1
    REQUIRE(std::get<1>(firstConn) > 0);
176
1
    REQUIRE(std::get<2>(firstConn).has_value());
177
1
    REQUIRE(std::get<2>(firstConn).value() == device1);
178
1
179
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
180
1
    REQUIRE(acts.size() == 1); // just read payload (ID)
181
1
    auto firstAct = acts.front();
182
1
    REQUIRE(firstAct.prerequisites.size() == 1);
183
1
  }
184
1
}
185
186
1
TEST_CASE("blecoordinator-two-mixed-no-id", "[coordinator][two-mixed-no-id][basic]") {
187
1
  SECTION("blecoordinator-two-mixed-no-id") {
188
1
    DummyLoggingSink dls;
189
1
    DummyBluetoothStateManager dbsm;
190
1
    herald::DefaultPlatformType dpt;
191
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
192
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
193
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
194
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
195
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
196
1
197
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
198
1
    herald::datatype::TargetIdentifier device1(devMac1);
199
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
200
1
201
1
    herald::datatype::Data devMac2(std::byte(0x1f),6);
202
1
    herald::datatype::TargetIdentifier device2(devMac2);
203
1
    herald::ble::BLEDevice& devPtr2 = db.device(device2);
204
1
205
1
    // Specify that some activity has already happened with the device
206
1
    std::vector<herald::datatype::UUID> heraldServiceList;
207
1
    heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
208
1
    devPtr1.services(heraldServiceList);
209
1
    devPtr1.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
210
1
    devPtr2.services(heraldServiceList);
211
1
    devPtr2.operatingSystem(herald::ble::BLEDeviceOperatingSystem::ios);
212
1
213
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
214
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
215
1
      coord.requiredConnections();
216
1
    REQUIRE(conns.size() == 2); // connections to BOTH devices
217
1
    auto firstConn = conns.front();
218
1
    REQUIRE(std::get<0>(firstConn) == herald::engine::Features::HeraldBluetoothProtocolConnection);
219
1
    REQUIRE(std::get<1>(firstConn) > 0);
220
1
    REQUIRE(std::get<2>(firstConn).has_value());
221
1
    REQUIRE(std::get<2>(firstConn).value() == device1);
222
1
223
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
224
1
    REQUIRE(acts.size() == 2); // just read payload (ID) for BOTH devices
225
1
    auto firstAct = acts.front();
226
1
    REQUIRE(firstAct.prerequisites.size() == 1);
227
1
  }
228
1
}
229
230
1
TEST_CASE("blecoordinator-got-os-and-id", "[coordinator][got-os-and-id][basic]") {
231
1
  SECTION("blecoordinator-got-os-and-id") {
232
1
    DummyLoggingSink dls;
233
1
    DummyBluetoothStateManager dbsm;
234
1
    herald::DefaultPlatformType dpt;
235
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
236
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
237
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
238
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
239
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
240
1
241
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
242
1
    herald::datatype::TargetIdentifier device1(devMac1);
243
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
244
1
245
1
    // Specify that some activity has already happened with the device
246
1
    std::vector<herald::datatype::UUID> heraldServiceList;
247
1
    heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
248
1
    devPtr1.services(heraldServiceList);
249
1
    devPtr1.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
250
1
    devPtr1.payloadData(herald::datatype::PayloadData(std::byte(5),32));
251
1
252
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
253
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
254
1
      coord.requiredConnections();
255
1
    REQUIRE(conns.size() == 0);
256
1
257
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
258
1
    REQUIRE(acts.size() == 0);
259
1
  }
260
1
}
261
262
1
TEST_CASE("blecoordinator-got-two-at-different-states", "[coordinator][got-two-at-different-states][basic]") {
263
1
  SECTION("blecoordinator-got-two-at-different-states") {
264
1
    DummyLoggingSink dls;
265
1
    DummyBluetoothStateManager dbsm;
266
1
    herald::DefaultPlatformType dpt;
267
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
268
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
269
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
270
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
271
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
272
1
273
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
274
1
    herald::datatype::TargetIdentifier device1(devMac1);
275
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
276
1
277
1
    herald::datatype::Data devMac2(std::byte(0x1f),6);
278
1
    herald::datatype::TargetIdentifier device2(devMac2);
279
1
    herald::ble::BLEDevice& devPtr2 = db.device(device2);
280
1
281
1
    // Specify that some activity has already happened with the device
282
1
    std::vector<herald::datatype::UUID> heraldServiceList;
283
1
    heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
284
1
    devPtr1.services(heraldServiceList);
285
1
    devPtr1.payloadData(herald::datatype::PayloadData(std::byte(5),32));
286
1
    devPtr2.services(heraldServiceList);
287
1
288
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
289
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
290
1
      coord.requiredConnections();
291
1
    REQUIRE(conns.size() == 1); // just for ONE device
292
1
    auto firstConn = conns.front();
293
1
    REQUIRE(std::get<0>(firstConn) == herald::engine::Features::HeraldBluetoothProtocolConnection);
294
1
    REQUIRE(std::get<1>(firstConn) > 0);
295
1
    REQUIRE(std::get<2>(firstConn).has_value());
296
1
    REQUIRE(std::get<2>(firstConn).value() == device2); // device 2 only
297
1
298
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
299
1
    REQUIRE(acts.size() == 1); // just read payload (ID) for ONE device
300
1
    auto firstAct = acts.front();
301
1
    REQUIRE(firstAct.prerequisites.size() == 1);
302
1
  }
303
1
}
304
305
306
// TEST_CASE("blecoordinator-got-immediate-send-targeted", "[coordinator][got-immediate-send-targeted][basic]") {
307
//   SECTION("blecoordinator-got-immediate-send-targeted") {
308
//     DummyLoggingSink dls;
309
//     DummyBluetoothStateManager dbsm;
310
//     herald::DefaultPlatformType dpt;
311
//     herald::Context ctx(dpt,dls,dbsm); // default context include
312
//     using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
313
//     herald::ble::ConcreteBLEDatabase<CT> db(ctx);
314
//     NoOpHeraldV1ProtocolProvider pp(ctx,db);
315
//     herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
316
317
//     herald::datatype::Data devMac1(std::byte(0x1d),6);
318
//     herald::datatype::TargetIdentifier device1(devMac1);
319
//     herald::ble::BLEDevice& devPtr1 = db.device(device1);
320
321
//     // Specify that some activity has already happened with the device
322
//     std::vector<herald::datatype::UUID> heraldServiceList;
323
//     heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
324
//     devPtr1.services(heraldServiceList);
325
//     devPtr1.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
326
//     devPtr1.payloadData(herald::datatype::PayloadData(std::byte(5),32));
327
//     devPtr1.immediateSendData(herald::datatype::ImmediateSendData(
328
//       herald::datatype::Data(std::byte(0x01),2)));
329
330
//     std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
331
//       std::optional<herald::datatype::TargetIdentifier>>> conns = 
332
//       coord.requiredConnections();
333
//     REQUIRE(conns.size() == 1);
334
335
//     std::vector<herald::engine::Activity> acts = coord.requiredActivities();
336
//     REQUIRE(acts.size() == 1);
337
//   }
338
// }
339
340
1
TEST_CASE("blecoordinator-got-three-at-different-states", "[coordinator][got-three-at-different-states][basic]") {
341
1
  SECTION("blecoordinator-got-three-at-different-states") {
342
1
    DummyLoggingSink dls;
343
1
    DummyBluetoothStateManager dbsm;
344
1
    herald::DefaultPlatformType dpt;
345
1
    herald::Context ctx(dpt,dls,dbsm); // default context include
346
1
    using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
347
1
    herald::ble::ConcreteBLEDatabase<CT> db(ctx);
348
1
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
349
1
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
350
1
351
1
    herald::datatype::Data devMac1(std::byte(0x1d),6);
352
1
    herald::datatype::TargetIdentifier device1(devMac1);
353
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
354
1
355
1
    herald::datatype::Data devMac2(std::byte(0x1f),6);
356
1
    herald::datatype::TargetIdentifier device2(devMac2);
357
1
    herald::ble::BLEDevice& devPtr2 = db.device(device2);
358
1
359
1
    herald::datatype::Data devMac3(std::byte(0x09),6);
360
1
    herald::datatype::TargetIdentifier device3(devMac3);
361
1
    herald::ble::BLEDevice& devPtr3 = db.device(device3);
362
1
363
1
    // Specify that some activity has already happened with the device
364
1
    std::vector<herald::datatype::UUID> heraldServiceList;
365
1
    heraldServiceList.push_back(ctx.getSensorConfiguration().serviceUUID);
366
1
    devPtr1.services(heraldServiceList);
367
1
    devPtr1.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
368
1
    devPtr1.payloadData(herald::datatype::PayloadData(std::byte(5),32));
369
1
    devPtr2.services(heraldServiceList);
370
1
    devPtr2.operatingSystem(herald::ble::BLEDeviceOperatingSystem::ios);
371
1
    devPtr3.services(heraldServiceList);
372
1
    devPtr3.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
373
1
    devPtr3.payloadData(herald::datatype::PayloadData(std::byte(5),32));
374
1
    // devPtr3.immediateSendData(herald::datatype::ImmediateSendData(
375
1
    //   herald::datatype::Data(std::byte(0x01),2)));
376
1
377
1
    std::vector<std::tuple<herald::engine::FeatureTag,herald::engine::Priority,
378
1
      std::optional<herald::datatype::TargetIdentifier>>> conns = 
379
1
      coord.requiredConnections();
380
1
    REQUIRE(conns.size() == 1); // 2 with immediateSend enabled
381
1
    auto firstConn = conns.front();
382
1
    REQUIRE(std::get<0>(firstConn) == herald::engine::Features::HeraldBluetoothProtocolConnection);
383
1
    REQUIRE(std::get<1>(firstConn) > 0);
384
1
    REQUIRE(std::get<2>(firstConn).has_value());
385
1
    REQUIRE(std::get<2>(firstConn).value() == device2);
386
1
    // auto secondConn = conns[1];
387
1
    // REQUIRE(std::get<1>(secondConn) > 0);
388
1
    // REQUIRE(std::get<2>(secondConn).has_value());
389
1
    // REQUIRE(std::get<2>(secondConn).value() == device3);
390
1
391
1
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
392
1
    REQUIRE(acts.size() == 1); // just read payload (ID) for ONE device, and immediate send for another
393
1
    auto firstAct = acts.front();
394
1
    REQUIRE(firstAct.prerequisites.size() == 1);
395
1
    REQUIRE(std::get<1>(firstAct.prerequisites.front()).has_value());
396
1
    REQUIRE(std::get<1>(firstAct.prerequisites.front()).value() == device2);
397
1
    // auto secondAct = acts[1];
398
1
    // REQUIRE(secondAct.prerequisites.size() == 1);
399
1
    // REQUIRE(secondAct.prerequisites.size() == 1);
400
1
    // REQUIRE(std::get<1>(secondAct.prerequisites.front()).has_value());
401
1
    // REQUIRE(std::get<1>(secondAct.prerequisites.front()).value() == device3);
402
1
  }
403
1
}
404
405
406
407
408
// Non-device specific activity (broadcast via notify e.g. immediate send all, remove old DB items)
409
410
// TODO create generic TimeSource that time-bound classes are templatised on, separate from the full context
411
412
/*
413
414
TEST_CASE("blecoordinator-remove-old", "[ble][coordinator][remove][old]") {
415
  SECTION("blecoordinator-remove-old") {
416
    DummyLoggingSink dls;
417
    DummyBluetoothStateManager dbsm;
418
    TimeSetPlatformType dpt; // Use a platform type with customised now() Date support
419
    herald::Context ctx(dpt,dls,dbsm); // default context include
420
    using CT = typename herald::Context<TimeSetPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
421
    herald::ble::ConcreteBLEDatabase<CT> db(ctx); // enables shared_from_this
422
      
423
    NoOpHeraldV1ProtocolProvider pp(ctx,db);
424
    herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
425
426
    DummyBLEDBDelegate delegate;
427
    db.add(delegate);
428
429
    REQUIRE(db.size() == 0);
430
    REQUIRE(delegate.createCallbackCalled == false);
431
    REQUIRE(delegate.updateCallbackCalled == false);
432
    REQUIRE(delegate.deleteCallbackCalled == false);
433
434
    herald::datatype::Data devMac(std::byte(0x02),6);
435
    herald::datatype::TargetIdentifier dev(devMac);
436
437
    // Set NOW time
438
    dpt.seconds = 10;
439
440
    // add in new device
441
    std::shared_ptr<herald::ble::BLEDevice> devPtr = db.device(dev);
442
    REQUIRE(db.size() == 1);
443
    REQUIRE(delegate.createCallbackCalled == true);
444
    REQUIRE(delegate.updateCallbackCalled == false);
445
    REQUIRE(delegate.deleteCallbackCalled == false);
446
    REQUIRE(delegate.dev.has_value());
447
    REQUIRE(delegate.dev.value() == devPtr);
448
449
    // ADVANCE NOW TIME to just before expiry
450
    dpt.seconds += ctx.getSensorConfiguration().peripheralCleanInterval.seconds() - 1;
451
    long secondDeviceAppearedAt = dpt.seconds;
452
453
    // add in a second device via the payload, not target identifier
454
    herald::datatype::PayloadData payload(std::byte(0x1f),6);
455
    herald::ble::BLEDevice& devPtr2 = db.device(payload);
456
    REQUIRE(db.size() == 2);
457
    REQUIRE(delegate.createCallbackCalled == true);
458
    REQUIRE(delegate.updateCallbackCalled == false);
459
    REQUIRE(delegate.deleteCallbackCalled == false);
460
    REQUIRE(delegate.dev.has_value());
461
    REQUIRE(delegate.dev.value() == devPtr2);
462
463
    // ADVANCE NOW TIME BEYOND LIMIT FOR FIRST DEVICE
464
    dpt.seconds += 2; // 1 second past expiry
465
    
466
    // Force DB cache re-evaluation
467
    std::vector<herald::engine::Activity> acts = coord.requiredActivities();
468
    
469
    REQUIRE(db.size() == 1);
470
    REQUIRE(delegate.createCallbackCalled == true);
471
    REQUIRE(delegate.updateCallbackCalled == false);
472
    REQUIRE(delegate.deleteCallbackCalled == true);
473
    REQUIRE(delegate.dev.has_value());
474
    REQUIRE(delegate.dev.value() == devPtr);
475
476
    // update the second devices attribute
477
    devPtr->rssi(herald::datatype::RSSI{14});
478
    REQUIRE(db.size() == 1);
479
    REQUIRE(delegate.createCallbackCalled == true);
480
    REQUIRE(delegate.updateCallbackCalled == true);
481
    REQUIRE(delegate.deleteCallbackCalled == true);
482
    REQUIRE(delegate.dev.has_value());
483
    REQUIRE(delegate.dev.value() == devPtr2);
484
485
    // Advance by just under expiry time from its appearance
486
    dpt.seconds = secondDeviceAppearedAt + ctx.getSensorConfiguration().peripheralCleanInterval.seconds() - 1;
487
488
    // Force DB cache re-evaluation
489
    acts = coord.requiredActivities();
490
491
    REQUIRE(db.size() == 1);
492
    REQUIRE(delegate.createCallbackCalled == true);
493
    REQUIRE(delegate.updateCallbackCalled == true);
494
    REQUIRE(delegate.deleteCallbackCalled == true);
495
    REQUIRE(delegate.dev.has_value());
496
    REQUIRE(delegate.dev.value() == devPtr2);
497
498
    // Now go to just past this time
499
    dpt.seconds += 2;
500
    
501
    // Force DB cache re-evaluation
502
    acts = coord.requiredActivities();
503
504
    REQUIRE(db.size() == 0);
505
    REQUIRE(delegate.createCallbackCalled == true);
506
    REQUIRE(delegate.updateCallbackCalled == true);
507
    REQUIRE(delegate.deleteCallbackCalled == true);
508
509
  }
510
}
511
512
*/