Merge pull request #17 from cmorty/Cooja_automation

Cooja automation related patches.
This commit is contained in:
Adam Dunkels 2012-11-13 03:59:17 -08:00
commit 6a7435e0ba
6 changed files with 182 additions and 50 deletions

View file

@ -29,22 +29,63 @@
package se.sics.cooja; package se.sics.cooja;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* COOJA Project. * COOJA Project.
* *
* @author Fredrik Osterlind * @author Fredrik Osterlind
* @author Moritz Strübe
*/ */
public class COOJAProject { public class COOJAProject {
private static Logger logger = Logger.getLogger(COOJAProject.class); private static Logger logger = Logger.getLogger(COOJAProject.class);
public static File[] sarchProjects(File folder){
return sarchProjects(folder, 3);
}
public static File[] sarchProjects(File folder, int depth){
if(depth == 0){
return null;
}
depth--;
ArrayList<File> dirs = new ArrayList<File>();
if(!folder.isDirectory()){
logger.warn("Project directorys: " + folder.getPath() + "is not a Folder" );
return null;
}
File[] files = folder.listFiles();
for(File subf : files){
if(subf.getName().charAt(0) == '.') continue;
if(subf.isDirectory()){
File[] newf = sarchProjects(subf, depth);
if(newf != null){
Collections.addAll(dirs, newf);
}
}
if(subf.getName().equals(GUI.PROJECT_CONFIG_FILENAME)){
try{
dirs.add(folder);
} catch(Exception e){
logger.error("Somthing odd happend", e);
}
}
}
return dirs.toArray(new File[0]);
}
public File dir = null; public File dir = null;
public File configFile = null; public File configFile = null;
public ProjectConfig config = null; public ProjectConfig config = null;
public COOJAProject(File dir) { public COOJAProject(File dir) {
try { try {
this.dir = dir; this.dir = dir;

View file

@ -60,13 +60,16 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.AccessControlException; import java.security.AccessControlException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Observable; import java.util.Observable;
@ -244,7 +247,8 @@ public class GUI extends Observable {
public static Properties currentExternalToolsSettings; public static Properties currentExternalToolsSettings;
private static final String externalToolsSettingNames[] = new String[] { private static final String externalToolsSettingNames[] = new String[] {
"PATH_CONTIKI", "PATH_COOJA_CORE_RELATIVE", "PATH_CONTIKI", "PATH_COOJA_CORE_RELATIVE","PATH_COOJA","PATH_APPS",
"PATH_APPSEARCH",
"PATH_MAKE", "PATH_MAKE",
"PATH_SHELL", "PATH_SHELL",
@ -424,6 +428,20 @@ public class GUI extends Observable {
} }
} }
//Scan for projects
String searchProjectDirs = getExternalToolsSetting("PATH_APPSEARCH", null);
if (searchProjectDirs != null && searchProjectDirs.length() > 0) {
String[] arr = searchProjectDirs.split(";");
for (String d : arr) {
File searchDir = restorePortablePath(new File(d));
File[] projects = COOJAProject.sarchProjects(searchDir, 3);
if(projects == null) continue;
for(File p : projects){
currentProjects.add(new COOJAProject(p));
}
}
}
/* Parse current extension configuration */ /* Parse current extension configuration */
try { try {
reparseProjectConfig(); reparseProjectConfig();
@ -2772,11 +2790,7 @@ public class GUI extends Observable {
* New value * New value
*/ */
public static void setExternalToolsSetting(String name, String newVal) { public static void setExternalToolsSetting(String name, String newVal) {
if (specifiedContikiPath != null && "PATH_CONTIKI".equals(name)) { currentExternalToolsSettings.setProperty(name, newVal);
specifiedContikiPath = newVal;
} else {
currentExternalToolsSettings.setProperty(name, newVal);
}
} }
/** /**
@ -3227,13 +3241,13 @@ public class GUI extends Observable {
logger.fatal("Error: " + e.getMessage(), e); logger.fatal("Error: " + e.getMessage(), e);
System.exit(1); System.exit(1);
} }
sim.setSpeedLimit(null);
sim.startSimulation();
} else { } else {
logger.fatal("No test editor controlling simulation, aborting"); logger.fatal("No test editor controlling simulation, aborting");
System.exit(1); System.exit(1);
} }
} }
sim.setSpeedLimit(null);
sim.startSimulation();
} else if (args.length > 0 && args[0].startsWith("-applet")) { } else if (args.length > 0 && args[0].startsWith("-applet")) {
@ -4122,52 +4136,99 @@ public class GUI extends Observable {
return file; return file;
} }
private final static String PATH_CONTIKI_IDENTIFIER = "[CONTIKI_DIR]"; private final static String[][] PATH_IDENTIFIER = {
{"[CONTIKI_DIR]","PATH_CONTIKI",""},
{"[COOJA_DIR]","PATH_COOJA","/tools/cooja"},
{"[APPS_DIR]","PATH_APPS","/tools/cooja/apps"}
};
private File createContikiRelativePath(File file) { private File createContikiRelativePath(File file) {
try { try {
File contikiPath = new File(GUI.getExternalToolsSetting("PATH_CONTIKI", null)); int elem = PATH_IDENTIFIER.length;
String contikiCanonical = contikiPath.getCanonicalPath(); File path[] = new File [elem];
String canonicals[] = new String[elem];
int match = -1;
int mlength = 0;
String fileCanonical = file.getCanonicalPath();
String fileCanonical = file.getCanonicalPath(); //No so nice, but goes along with GUI.getExternalToolsSetting
if (!fileCanonical.startsWith(contikiCanonical)) { String defp = GUI.getExternalToolsSetting("PATH_CONTIKI", null);
/* File is not in a Contiki subdirectory */
/*logger.info("File is not in a Contiki subdirectory: " + file.getAbsolutePath());*/
return null;
}
/* Replace Contiki's canonical path with Contiki identifier */
String portablePath = fileCanonical.replaceFirst(
java.util.regex.Matcher.quoteReplacement(contikiCanonical),
java.util.regex.Matcher.quoteReplacement(PATH_CONTIKI_IDENTIFIER));
File portable = new File(portablePath);
/* Verify conversion */ for(int i = 0; i < elem; i++){
File verify = restoreContikiRelativePath(portable); path[i] = new File(GUI.getExternalToolsSetting(PATH_IDENTIFIER[i][1], defp + PATH_IDENTIFIER[i][2]));
if (verify == null || !verify.exists()) { canonicals[i] = path[i].getCanonicalPath();
/* Error: did file even exist pre-conversion? */ if (fileCanonical.startsWith(canonicals[i])){
return null; if(mlength < canonicals[i].length()){
} mlength = canonicals[i].length();
match = i;
}
return portable; }
}
if(match == -1) return null;
/* Replace Contiki's canonical path with Contiki identifier */
String portablePath = fileCanonical.replaceFirst(
java.util.regex.Matcher.quoteReplacement(canonicals[match]),
java.util.regex.Matcher.quoteReplacement(PATH_IDENTIFIER[match][0]));
File portable = new File(portablePath);
/* Verify conversion */
File verify = restoreContikiRelativePath(portable);
if (verify == null || !verify.exists()) {
/* Error: did file even exist pre-conversion? */
return null;
}
return portable;
} catch (IOException e1) { } catch (IOException e1) {
/*logger.warn("Error when converting to Contiki relative path: " + e1.getMessage());*/ /*logger.warn("Error when converting to Contiki relative path: " + e1.getMessage());*/
return null; return null;
} }
} }
private File restoreContikiRelativePath(File portable) { private File restoreContikiRelativePath(File portable) {
int elem = PATH_IDENTIFIER.length;
File path = null;
String canonical = null;
try { try {
File contikiPath = new File(GUI.getExternalToolsSetting("PATH_CONTIKI", null));
String contikiCanonical = contikiPath.getCanonicalPath();
String portablePath = portable.getPath(); String portablePath = portable.getPath();
if (!portablePath.startsWith(PATH_CONTIKI_IDENTIFIER)) {
return null;
}
File absolute = new File(portablePath.replace(PATH_CONTIKI_IDENTIFIER, contikiCanonical)); int i = 0;
return absolute; //logger.info("PPATH: " + portablePath);
for(; i < elem; i++){
if (portablePath.startsWith(PATH_IDENTIFIER[i][0])) break;
}
if(i == elem) return null;
//logger.info("Found: " + PATH_IDENTIFIER[i][0]);
//No so nice, but goes along with GUI.getExternalToolsSetting
String defp = GUI.getExternalToolsSetting("PATH_CONTIKI", null);
path = new File(GUI.getExternalToolsSetting(PATH_IDENTIFIER[i][1], defp + PATH_IDENTIFIER[i][2]));
//logger.info("Config: " + PATH_IDENTIFIER[i][1] + ", " + defp + PATH_IDENTIFIER[i][2] + " = " + path.toString());
canonical = path.getCanonicalPath();
File absolute = new File(portablePath.replace(PATH_IDENTIFIER[i][0], canonical));
if(!absolute.exists()){
logger.warn("Replaced " + portable + " with " + absolute.toString() + " (default: "+ defp + PATH_IDENTIFIER[i][2] +"), but could not find it. This does not have to be an error, as the file might be created later.");
}
return absolute;
} catch (IOException e) { } catch (IOException e) {
return null; return null;
} }
} }
@ -4623,3 +4684,4 @@ public class GUI extends Observable {
}; };
} }

View file

@ -237,7 +237,7 @@ public class ProjectConfig {
public boolean appendConfigFile(File propertyFile) public boolean appendConfigFile(File propertyFile)
throws FileNotFoundException, IOException { throws FileNotFoundException, IOException {
if (!propertyFile.exists()) { if (!propertyFile.exists()) {
logger.warn("Trying to import non-existant project configuration"); logger.warn("Trying to import non-existant project configuration: " + propertyFile.toString());
return true; return true;
} }

View file

@ -59,6 +59,7 @@ public class Simulation extends Observable implements Runnable {
/*private static long EVENT_COUNTER = 0;*/ /*private static long EVENT_COUNTER = 0;*/
private Vector<Mote> motes = new Vector<Mote>(); private Vector<Mote> motes = new Vector<Mote>();
private Vector<Mote> motesUninit = new Vector<Mote>();
private Vector<MoteType> moteTypes = new Vector<MoteType>(); private Vector<MoteType> moteTypes = new Vector<MoteType>();
@ -819,6 +820,7 @@ public class Simulation extends Observable implements Runnable {
} }
motes.add(mote); motes.add(mote);
motesUninit.remove(mote);
currentRadioMedium.registerMote(mote, Simulation.this); currentRadioMedium.registerMote(mote, Simulation.this);
/* Notify mote interfaces that node was added */ /* Notify mote interfaces that node was added */
@ -838,6 +840,9 @@ public class Simulation extends Observable implements Runnable {
/* Add mote from simulation thread */ /* Add mote from simulation thread */
invokeSimulationThread(addMote); invokeSimulationThread(addMote);
} }
//Add to list of uninitialized motes
motesUninit.add(mote);
} }
/** /**
@ -868,6 +873,24 @@ public class Simulation extends Observable implements Runnable {
return null; return null;
} }
/**
* Returns uninitialised simulation mote with with given ID.
*
* @param id ID
* @return Mote or null
* @see Mote#getID()
*/
public Mote getMoteWithIDUninit(int id) {
for (Mote m: motesUninit) {
if (m.getID() == id) {
return m;
}
}
return null;
}
/** /**
* Returns number of motes in this simulation. * Returns number of motes in this simulation.
* *
@ -888,6 +911,16 @@ public class Simulation extends Observable implements Runnable {
return arr; return arr;
} }
/**
* Returns uninitialised motes
*
* @return Motes
*/
public Mote[] getMotesUninit() {
return motesUninit.toArray(new Mote[motesUninit.size()]);
}
/** /**
* Returns all mote types in simulation. * Returns all mote types in simulation.
* *
@ -1071,9 +1104,6 @@ public class Simulation extends Observable implements Runnable {
* @return True if simulation is runnable * @return True if simulation is runnable
*/ */
public boolean isRunnable() { public boolean isRunnable() {
if (motes.isEmpty()) {
return false;
}
return isRunning || hasPollRequests || eventQueue.peekFirst() != null; return isRunning || hasPollRequests || eventQueue.peekFirst() != null;
} }

View file

@ -339,6 +339,7 @@ public class LogScriptEngine {
engine.put("global", hash); engine.put("global", hash);
engine.put("sim", simulation); engine.put("sim", simulation);
engine.put("gui", simulation.getGUI()); engine.put("gui", simulation.getGUI());
engine.put("msg", new String(""));
scriptMote = new ScriptMote(); scriptMote = new ScriptMote();
engine.put("node", scriptMote); engine.put("node", scriptMote);

View file

@ -672,8 +672,6 @@ public class ScriptRunner extends VisPlugin {
} catch (Exception e) { } catch (Exception e) {
logger.fatal("Error: " + e.getMessage(), e); logger.fatal("Error: " + e.getMessage(), e);
} }
simulation.setSpeedLimit(null);
simulation.startSimulation();
} }
return true; return true;
} }