Skip to content

Using Cooja Test Scripts to Automate Simulations

pacovi edited this page Apr 24, 2014 · 7 revisions

Overview

(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.

Create new simulation

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.

Configure simulation

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...

Create a test script

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).

Activate the test

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).

Run test (repeatedly) without GUI

(This section is outdated and doesn't work, there is no "Export as Contiki test" option, see mailing list discussion at http://sourceforge.net/p/contiki/mailman/contiki-developers/thread/[email protected]/ )

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.

Background

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

Keywords

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 if expr is not true
  • YIELD_THEN_WAIT_UNTIL(expr) This is equivalent to YIELD(); 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

Tips and Tricks

Get access to a certain mote

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");

Writing to Flash (Sky,??) c

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);

Get the current simulation Time

 sim.getSimulationTime() // us
 sim.getSimulationTimeMillis() // ms

Press a button

mote.getInterfaces().getButton().clickButton()

Set simulation to real time

sim.setSpeedLimit(1.0);

Send message to all motes

 allm = sim.getMotes();
 for(var i = 0; i < allm.length; i++){
     write(allm[i], "msg"); 
 }

Write Output to separate Files

 //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');
 	}
 }
Clone this wiki locally