-
Notifications
You must be signed in to change notification settings - Fork 3
Using Cooja Test Scripts to Automate Simulations
(The following tutorial is based on an email from Fredrik Österlind to the developer mailing list, 2009-05-18)
The easiest way to automate simulations in Cooja so that you can run multiple test is by using COOJAs Contiki test scripts. Contiki tests can be run both with and without GUI, and could, combined with a shell script, automate several test runs (for example changing parameters in the .csc simulation file).
Example: running a simple Hello world test repeatedly with different random seeds.
When in the "Create new simulation" dialog, be sure to configure for automatically generated random seeds (the checkbox right of the "Main random seed"). Every time this simulation is loaded, a new random seed will be used.
Create a mote type (use hello world or your favorite Contiki app), and add a few nodes. At this step you may typically also want to configure the radio medium, node positions...
Start the "Contiki Test Editor" plugin. There are several test scripts available (Javascripts, ends with .js), for now use this very simple script:
TIMEOUT(10000);
log.log("first simulation message at time : " + time + "\n");
while (true) {
YIELD(); /* wait for another mote output */
}
Copy and paste this script into the upper part of the test editor - this is where the javascript code goes. The lower part shows the currently active test output.
The above script is very simple: it declares a test timeout of 10 seconds. It also prints the first printf() output from any of the simulation nodes. Depending on what you want to do, perhaps such a simple script is sufficient if you only want to repeat tests with a given duration (10 seconds in this case).
Click "Activate" in the plugin, and then start the simulation. The simulation stops after ten seconds. In the lower part of the test editor plugin, you should messages indicating that the test timed out (failed).
To run this test without GUI, you should first export it: "Export as Contiki test". Follow the instructions. The test files will be saved to /tools/cooja/contiki_tests. Open a terminal and enter this directory.
To run the test once:
bash RUN_TEST mytest
mytest.log contains the test output (the lower part of the plugin when in graphical mode).
To run the test 10 times:
bash RUN_REPEATED 10 mytest
mytest6.log contains the test output of test run number 6/10.
Test scripts are written in JavaScript using Rhino The following objects are exported from the Cooja Java environment to the JavaScript environment. Using these you should be able to access any part of the Cooja.
-
se.sics.cooja.Mote mote
The Mote Mote.java -
int id
The id of the mote -
long time
The current time -
String msg
The message -
se.sics.cooja.Simulation sim
The simulation Simulation.java -
se.sics.cooja.Gui gui
The GUI Gui.java interface ScriptLog log
log(String log)
public void testOK()
public void testFailed()
-
public void generateMessage(long delay, String msg)
This generates a message after delay. This can be used to wait without having a mote to output anything. -
boolean TIMEOUT
Set to true when the script times out -
boolean SHUTDOWN
Set to true when the script is deactivated java.util.concurrent.Semaphore.Semaphore SEMAPHORE_SCRIPT
java.util.concurrent.Semaphore.Semaphore SEMAPHORE_SIM
These may not be split into multiple lines!
-
write(Mote mote, String msg)
Write to the mote's serial interface -
TIMEOUT(long time[, action])
-
time
Time until timeout -
action
Script to execute when timing out (e.g.log.log("last message: " + msg + "\n")
)
-
-
YIELD()
Wait for the next message -
WAIT_UNTIL(expr)
Yield ifexpr
is not true -
YIELD_THEN_WAIT_UNTIL(expr)
This is equivalent toYIELD(); WAIT_UNTIL(expr)
-
GENERATE_MSG(long time, String msg)
Send a message in the future. This is handy if you want to sleep a while, but continue the execution afterwards
GENERATE_MSG(2000, "sleep"); //Wait for two sec
YIELD_THEN_WAIT_UNTIL(msg.equals("sleep"));
Documentation might be buggy or the commands might have unexpected side effects:
-
SCRIPT_KILL()
Terminate the script -
SCRIPT_TIMEOUT()
Cause a timeout
This allows to write to a mote without having to get a reference by waiting for the ''mote'' variable to point to the right mote.
write(sim.getMoteWithID(1), "some string");
The interfaces must be initialized by opening the interface viewer and selecting the flash. The window can be minimized, though.
file = "Myfile.bin";
fs = mote.getFilesystem();
success = fs.insertFile(file);
sim.getSimulationTime() // us
sim.getSimulationTimeMillis() // ms
mote.getInterfaces().getButton().clickButton()
sim.setSpeedLimit(1.0);
allm = sim.getMotes();
for(var i = 0; i < allm.length; i++){
write(allm[i], "msg");
}
//import Java Package to JavaScript
importPackage(java.io);
// Use JavaScript object as an associative array
outputs = new Object();
while (true) {
//Has the output file been created.
if(! outputs[id.toString()]){
// Open log_<id>.txt for writing.
// BTW: FileWriter seems to be buffered.
outputs[id.toString()]= new FileWriter("log_" + id +".txt");
}
//Write to file.
outputs[id.toString()].write(time + " " + msg + "\n");
try{
//This is the tricky part. The Script is terminated using
// an exception. This needs to be caught.
YIELD();
} catch (e) {
//Close files.
for (var ids in outputs){
outputs[ids].close();
}
//Rethrow exception again, to end the script.
throw('test script killed');
}
}