Coverage Report

Created: 2021-08-28 18:14

D:\git\skunkworks\herald-for-cpp\herald-tests\coordinator-tests.cpp
Line
Count
Source
1
//  Copyright 2021 Herald Project Contributors
2
//  SPDX-License-Identifier: Apache-2.0
3
//
4
5
#include <memory>
6
#include <vector>
7
#include <optional>
8
#include <iostream>
9
10
#include "test-templates.h"
11
12
#include "catch.hpp"
13
14
#include "herald/herald.h"
15
16
/**
17
 * This set of tests uses the BLECoordinator and a Mock Herald V1 Protocol provider
18
 * to test the iteration functionality of the core Coordinator class
19
 */
20
21
template <typename CoordProvT>
22
class MockSensor {
23
public:
24
1
  MockSensor(CoordProvT& provider) : cp(provider) {}
25
  ~MockSensor() = default;
26
27
  void start() {}
28
  void stop() {}
29
30
  /** For complex sensor coordination support, if required - Since v1.2-beta3 **/
31
1
  std::optional<std::reference_wrapper<herald::engine::CoordinationProvider>> coordinationProvider() {
32
1
    return std::optional<std::reference_wrapper<herald::engine::CoordinationProvider>>(cp);
33
1
  }
34
35
  CoordProvT& cp;
36
};
37
38
template <typename ContextT, typename BLEDBT>
39
class NoOpHeraldV1ProtocolProvider : public herald::ble::HeraldProtocolV1Provider {
40
public:
41
  NoOpHeraldV1ProtocolProvider(ContextT& context,BLEDBT& bledb)
42
    : ctx(context) 
43
      HLOGGERINIT(ctx,"TESTS","NoOpProvider")
44
  {}
45
  ~NoOpHeraldV1ProtocolProvider() = default;
46
  
47
  // FOR PLATFORMS WITH STD::ASYNC:-
48
  // void openConnection(const herald::datatype::TargetIdentifier& toTarget,
49
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
50
  //   connCallback(toTarget, true);
51
  // }
52
53
  // void closeConnection(const herald::datatype::TargetIdentifier& toTarget,
54
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
55
  //   connCallback(toTarget,false);
56
  // }
57
58
  // void serviceDiscovery(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
59
  //   HTDBG("serviceDiscovery called");
60
  //   cb(act,{});
61
  // }
62
63
  // void readPayload(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
64
  //   HTDBG("readPayload called");
65
  //   cb(act,{});
66
  // }
67
68
  // void immediateSend(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
69
  //   HTDBG("immediateSend called");
70
  //   cb(act,{});
71
  // }
72
73
  // void immediateSendAll(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
74
  //   HTDBG("immediateSendAll called");
75
  //   cb(act,{});
76
  // }
77
78
  // FOR PLATFORMS WITHOUT STD::SYNC
79
  bool openConnection(const herald::datatype::TargetIdentifier& toTarget) override {
80
    return true;
81
  }
82
  bool closeConnection(const herald::datatype::TargetIdentifier& toTarget) override {
83
    return false;
84
  }
85
  
86
  void restartScanningAndAdvertising() override {}
87
88
  std::optional<herald::engine::Activity> serviceDiscovery(herald::engine::Activity act) override {
89
    HTDBG("serviceDiscovery called");
90
    return {};
91
  }
92
93
  std::optional<herald::engine::Activity> readPayload(herald::engine::Activity act) override {
94
    HTDBG("readPayload called");
95
    return {};
96
  }
97
98
  // std::optional<herald::engine::Activity> immediateSend(herald::engine::Activity act) override {
99
  //   HTDBG("immediateSend called");
100
  //   return {};
101
  // }
102
103
  // std::optional<herald::engine::Activity> immediateSendAll(herald::engine::Activity act) override {
104
  //   HTDBG("immediateSendAll called");
105
  //   return {};
106
  // }
107
108
  ContextT& ctx;
109
  HLOGGER(ContextT);
110
};
111
112
template <typename ContextT, typename BLEDBT>
113
class MockHeraldV1ProtocolProvider : public herald::ble::HeraldProtocolV1Provider {
114
public:
115
  MockHeraldV1ProtocolProvider(ContextT& context,BLEDBT& bledb)
116
    : ctx(context), db(bledb), hasIdentifiedOs(false), lastDeviceOS(), hasReadPayload(false), lastDevicePayload()
117
      // ,hasImmediateSend(false), lastImmediateSend(), hasImmediateSendAll(false), lastImmediateSendAll()
118
      HLOGGERINIT(ctx,"TESTS","MockHeraldV1ProtocolProvider")
119
1
  {}
120
1
  ~MockHeraldV1ProtocolProvider() = default;
121
  
122
  // FOR PLATFORMS WITH STD::ASYNC:-
123
  // void openConnection(const herald::datatype::TargetIdentifier& toTarget,
124
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
125
  //   connCallback(toTarget, true);
126
  // }
127
  // void closeConnection(const herald::datatype::TargetIdentifier& toTarget,
128
  //   const herald::ble::HeraldConnectionCallback& connCallback) override {
129
  //   connCallback(toTarget,false);
130
  // }
131
132
  // void serviceDiscovery(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
133
  //   HTDBG("serviceDiscovery called");
134
  //   auto device = db->device(std::get<1>(act.prerequisites.front()).value());
135
  //   device->operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
136
  //   hasIdentifiedOs = true;
137
  //   lastDeviceOS = device->identifier();
138
  //   cb(act,{});
139
  // }
140
141
  // void readPayload(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
142
  //   HTDBG("readPayload called");
143
  //   auto device = db->device(std::get<1>(act.prerequisites.front()).value());
144
  //   device->payloadData(herald::datatype::Data(std::byte(0x02),2));
145
  //   hasReadPayload = true;
146
  //   lastDevicePayload = device->identifier();
147
  //   cb(act,{});
148
  // }
149
150
  // void immediateSend(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
151
  //   HTDBG("immediateSend called");
152
  //   auto device = db->device(std::get<1>(act.prerequisites.front()).value());
153
  //   hasImmediateSend = true;
154
  //   lastImmediateSend = device->identifier();
155
  //   device->clearImmediateSendData();
156
  //   cb(act,{});
157
  // }
158
159
  // void immediateSendAll(herald::engine::Activity act, herald::engine::CompletionCallback cb) override {
160
  //   HTDBG("immediateSendAll called");
161
  //   auto device = db->device(std::get<1>(act.prerequisites.front()).value());
162
  //   hasImmediateSendAll = true;
163
  //   lastImmediateSendAll = device->identifier();
164
  //   device->clearImmediateSendData();
165
  //   cb(act,{});
166
  // }
167
168
  // FOR PLATFORMS WITHOUT:-
169
2
  bool openConnection(const herald::datatype::TargetIdentifier& toTarget) override {
170
2
    return true;
171
2
  }
172
1
  bool closeConnection(const herald::datatype::TargetIdentifier& toTarget) override {
173
1
    return false;
174
1
  }
175
  
176
2
  void restartScanningAndAdvertising() override {}
177
178
1
  std::optional<herald::engine::Activity> serviceDiscovery(herald::engine::Activity act) override {
179
1
    HTDBG("serviceDiscovery called");
180
1
    auto& device = db.device(std::get<1>(act.prerequisites.front()).value());
181
1
    std::vector<herald::datatype::UUID> heraldServiceList;
182
1
    herald::ble::BLESensorConfiguration cfg;
183
1
    heraldServiceList.push_back(cfg.serviceUUID);
184
1
    device.services(heraldServiceList);
185
1
    device.operatingSystem(herald::ble::BLEDeviceOperatingSystem::android);
186
1
    hasIdentifiedOs = true;
187
1
    lastDeviceOS = device.identifier();
188
1
    return {};
189
1
  }
190
191
1
  std::optional<herald::engine::Activity> readPayload(herald::engine::Activity act) override {
192
1
    HTDBG("readPayload called");
193
1
    auto& device = db.device(std::get<1>(act.prerequisites.front()).value());
194
1
    device.payloadData(herald::datatype::Data(std::byte(0x02),2));
195
1
    hasReadPayload = true;
196
1
    lastDevicePayload = device.identifier();
197
1
    return {};
198
1
  }
199
200
  // std::optional<herald::engine::Activity> immediateSend(herald::engine::Activity act) override {
201
  //   HTDBG("immediateSend called");
202
  //   auto& device = db.device(std::get<1>(act.prerequisites.front()).value());
203
  //   hasImmediateSend = true;
204
  //   lastImmediateSend = device.identifier();
205
  //   device.clearImmediateSendData();
206
  //   return {};
207
  // }
208
209
  // std::optional<herald::engine::Activity> immediateSendAll(herald::engine::Activity act) override {
210
  //   HTDBG("immediateSendAll called");
211
  //   auto& device = db.device(std::get<1>(act.prerequisites.front()).value());
212
  //   hasImmediateSendAll = true;
213
  //   lastImmediateSendAll = device.identifier();
214
  //   device.clearImmediateSendData();
215
  //   return {};
216
  // }
217
218
  ContextT& ctx;
219
  BLEDBT& db;
220
  
221
  bool hasIdentifiedOs;
222
  std::optional<herald::datatype::TargetIdentifier> lastDeviceOS;
223
  
224
  bool hasReadPayload;
225
  std::optional<herald::datatype::TargetIdentifier> lastDevicePayload;
226
227
  // bool hasImmediateSend;
228
  // std::optional<herald::datatype::TargetIdentifier> lastImmediateSend;
229
230
  // bool hasImmediateSendAll;
231
  // std::optional<herald::datatype::TargetIdentifier> lastImmediateSendAll;
232
233
  HLOGGER(ContextT);
234
};
235
236
237
238
239
1
TEST_CASE("coordinator-complex-iterations", "[coordinator][iterations][complex]") {
240
1
  // create our BLE coordinator
241
1
  DummyLoggingSink dls;
242
1
  DummyBluetoothStateManager dbsm;
243
1
  herald::DefaultPlatformType dpt;
244
1
  herald::Context ctx(dpt,dls,dbsm); // default context include
245
1
  auto serviceUUID = herald::datatype::UUID::fromString("428132af-4746-42d3-801e-4572d65bfd9b");
246
1
  // INFO("Service UUID " << std::string(serviceUUID));
247
1
  REQUIRE(ctx.getSensorConfiguration().serviceUUID == serviceUUID);
248
1
  auto blankUUID = herald::datatype::UUID::fromString("");
249
1
  // INFO("Blank UUID " << std::string(blankUUID));
250
1
  REQUIRE(ctx.getSensorConfiguration().serviceUUID != blankUUID);
251
1
  using CT = typename herald::Context<herald::DefaultPlatformType,DummyLoggingSink,DummyBluetoothStateManager>;
252
1
  herald::ble::ConcreteBLEDatabase db(ctx);
253
1
  MockHeraldV1ProtocolProvider pp(ctx,db);
254
1
  herald::ble::HeraldProtocolBLECoordinationProvider coord(ctx,db,pp);
255
1
  using CPT = herald::ble::HeraldProtocolBLECoordinationProvider<
256
1
    CT,
257
1
    herald::ble::ConcreteBLEDatabase<CT>,
258
1
    MockHeraldV1ProtocolProvider<CT,herald::ble::ConcreteBLEDatabase<CT>>
259
1
  >;
260
1
261
1
  // Mock Sensor
262
1
  MockSensor<CPT> mockSensor(coord);
263
1
264
1
  // register ble coordinator
265
1
  herald::engine::Coordinator<CT> c(ctx);
266
1
  c.add(mockSensor); // registers the BLE coordinator
267
1
  c.start();
268
1
269
1
  // section wide data definitions
270
1
  herald::datatype::Data devMac1(std::byte(0x1d),6);
271
1
  herald::datatype::TargetIdentifier device1(devMac1);
272
1
273
1
  herald::datatype::Data devMac2(std::byte(0x1f),6);
274
1
  herald::datatype::TargetIdentifier device2(devMac2);
275
1
276
1
  herald::datatype::Data devMac3(std::byte(0x09),6);
277
1
  herald::datatype::TargetIdentifier device3(devMac3);
278
1
  
279
1
  SECTION("blecoordinator-complex-iterations-01-device1") {
280
1
    herald::ble::BLEDevice& devPtr1 = db.device(device1);
281
1
282
1
    // Now perform one iteration
283
1
    c.iteration(); // should call serviceDiscovery
284
1
    
285
1
    // check provider used
286
1
    REQUIRE(pp.hasIdentifiedOs == true);
287
1
    REQUIRE(pp.lastDeviceOS == device1);
288
1
    REQUIRE(pp.hasReadPayload == false);
289
1
    // REQUIRE(pp.hasImmediateSend == false);
290
1
    // REQUIRE(pp.hasImmediateSendAll == false);
291
1
292
1
  // second iteration should read payload
293
1
    c.iteration();
294
1
    REQUIRE(pp.hasIdentifiedOs == true);
295
1
    REQUIRE(pp.lastDeviceOS == device1);
296
1
    REQUIRE(pp.hasReadPayload == true);
297
1
    REQUIRE(pp.lastDevicePayload == device1);
298
1
    // REQUIRE(pp.hasImmediateSend == false);
299
1
    // REQUIRE(pp.hasImmediateSendAll == false);
300
1
301
1
    // TODO MARK DEVICE FOR IMMEDIATE SEND IN PROVIDER
302
1
    // devPtr1.immediateSendData(herald::datatype::Data(std::byte(0x09),4));
303
1
304
1
    // Now perform one iteration
305
1
    c.iteration();
306
1
    
307
1
    // check provider used
308
1
    REQUIRE(pp.hasIdentifiedOs == true);
309
1
    REQUIRE(pp.lastDeviceOS == device1);
310
1
    REQUIRE(pp.hasReadPayload == true);
311
1
    REQUIRE(pp.lastDevicePayload == device1);
312
1
    // REQUIRE(pp.hasImmediateSend == true);
313
1
    // REQUIRE(pp.lastImmediateSend == device1);
314
1
    // REQUIRE(pp.hasImmediateSendAll == false);
315
1
316
1
    // Now perform one iteration
317
1
    c.iteration();
318
1
    
319
1
    // check provider used
320
1
    REQUIRE(pp.hasIdentifiedOs == true);
321
1
    REQUIRE(pp.lastDeviceOS == device1);
322
1
    REQUIRE(pp.hasReadPayload == true);
323
1
    REQUIRE(pp.lastDevicePayload == device1);
324
1
    // REQUIRE(pp.hasImmediateSend == true);
325
1
    // REQUIRE(pp.lastImmediateSend == device1);
326
1
    // REQUIRE(pp.hasImmediateSendAll == false);
327
1
  }
328
1
329
1
  c.stop();
330
1
}