Wyatt  1.0.1
test_main.cpp
1 
5 #include <SimpleIteratorCommand.h>
6 #include <Communicator.h>
7 #include "../include/CommandManager.h"
8 #include "../catch/catch.hpp"
9 #include "sensors/IRangeFinderSensor.h"
10 #include "sensors/SensorManager.h"
11 #include "hardwareinterface/MotorAdapter.h"
12 #include "sensors/EncoderSensor.h"
13 #include "exceptions/DataSizeException.h"
14 #include <unistd.h>
15 #include "../include/hardwareinterface/EncoderAdapter.h"
16 
17 /* MOCKS */
18 #include "mocks/include/MockIRRangeFinderSensor.h"
19 #include "mocks/include/MockSensorManager.h"
20 #include "mocks/include/MockHardwareInterface.h"
21 #include "mocks/include/MockIRRangeFinderSensorMessage.h"
22 #include "mocks/include/SimpleIteratorCommand.h"
23 
24 
25 TEST_CASE("Command subsystem tests", "[CommandManager]") {
26 
27  SECTION("Command manager can be killed.") {
28  CommandManager *commandManager = new CommandManager();
29  REQUIRE(commandManager->kill() == 0);
30  delete commandManager;
31  }
32 
33  SECTION("Simple commands run to completion.") {
34  CommandManager *commandManager1 = new CommandManager();
37  commandManager1->runCommand(sc1);
38  commandManager1->runCommand(sc2);
39  REQUIRE(commandManager1->inFlight() == 2);
40  while (!sc1->isFinished() && !sc2->isFinished()) {}
41  REQUIRE(sc1->getCount() == 10);
42  REQUIRE(sc2->getCount() == 20);
43  REQUIRE(commandManager1->inFlight() == 0);
44  commandManager1->kill();
45  delete commandManager1;
46  delete sc1;
47  delete sc2;
48  }
49 
50  SECTION("Commands can be canceled.") {
51  CommandManager *commandManager2 = new CommandManager();
53  commandManager2->runCommand(sc3);
54  commandManager2->cancel(sc3);
55  while (!sc3->isFinished()) {}
56  REQUIRE(sc3->getCount() != 1000);
60  commandManager2->runCommand(sc4);
61  commandManager2->runCommand(sc5);
62  commandManager2->runCommand(sc6);
63  commandManager2->cancelAll();
64  while (!sc4->isFinished() && !sc5->isFinished() && !sc6->isFinished()) {}
65  REQUIRE(sc4->getCount() != 1000);
66  REQUIRE(sc5->getCount() != 2000);
67  REQUIRE(sc6->getCount() != 3000);
68  commandManager2->kill();
69  delete commandManager2;
70  delete sc3;
71  delete sc4;
72  delete sc5;
73  delete sc6;
74  }
75 }
76 
77 TEST_CASE("ISensorManager tests", "[ISensorManager]") {
78 
79  ISensorManager* sensorManager = new SensorManager();
80 
81  SECTION("Adding hardware twice results in exception.") {
82  Hardware mockHardware = H_LEFT_MOTOR;
83  ISensor* mockSensor = new MockIRRangeFinderSensor();
84 
85  sensorManager->addSensor(mockHardware, mockSensor);
86  REQUIRE_THROWS_AS(
87  sensorManager->addSensor(mockHardware, mockSensor),
89  );
90  }
91 
92  SECTION("Updating non-existent hardware results in exception") {
93  int data = FULL_FORWARD;
94  MotorMessage* msg = new MotorMessage(H_LEFT_MOTOR, data);
95  std::list<IMessage*>* messages = new std::list<IMessage*>;
96  messages->push_back(msg);
97 
98  REQUIRE_THROWS_AS(
99  sensorManager->updateSensors(messages),
101  );
102  }
103 
104  SECTION("Updates sensors correctly") {
105  Hardware mockHardware = {255, 1};
107  sensorManager->addSensor(mockHardware, mockSensor);
108 
109  std::string data = "255";
110  IMessage* msg = new MockIRRangeFinderSensorMessage(mockHardware, data);
111  std::list<IMessage*>* messages = new std::list<IMessage*>;
112  messages->push_back(msg);
113 
114  sensorManager->updateSensors(messages);
115 
116  REQUIRE(mockSensor->getData() == data);
117  }
118 
119  SECTION("Destructor") {
120  delete sensorManager;
121  }
122 }
123 
124 TEST_CASE("Communicator Tests", "[Communicator]") {
125 
126  /* Initialize object */
127  MockSensorManager* mockSensorManager = new MockSensorManager();
128  Communicator* comm = new Communicator(mockSensorManager);
129 
130  SECTION("Test queuing message for single hardware interface") {
131 
132  Hardware mockHardware = {255, sizeof(int)};
133  MockHardwareInterface* mockHardwareInterface = new MockHardwareInterface();
134  std::list<IMessage*>* readMessages = new std::list<IMessage*>;
135  mockHardwareInterface->setReadMessages(readMessages);
136 
137  /* Register hardware */
138  comm->registerHardware(mockHardware, mockHardwareInterface);
139 
140  /* Compose a mock message */
141  int mockData = FULL_FORWARD;
142  IMessage* mockMessage = new MotorMessage(mockHardware, mockData);
143 
144  /* Queue message and wait for it to be sent */
145  comm->queueMessage(mockMessage);
146  comm->start();
147  usleep(100000);
148  comm->signal(1);
149  comm->join();
150  REQUIRE(mockHardwareInterface->getWriteMessages()->size() == 1);
151  REQUIRE(mockHardwareInterface->getWriteMessages()->front() == mockMessage);
152  }
153 
154  SECTION("Test queuing messages for multiple hardware interfaces") {
155  Hardware mockHardware1 = {255, sizeof(int)};
156  Hardware mockHardware2 = {254, sizeof(int)};
157 
158  MockHardwareInterface* mockHardwareInterface1 = new MockHardwareInterface();
159  MockHardwareInterface* mockHardwareInterface2 = new MockHardwareInterface();
160 
161  /* Register hardware */
162  comm->registerHardware(mockHardware1, mockHardwareInterface1);
163  comm->registerHardware(mockHardware2, mockHardwareInterface2);
164 
165  /* Compose a mock message */
166  int data1 = FULL_FORWARD, data2 = FULL_BACKWARD;
167  IMessage* mockMessage1 = new MotorMessage(mockHardware1, data1);
168  IMessage* mockMessage2 = new MotorMessage(mockHardware2, data2);
169 
170  /* Queue message and wait for it to be sent */
171  comm->queueMessage(mockMessage1);
172  comm->queueMessage(mockMessage2);
173  comm->start();
174  usleep(100000);
175  comm->signal(1);
176  comm->join();
177 
178  REQUIRE(mockHardwareInterface1->getWriteMessages()->size() == 1);
179  REQUIRE(mockHardwareInterface2->getWriteMessages()->size() == 1);
180 
181  REQUIRE(mockHardwareInterface1->getWriteMessages()->front() == mockMessage1);
182  REQUIRE(mockHardwareInterface2->getWriteMessages()->front() == mockMessage2);
183  }
184 
185  SECTION("Test receiving message from single hardware interface") {
186  Hardware mockHardware = {255, sizeof(int)};
187  MockHardwareInterface* mockHardwareInterface = new MockHardwareInterface();
188 
189  /* Register hardware */
190  comm->registerHardware(mockHardware, mockHardwareInterface);
191 
192  /* Compose a mock message */
193  int data = FULL_FORWARD;
194  IMessage* mockMessage = new MotorMessage(mockHardware, data);
195  std::list<IMessage*>* messages = new std::list<IMessage*>;
196  messages->push_back(mockMessage);
197  mockHardwareInterface->setReadMessages(messages);
198 
199  /* Wait for it to be read */
200  comm->start();
201  usleep(100000);
202  comm->signal(1);
203  comm->join();
204 
205  REQUIRE(mockSensorManager->updateMessages->size() == 1);
206  REQUIRE(mockSensorManager->updateMessages->front() == mockMessage);
207  }
208 
209  SECTION("Test receiving messages from multiple hardware interfaces") {
210  Hardware mockHardware1 = {255, sizeof(int)};
211  Hardware mockHardware2 = {254, sizeof(int)};
212  MockHardwareInterface* mockHardwareInterface1 = new MockHardwareInterface();
213  MockHardwareInterface* mockHardwareInterface2 = new MockHardwareInterface();
214 
215  /* Register hardware */
216  comm->registerHardware(mockHardware1, mockHardwareInterface1);
217  comm->registerHardware(mockHardware2, mockHardwareInterface2);
218 
219  /* Compose a mock message */
220  int data1 = FULL_FORWARD, data2 = FULL_BACKWARD;
221  IMessage* mockMessage1 = new MotorMessage(mockHardware1, data1);
222  IMessage* mockMessage2 = new MotorMessage(mockHardware2, data2);
223  std::list<IMessage*>* messages1 = new std::list<IMessage*>;
224  messages1->push_back(mockMessage1);
225  std::list<IMessage*>* messages2 = new std::list<IMessage*>;
226  messages2->push_back(mockMessage2);
227 
228  mockHardwareInterface1->setReadMessages(messages1);
229  mockHardwareInterface2->setReadMessages(messages2);
230 
231  /* Wait for it to be read */
232  comm->start();
233  usleep(100000);
234  comm->signal(1);
235  comm->join();
236 
237  REQUIRE(mockSensorManager->updateMessages->size() == 2);
238 
239  REQUIRE(mockSensorManager->updateMessages->front() == mockMessage1);
240  mockSensorManager->updateMessages->pop_front();
241  REQUIRE(mockSensorManager->updateMessages->front() == mockMessage2);
242  }
243 
244  SECTION("Test throws duplicate hardware exception when hardware with the same address is registered more than once.") {
245  Hardware mockHardware1 = {255, sizeof(int)};
246  Hardware mockHardware2 = {255, sizeof(int)};
247  MockHardwareInterface* mockHardwareInterface = new MockHardwareInterface();
248 
249  /* Register hardware */
250  comm->registerHardware(mockHardware1, mockHardwareInterface);
251 
252  REQUIRE_THROWS_AS(
253  comm->registerHardware(mockHardware2, mockHardwareInterface),
255  );
256  }
257 
258  SECTION("Test queue list of messages sent to single interface") {
259  Hardware mockHardware = {255, sizeof(int)};
260  MockHardwareInterface* mockHardwareInterface = new MockHardwareInterface();
261 
262  /* Register hardware */
263  comm->registerHardware(mockHardware, mockHardwareInterface);
264 
265  /* Compose two mock messages */
266  int data1 = FULL_FORWARD, data2 = FULL_BACKWARD;
267  IMessage* mockMessage1 = new MotorMessage(mockHardware, data1);
268  IMessage* mockMessage2 = new MotorMessage(mockHardware, data2);
269  std::list<IMessage*>* messages = new std::list<IMessage*>;
270  messages->push_back(mockMessage1);
271  messages->push_back(mockMessage2);
272 
273  /* Queue message and wait for them to be sent */
274  comm->queueMessage(messages);
275  comm->start();
276  usleep(100000);
277  comm->signal(1);
278  comm->join();
279 
280 // REQUIRE(mockHardwareInterface->getWriteMessages()->size() == 2);
281 //
282 // REQUIRE(mockHardwareInterface->getWriteMessages()->front() == mockMessage1);
283 // mockHardwareInterface->getWriteMessages()->pop_front();
284 // REQUIRE(mockHardwareInterface->getWriteMessages()->front() == mockMessage2);
285  }
286 
287  SECTION("Test queue list of messages sent to multiple interfaces") {
288  Hardware mockHardware1 = {255, sizeof(int)};
289  Hardware mockHardware2 = {254, sizeof(int)};
290  MockHardwareInterface* mockHardwareInterface1 = new MockHardwareInterface();
291  MockHardwareInterface* mockHardwareInterface2 = new MockHardwareInterface();
292 
293  /* Register hardware */
294  comm->registerHardware(mockHardware1, mockHardwareInterface1);
295  comm->registerHardware(mockHardware2, mockHardwareInterface2);
296 
297  /* Compose two mock messages */
298  int data1 = FULL_FORWARD, data2 = FULL_BACKWARD;
299  IMessage* mockMessage1 = new MotorMessage(mockHardware1, data1);
300  IMessage* mockMessage2 = new MotorMessage(mockHardware2, data2);
301  std::list<IMessage*>* messages = new std::list<IMessage*>;
302  messages->push_back(mockMessage1);
303  messages->push_back(mockMessage2);
304 
305  /* Queue message and wait for them to be sent */
306  comm->queueMessage(messages);
307  comm->start();
308  usleep(100000);
309  comm->signal(1);
310  comm->join();
311 
312  REQUIRE(mockHardwareInterface1->getWriteMessages()->size() == 1);
313  REQUIRE(mockHardwareInterface2->getWriteMessages()->size() == 1);
314 
315  REQUIRE(mockHardwareInterface1->getWriteMessages()->front() == mockMessage1);
316  REQUIRE(mockHardwareInterface2->getWriteMessages()->front() == mockMessage2);
317  }
318 
319  SECTION("Test queuing multiple messages for different hardware sent to the same hardware interface") {
320  Hardware mockHardware1 = {255, sizeof(int)};
321  Hardware mockHardware2 = {254, sizeof(int)};
322  MockHardwareInterface* mockHardwareInterface = new MockHardwareInterface();
323 
324  /* Register hardware */
325  comm->registerHardware(mockHardware1, mockHardwareInterface);
326  comm->registerHardware(mockHardware2, mockHardwareInterface);
327 
328  /* Compose two mock messages */
329  int data1 = FULL_FORWARD, data2 = FULL_BACKWARD;
330  IMessage* mockMessage1 = new MotorMessage(mockHardware1, data1);
331  IMessage* mockMessage2 = new MotorMessage(mockHardware2, data2);
332  std::list<IMessage*>* messages = new std::list<IMessage*>;
333  messages->push_back(mockMessage1);
334  messages->push_back(mockMessage2);
335 
336  /* Queue message and wait for them to be sent */
337  comm->queueMessage(messages);
338  comm->start();
339  usleep(100000);
340  comm->signal(1);
341  comm->join();
342 
343 // REQUIRE(mockHardwareInterface->getWriteMessages()->size() == 2);
344 
345 // REQUIRE(mockHardwareInterface->getWriteMessages()->front() == mockMessage1);
346 // mockHardwareInterface->getWriteMessages()->pop_front();
347 // REQUIRE(mockHardwareInterface->getWriteMessages()->front() == mockMessage2);
348  }
349 
350  SECTION("Destructor") {
351  delete comm;
352  }
353 
354 }
355 
356 TEST_CASE("MotorMessage Tests", "[MotorMessage]") {
357 
358  unsigned char address = 255;
359  Hardware mockHardware = {address, sizeof(int)};
360  int mockData = FULL_FORWARD;
361  MotorMessage* msg = new MotorMessage(mockHardware, mockData);
362 
363  SECTION("GetHardware returns proper hardware") {
364  REQUIRE(msg->getHardware() == mockHardware);
365  }
366 
367  SECTION("GetData returns proper data") {
368  REQUIRE(msg->getData() == mockData);
369  }
370 
371  SECTION("Not enough data throws MessageLengthException") {
372  // Expect 5 bytes, given 4
373  Hardware mockHardware = {address, 2};
374 
375  REQUIRE_THROWS_AS(
376  new MotorMessage(mockHardware, mockData),
378  );
379  }
380 
381  SECTION("Too much data throws MessageLengthException") {
382  // Expect 0 bytes, given 4
383  Hardware mockHardware = {address, 0};
384 
385  REQUIRE_THROWS_AS(
386  new MotorMessage(mockHardware, mockData),
388  );
389  }
390 
391  SECTION("Serialize to proper string") {
392  std::string serial;
393  serial.append(1, address);
394  serial.append((char*)(&mockData), sizeof(int));
395 
396  REQUIRE(msg->serialize() == serial);
397  int unserializeData = *((int*)(serial.c_str() + sizeof(char)));
398  REQUIRE(unserializeData == mockData);
399  }
400 
401  SECTION("Data too large throws DataSizeException") {
402  REQUIRE_THROWS_AS(
403  new MotorMessage(mockHardware, FULL_FORWARD + 1),
405  );
406  }
407 
408  SECTION("Data too small throws DataSizeException") {
409  REQUIRE_THROWS_AS(
410  new MotorMessage(mockHardware, FULL_BACKWARD - 1),
412  );
413  }
414 
415  SECTION("Destructor") {
416  delete msg;
417  }
418 
419 }
420 
421 TEST_CASE("EncoderMessage Tests", "[EncoderMessage]") {
422  unsigned char address = 255;
423  Hardware mockHardware = {address, sizeof(double)};
424  double mockData = 128.0;
425  EncoderMessage* msg = new EncoderMessage(mockHardware, mockData);
426 
427  SECTION("GetHardware returns proper hardware") {
428  REQUIRE(msg->getHardware() == mockHardware);
429  }
430 
431  SECTION("GetData returns proper data") {
432  REQUIRE(msg->getData() == mockData);
433  }
434 
435  SECTION("Not enough data throws MessageLengthException") {
436  // Expect 10 bytes, given 8
437  Hardware mockHardware = {address, 10};
438 
439  REQUIRE_THROWS_AS(
440  new EncoderMessage(mockHardware, mockData),
442  );
443  }
444 
445  SECTION("Too much data throws MessageLengthException") {
446  // Expect 0 bytes, given 1
447  Hardware mockHardware = {address, 0};
448 
449  REQUIRE_THROWS_AS(
450  new EncoderMessage(mockHardware, mockData),
452  );
453  }
454 
455  SECTION("Serialize to proper string") {
456  std::string serial;
457  serial.append(1, address);
458  serial.append((char*)(&mockData), sizeof(double));
459 
460  // Serialized data is expected
461  REQUIRE(msg->serialize() == serial);
462 
463  // Unserialized data is unchanged
464  // Need to move pointer forward 1 byte to skip over the address
465  double data = *((double*)(serial.c_str() + sizeof(char)));
466  REQUIRE(data == mockData);
467  }
468 
469 
470  SECTION("Destructor") {
471  delete msg;
472  }
473 }
474 
475 TEST_CASE("MotorAdapter Tests", "[MotorAdapter]") {
476 
477  int forwardPin = 1, backwardPin = 2;
478  AdafruitPWMServoHat* m_pwmHat = new AdafruitPWMServoHat();
479  MotorAdapter* adapter = new MotorAdapter(m_pwmHat, forwardPin, backwardPin);
480  Hardware hardware = H_RIGHT_MOTOR;
481 
482  SECTION("Read returns empty list. Cannot read motors.") {
483  REQUIRE(adapter->read()->size() == 0);
484  }
485 
486  SECTION("Drive the motor full backwards") {
487  int speed = FULL_BACKWARD;
488  IMessage* msg = new MotorMessage(hardware, speed);
489  adapter->write(msg);
490 
491  // TODO: Check that the appropriate register has been written
492  }
493 
494  SECTION("Drive the motor full forwards") {
495  int speed = FULL_FORWARD;
496  IMessage* msg = new MotorMessage(hardware, speed);
497  adapter->write(msg);
498 
499  // TODO: Check that the appropriate register has been written
500  }
501 
502  SECTION("MismatchedMessageException thrown when message of wrong type is passed in") {
503  IMessage* msg = new EncoderMessage(H_RIGHT_ENCODER, 10.0);
504 
505  REQUIRE_THROWS_AS(
506  adapter->write(msg),
508  );
509  }
510 
511  SECTION("Destructor") {
512  delete adapter;
513  }
514 
515 
516 }
517 
518 TEST_CASE("EncoderAdapter Tests", "[EncoderAdapter]") {
519 
520  Hardware mockHardware = {255, sizeof(double)};
521  int ticksPerRev = 100;
522  int channelA = 0, channelB = 1;
523  EncoderAdapter* adapter = new EncoderAdapter(channelA, channelB, ticksPerRev, mockHardware);
524 
525  SECTION("Destructor") {
526  delete adapter;
527  }
528 }
529 
530 TEST_CASE("EncoderSensor Tests", "[EncoderSensor]") {
531 
532  EncoderSensor* sensor = new EncoderSensor();
533 
534  SECTION("Sensor value updates correctly") {
535  double data = 1000;
536  IMessage* msg = new EncoderMessage(H_LEFT_ENCODER, data);
537  sensor->updateSensor(msg);
538 
539  REQUIRE(sensor->getRPM() == data);
540 
541  }
542 
543  SECTION("MismatchMessageException thrown if wrong message type sent to encoder") {
544  IMessage* msg = new MotorMessage(H_RIGHT_MOTOR, FULL_FORWARD);
545 
546  REQUIRE_THROWS_AS(
547  sensor->updateSensor(msg),
549  );
550  }
551 
552  SECTION("Destructor") {
553  delete sensor;
554  }
555 }
void write(IMessage *msg) override
virtual void updateSensors(std::list< IMessage * > *messages)=0
bool cancel(Command *command)
Hardware getHardware()
Definition: IMessage.h:30
void updateSensor(IMessage *message)
std::string serialize() override
virtual void addSensor(Hardware hardware, ISensor *sensor)=0
Definition: ISensor.h:7
void registerHardware(Hardware hardware, IHardwareInterface *interface)
void queueMessage(IMessage *message)
std::list< IMessage * > * read() override
Definition: MotorAdapter.h:45
bool runCommand(Command *command)
std::string serialize() override
bool isFinished()
Definition: Command.cpp:64
unsigned long inFlight()