Multi-Node Unit Testing
Multi-Node unit tests require some thinking up front about how to setup the test. Unlike isolation tests and single-node test suites, there is typically only a single test in each multi-node test suite. A multi-node test implies the radio is in use and communicating to a nearby node.
Multiple nodes in a TUnit test bed are intentionally placed close together to reduce the effects of RF issues. After all, we're testing software, not physical RF performance.
Test Basic Radio Communication
When using the radio, we need to turn it on before the test begins and turn it back off when the test is complete. To do this, access the SetUpOneTime and TearDownOneTime TestControl interfaces to turn the radio on and off.
TUnit Tip Be polite to the next test suite that runs! Always turn off your radio when your current test is complete with the TearDownOneTime interface.
Every node defined in your tunit.xml Test Run will execute SetUpOneTime before the test runs and TearDownOneTime when the test completes.
Configuration Example
MultiNodeTestC.nc example configuration file 0| configuration MultiNodeTestC { 1| } 2| 3| implementation { 4| 5| components new TestCaseC() as TestSendReceiveC; 6| 7| components MultiNodeTestP, 8| new AMSenderC(0), 9| new AMReceiverC(0), 10| ActiveMessageC; 11| 12| MultiNodeTestP.SetUpOneTime -> TestSendReceiveC.SetUpOneTime; 13| MultiNodeTestP.TearDownOneTime -> TestSendReceiveP.TearDownOneTime; 14| 15| MultiNodeTestP.TestSendReceive -> TestSendReceiveC; 16| MultiNodeTestP.AMSend -> AMSenderC; 17| MultiNodeTestP.Receive -> AMReceiverC; 18| MultiNodeTestP.SplitControl -> ActiveMessageC; 19| 20| }
Module Example
MultiNodeTestP.nc example module file 0| #include "TestCase.h" 1| 2| module MultiNodeTestP { 3| uses { 4| interface TestControl as SetUpOneTime; 5| interface TestControl as TearDownOneTime; 6| 7| interface TestCase as TestSendReceive; 8| interface AMSend; 9| interface Receive; 10| interface SplitControl; 11| } 12| } 13| 14| implementation { 15| 16| message_t myMsg; 17| 18| /***************** TestControl Events ****************/ 19| /** 20| * This event is run once by EVERY node before the test begins. 21| * We turn on the radio, and when the radio turns on it's done(). 22| */ 23| event void SetUpOneTime.run() { 24| call SplitControl.start(); 25| } 26| 27| /** 28| * This event is run once by EVERY node after the test completes. 29| * We turn off the radio, and when the radio turns off it's done(). 30| */ 31| event void TearDownOneTime.run() { 32| call SplitControl.stop(); 33| } 34| 35| /***************** SplitControl Events ****************/ 36| event void SplitControl.startDone(error_t error) { 37| call SetUpOneTime.done(); 38| } 39| 40| event void SplitControl.stopDone(error_t error) { 41| call TearDownOneTime.done(); 42| } 43| 44| /***************** Tests ****************/ 45| /** 46| * This test is executed only on the Driving Node, node 0. 47| * No Supporting Node can start a test. 48| * 49| * Since there will only be a single Supporting Node in this 50| * test, we know its address will be 1, so we send the message 51| * to address 1. 52| */ 53| event void TestSendReceive.run() { 54| error_t error; 55| error = call AMSend.send(1, &myMsg, 0); 56| 57| assertEquals("Send failed", SUCCESS, error); 58| 59| if(error) { 60| call TestSendReceive.done(); 61| } 62| } 63| 64| 65| /***************** Receive Events ****************/ 66| /** 67| * Since the Driving Node is the only node that 68| * gets to run the test and send a message, the only 69| * node that can get this Receive event is a Supporting Node. 70| */ 71| event message_t *Receive.receive(message_t *msg, void *payload, uint8_t len) { 72| assertSuccess(); 73| call TestSendReceive.done(); 74| } 75| 76| 77| /***************** AMSend Events ****************/ 78| event void AMSend.sendDone(message_t *msg, error_t error) { 79| } 80| 81| }