some bugfixes regarding timeouts in test scripts, with simplified code

This commit is contained in:
Fredrik Osterlind 2012-03-23 15:14:24 +01:00
parent a9e36b0365
commit c78b5bad5c
3 changed files with 246 additions and 225 deletions

View file

@ -34,6 +34,7 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Dialog; import java.awt.Dialog;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
@ -41,7 +42,6 @@ import java.awt.GraphicsEnvironment;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
@ -271,7 +271,7 @@ public class GUI extends Observable {
"COMMAND_DATA_START", "COMMAND_DATA_END", "COMMAND_DATA_START", "COMMAND_DATA_END",
"COMMAND_BSS_START", "COMMAND_BSS_END", "COMMAND_BSS_START", "COMMAND_BSS_END",
"COMMAND_COMMON_START", "COMMAND_COMMON_END", "COMMAND_COMMON_START", "COMMAND_COMMON_END",
"HIDE_WARNINGS" "HIDE_WARNINGS"
}; };
@ -299,7 +299,7 @@ public class GUI extends Observable {
private Vector<Plugin> startedPlugins = new Vector<Plugin>(); private Vector<Plugin> startedPlugins = new Vector<Plugin>();
private ArrayList<GUIAction> guiActions = new ArrayList<GUIAction>(); private ArrayList<GUIAction> guiActions = new ArrayList<GUIAction>();
// Platform configuration variables // Platform configuration variables
// Maintained via method reparseProjectConfig() // Maintained via method reparseProjectConfig()
private ProjectConfig projectConfig; private ProjectConfig projectConfig;
@ -380,12 +380,12 @@ public class GUI extends Observable {
quickHelpScroll = new JScrollPane(quickHelpTextPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); quickHelpScroll = new JScrollPane(quickHelpTextPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
quickHelpScroll.setPreferredSize(new Dimension(200, 0)); quickHelpScroll.setPreferredSize(new Dimension(200, 0));
quickHelpScroll.setBorder(BorderFactory.createCompoundBorder( quickHelpScroll.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.GRAY), BorderFactory.createLineBorder(Color.GRAY),
BorderFactory.createEmptyBorder(0, 3, 0, 0) BorderFactory.createEmptyBorder(0, 3, 0, 0)
)); ));
quickHelpScroll.setVisible(false); quickHelpScroll.setVisible(false);
loadQuickHelp("KEYBOARD_SHORTCUTS"); loadQuickHelp("KEYBOARD_SHORTCUTS");
// Load default and overwrite with user settings (if any) // Load default and overwrite with user settings (if any)
loadExternalToolsDefaultSettings(); loadExternalToolsDefaultSettings();
loadExternalToolsUserSettings(); loadExternalToolsUserSettings();
@ -597,7 +597,7 @@ public class GUI extends Observable {
menu.add(lastItem); menu.add(lastItem);
} }
} }
private void doLoadConfigAsync(final boolean ask, final boolean quick, final File file) { private void doLoadConfigAsync(final boolean ask, final boolean quick, final File file) {
new Thread(new Runnable() { new Thread(new Runnable() {
public void run() { public void run() {
@ -646,7 +646,7 @@ public class GUI extends Observable {
for (GUIAction a: guiActions) { for (GUIAction a: guiActions) {
a.setEnabled(a.shouldBeEnabled()); a.setEnabled(a.shouldBeEnabled());
} }
/* Mote and mote type menues */ /* Mote and mote type menues */
if (menuMoteTypeClasses != null) { if (menuMoteTypeClasses != null) {
menuMoteTypeClasses.setEnabled(getSimulation() != null); menuMoteTypeClasses.setEnabled(getSimulation() != null);
@ -655,7 +655,7 @@ public class GUI extends Observable {
menuMoteTypes.setEnabled(getSimulation() != null); menuMoteTypes.setEnabled(getSimulation() != null);
} }
} }
private JMenuBar createMenuBar() { private JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
JMenu menu; JMenu menu;
@ -673,7 +673,7 @@ public class GUI extends Observable {
guiActions.add(startStopSimulationAction); guiActions.add(startStopSimulationAction);
guiActions.add(removeAllMotesAction); guiActions.add(removeAllMotesAction);
guiActions.add(showBufferSettingsAction); guiActions.add(showBufferSettingsAction);
/* File menu */ /* File menu */
menu = new JMenu("File"); menu = new JMenu("File");
menu.addMenuListener(new MenuListener() { menu.addMenuListener(new MenuListener() {
@ -733,7 +733,7 @@ public class GUI extends Observable {
}); });
menu.setMnemonic(KeyEvent.VK_S); menu.setMnemonic(KeyEvent.VK_S);
menuBar.add(menu); menuBar.add(menu);
menu.add(new JMenuItem(startStopSimulationAction)); menu.add(new JMenuItem(startStopSimulationAction));
GUIAction guiAction = new StartPluginGUIAction("Control panel"); GUIAction guiAction = new StartPluginGUIAction("Control panel");
@ -929,7 +929,7 @@ public class GUI extends Observable {
menuItem.setEnabled(false); menuItem.setEnabled(false);
menuItem.setToolTipText("Not available in applet version"); menuItem.setToolTipText("Not available in applet version");
} }
menuItem = new JMenuItem("Contiki mote configuration wizard"); menuItem = new JMenuItem("Contiki mote configuration wizard");
menuItem.setActionCommand("configuration wizard"); menuItem.setActionCommand("configuration wizard");
menuItem.addActionListener(guiEventHandler); menuItem.addActionListener(guiEventHandler);
@ -940,7 +940,7 @@ public class GUI extends Observable {
} }
menu.add(new JMenuItem(showBufferSettingsAction)); menu.add(new JMenuItem(showBufferSettingsAction));
/* Help */ /* Help */
menu = new JMenu("Help"); menu = new JMenu("Help");
menu.setMnemonic(KeyEvent.VK_H); menu.setMnemonic(KeyEvent.VK_H);
@ -950,7 +950,7 @@ public class GUI extends Observable {
menu.add(checkBox); menu.add(checkBox);
menuBar.add(menu); menuBar.add(menu);
menu.addSeparator(); menu.addSeparator();
menuItem = new JMenuItem("Java version: " menuItem = new JMenuItem("Java version: "
+ System.getProperty("java.version") + " (" + System.getProperty("java.version") + " ("
@ -965,7 +965,7 @@ public class GUI extends Observable {
+ System.getProperty("sun.arch.data.model")); + System.getProperty("sun.arch.data.model"));
menuItem.setEnabled(false); menuItem.setEnabled(false);
menu.add(menuItem); menu.add(menuItem);
// Mote plugins popup menu (not available via menu bar) // Mote plugins popup menu (not available via menu bar)
if (menuMotePluginClasses == null) { if (menuMotePluginClasses == null) {
menuMotePluginClasses = new Vector<Class<? extends Plugin>>(); menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
@ -1356,7 +1356,7 @@ public class GUI extends Observable {
unregisterPositioners(); unregisterPositioners();
unregisterRadioMediums(); unregisterRadioMediums();
projectDirClassLoader = null; projectDirClassLoader = null;
/* Build cooja configuration */ /* Build cooja configuration */
try { try {
projectConfig = new ProjectConfig(true); projectConfig = new ProjectConfig(true);
@ -1381,7 +1381,7 @@ public class GUI extends Observable {
"Error when reading project config: " + e.getMessage()).initCause(e); "Error when reading project config: " + e.getMessage()).initCause(e);
} }
} }
/* Create project class loader */ /* Create project class loader */
try { try {
projectDirClassLoader = createClassLoader(currentProjects); projectDirClassLoader = createClassLoader(currentProjects);
@ -1585,7 +1585,7 @@ public class GUI extends Observable {
* Same as the {@link #startPlugin(Class, GUI, Simulation, Mote)} method, * Same as the {@link #startPlugin(Class, GUI, Simulation, Mote)} method,
* but does not throw exceptions. If COOJA is visualised, an error dialog * but does not throw exceptions. If COOJA is visualised, an error dialog
* is shown if plugin could not be started. * is shown if plugin could not be started.
* *
* @see #startPlugin(Class, GUI, Simulation, Mote) * @see #startPlugin(Class, GUI, Simulation, Mote)
* @param pluginClass Plugin class * @param pluginClass Plugin class
* @param argGUI Plugin GUI argument * @param argGUI Plugin GUI argument
@ -1609,7 +1609,7 @@ public class GUI extends Observable {
return null; return null;
} }
} while (cause != null && (cause=cause.getCause()) != null); } while (cause != null && (cause=cause.getCause()) != null);
logger.fatal("Error when starting plugin", ex); logger.fatal("Error when starting plugin", ex);
} }
} }
@ -1622,15 +1622,15 @@ public class GUI extends Observable {
} }
public Plugin startPlugin(final Class<? extends Plugin> pluginClass, public Plugin startPlugin(final Class<? extends Plugin> pluginClass,
final GUI argGUI, final Simulation argSimulation, final Mote argMote) final GUI argGUI, final Simulation argSimulation, final Mote argMote)
throws PluginConstructionException throws PluginConstructionException
{ {
return startPlugin(pluginClass, argGUI, argSimulation, argMote, true); return startPlugin(pluginClass, argGUI, argSimulation, argMote, true);
} }
/** /**
* Starts given plugin. If visualized, the plugin is also shown. * Starts given plugin. If visualized, the plugin is also shown.
* *
* @see PluginType * @see PluginType
* @param pluginClass Plugin class * @param pluginClass Plugin class
* @param argGUI Plugin GUI argument * @param argGUI Plugin GUI argument
@ -1665,7 +1665,7 @@ public class GUI extends Observable {
throw new PluginConstructionException("No mote argument for mote plugin"); throw new PluginConstructionException("No mote argument for mote plugin");
} }
plugin = plugin =
pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, GUI.class }) pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, GUI.class })
.newInstance(argMote, argSimulation, argGUI); .newInstance(argMote, argSimulation, argGUI);
@ -1678,7 +1678,7 @@ public class GUI extends Observable {
throw new PluginConstructionException("No simulation argument for simulation plugin"); throw new PluginConstructionException("No simulation argument for simulation plugin");
} }
plugin = plugin =
pluginClass.getConstructor(new Class[] { Simulation.class, GUI.class }) pluginClass.getConstructor(new Class[] { Simulation.class, GUI.class })
.newInstance(argSimulation, argGUI); .newInstance(argSimulation, argGUI);
@ -1717,7 +1717,7 @@ public class GUI extends Observable {
if (activate && plugin.getGUI() != null) { if (activate && plugin.getGUI() != null) {
myGUI.showPlugin(plugin); myGUI.showPlugin(plugin);
} }
return plugin; return plugin;
} }
@ -1807,7 +1807,7 @@ public class GUI extends Observable {
// Create 'start plugin'-menu item // Create 'start plugin'-menu item
JMenuItem menuItem; JMenuItem menuItem;
String tooltip = "<html>"; String tooltip = "<html>";
/* Sort menu according to plugin type */ /* Sort menu according to plugin type */
int itemIndex=0; int itemIndex=0;
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) { if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
@ -1892,7 +1892,7 @@ public class GUI extends Observable {
/** /**
* Returns started plugin that ends with given class name, if any. * Returns started plugin that ends with given class name, if any.
* *
* @param classname Class name * @param classname Class name
* @return Plugin instance * @return Plugin instance
*/ */
@ -1904,10 +1904,10 @@ public class GUI extends Observable {
} }
return null; return null;
} }
/** /**
* Returns started plugin with given class name, if any. * Returns started plugin with given class name, if any.
* *
* @param classname Class name * @param classname Class name
* @return Plugin instance * @return Plugin instance
* @deprecated * @deprecated
@ -1977,21 +1977,21 @@ public class GUI extends Observable {
/** /**
* Creates a new mote type of the given mote type class. * Creates a new mote type of the given mote type class.
* This may include displaying a dialog for user configurations. * This may include displaying a dialog for user configurations.
* *
* If mote type is created successfully, the add motes dialog will appear. * If mote type is created successfully, the add motes dialog will appear.
* *
* @param moteTypeClass Mote type class * @param moteTypeClass Mote type class
*/ */
public void doCreateMoteType(Class<? extends MoteType> moteTypeClass) { public void doCreateMoteType(Class<? extends MoteType> moteTypeClass) {
doCreateMoteType(moteTypeClass, true); doCreateMoteType(moteTypeClass, true);
} }
/** /**
* Creates a new mote type of the given mote type class. * Creates a new mote type of the given mote type class.
* This may include displaying a dialog for user configurations. * This may include displaying a dialog for user configurations.
* *
* @param moteTypeClass Mote type class * @param moteTypeClass Mote type class
* @param addMotes Show add motes dialog after successfully adding mote type * @param addMotes Show add motes dialog after successfully adding mote type
*/ */
public void doCreateMoteType(Class<? extends MoteType> moteTypeClass, boolean addMotes) { public void doCreateMoteType(Class<? extends MoteType> moteTypeClass, boolean addMotes) {
if (mySimulation == null) { if (mySimulation == null) {
@ -2236,7 +2236,7 @@ public class GUI extends Observable {
PROGRESS_WARNINGS.clear(); PROGRESS_WARNINGS.clear();
newSim = loadSimulationConfig(fileToLoad, quick); newSim = loadSimulationConfig(fileToLoad, quick);
myGUI.setSimulation(newSim, false); myGUI.setSimulation(newSim, false);
/* Optionally show compilation warnings */ /* Optionally show compilation warnings */
boolean hideWarn = Boolean.parseBoolean( boolean hideWarn = Boolean.parseBoolean(
GUI.getExternalToolsSetting("HIDE_WARNINGS", "false") GUI.getExternalToolsSetting("HIDE_WARNINGS", "false")
@ -2245,7 +2245,7 @@ public class GUI extends Observable {
showWarningsDialog(frame, PROGRESS_WARNINGS.toArray(new String[0])); showWarningsDialog(frame, PROGRESS_WARNINGS.toArray(new String[0]));
} }
PROGRESS_WARNINGS.clear(); PROGRESS_WARNINGS.clear();
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
shouldRetry = showErrorDialog(GUI.getTopParentContainer(), "Simulation load error", e, true); shouldRetry = showErrorDialog(GUI.getTopParentContainer(), "Simulation load error", e, true);
} catch (SimulationCreationException e) { } catch (SimulationCreationException e) {
@ -2276,7 +2276,7 @@ public class GUI extends Observable {
if (warnMemory()) { if (warnMemory()) {
return; return;
} }
final JDialog progressDialog = new JDialog(frame, "Reloading", true); final JDialog progressDialog = new JDialog(frame, "Reloading", true);
final Thread loadThread = new Thread(new Runnable() { final Thread loadThread = new Thread(new Runnable() {
public void run() { public void run() {
@ -2305,7 +2305,7 @@ public class GUI extends Observable {
if (autoStart) { if (autoStart) {
newSim.startSimulation(); newSim.startSimulation();
} }
/* Optionally show compilation warnings */ /* Optionally show compilation warnings */
boolean hideWarn = Boolean.parseBoolean( boolean hideWarn = Boolean.parseBoolean(
GUI.getExternalToolsSetting("HIDE_WARNINGS", "false") GUI.getExternalToolsSetting("HIDE_WARNINGS", "false")
@ -2314,7 +2314,7 @@ public class GUI extends Observable {
showWarningsDialog(frame, PROGRESS_WARNINGS.toArray(new String[0])); showWarningsDialog(frame, PROGRESS_WARNINGS.toArray(new String[0]));
} }
PROGRESS_WARNINGS.clear(); PROGRESS_WARNINGS.clear();
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
shouldRetry = showErrorDialog(frame, "Simulation reload error", e, true); shouldRetry = showErrorDialog(frame, "Simulation reload error", e, true);
@ -2459,7 +2459,7 @@ public class GUI extends Observable {
return saveFile; return saveFile;
} else { } else {
JOptionPane.showMessageDialog( JOptionPane.showMessageDialog(
getTopParentContainer(), "No write access to " + saveFile, "Save failed", getTopParentContainer(), "No write access to " + saveFile, "Save failed",
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
logger.fatal("No write access to file: " + saveFile.getAbsolutePath()); logger.fatal("No write access to file: " + saveFile.getAbsolutePath());
} }
@ -2757,8 +2757,8 @@ public class GUI extends Observable {
ExternalToolsDialog.showDialog(GUI.getTopParentContainer()); ExternalToolsDialog.showDialog(GUI.getTopParentContainer());
} else if (e.getActionCommand().equals("manage projects")) { } else if (e.getActionCommand().equals("manage projects")) {
COOJAProject[] newProjects = ProjectDirectoriesDialog.showDialog( COOJAProject[] newProjects = ProjectDirectoriesDialog.showDialog(
GUI.getTopParentContainer(), GUI.getTopParentContainer(),
GUI.this, GUI.this,
getProjects() getProjects()
); );
if (newProjects != null) { if (newProjects != null) {
@ -3029,7 +3029,7 @@ public class GUI extends Observable {
System.exit(1); System.exit(1);
} }
GUI gui = sim.getGUI(); GUI gui = sim.getGUI();
/* Make sure at least one test editor is controlling the simulation */ /* Make sure at least one test editor is controlling the simulation */
boolean hasEditor = false; boolean hasEditor = false;
for (Plugin startedPlugin : gui.startedPlugins) { for (Plugin startedPlugin : gui.startedPlugins) {
@ -3051,7 +3051,12 @@ public class GUI extends Observable {
System.exit(1); System.exit(1);
} }
plugin.updateScript(scriptFile); plugin.updateScript(scriptFile);
plugin.setScriptActive(true); try {
plugin.setScriptActive(true);
} catch (Exception e) {
logger.fatal("Error: " + e.getMessage(), e);
System.exit(1);
}
sim.setDelayTime(0); sim.setDelayTime(0);
sim.startSimulation(); sim.startSimulation();
} else { } else {
@ -3059,7 +3064,7 @@ public class GUI extends Observable {
System.exit(1); System.exit(1);
} }
} }
} else if (args.length > 0 && args[0].startsWith("-applet")) { } else if (args.length > 0 && args[0].startsWith("-applet")) {
String tmpWebPath=null, tmpBuildPath=null, tmpEsbFirmware=null, tmpSkyFirmware=null; String tmpWebPath=null, tmpBuildPath=null, tmpEsbFirmware=null, tmpSkyFirmware=null;
@ -3258,11 +3263,11 @@ public class GUI extends Observable {
// Create and write to document // Create and write to document
Document doc = new Document(extractSimulationConfig()); Document doc = new Document(extractSimulationConfig());
OutputStream out = new FileOutputStream(file); OutputStream out = new FileOutputStream(file);
if (file.getName().endsWith(".gz")) { if (file.getName().endsWith(".gz")) {
out = new GZIPOutputStream(out); out = new GZIPOutputStream(out);
} }
XMLOutputter outputter = new XMLOutputter(); XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat()); outputter.setFormat(Format.getPrettyFormat());
outputter.output(doc, out); outputter.output(doc, out);
@ -3274,7 +3279,7 @@ public class GUI extends Observable {
e.printStackTrace(); e.printStackTrace();
} }
} }
public Element extractSimulationConfig() { public Element extractSimulationConfig() {
// Create simulation config // Create simulation config
Element root = new Element("simconf"); Element root = new Element("simconf");
@ -3391,7 +3396,7 @@ public class GUI extends Observable {
projectFile = projectFile.getCanonicalFile(); projectFile = projectFile.getCanonicalFile();
} catch (IOException e) { } catch (IOException e) {
} }
boolean found = false; boolean found = false;
for (COOJAProject currentProject: currentProjects) { for (COOJAProject currentProject: currentProjects) {
if (projectFile.getPath().replaceAll("\\\\", "/"). if (projectFile.getPath().replaceAll("\\\\", "/").
@ -3473,7 +3478,7 @@ public class GUI extends Observable {
/* Activate plugin */ /* Activate plugin */
startedPlugin.startPlugin(); startedPlugin.startPlugin();
/* If Cooja not visualized, ignore window configuration */ /* If Cooja not visualized, ignore window configuration */
if (startedPlugin.getGUI() == null) { if (startedPlugin.getGUI() == null) {
continue; continue;
@ -3511,7 +3516,7 @@ public class GUI extends Observable {
pluginGUI.setIcon(true); pluginGUI.setIcon(true);
} catch (PropertyVetoException e) { } catch (PropertyVetoException e) {
} }
}; };
}); });
} }
} }
@ -3618,7 +3623,7 @@ public class GUI extends Observable {
list.addPopupMenuItem(null, true); list.addPopupMenuItem(null, true);
tabbedPane.addTab("Contiki error", new JScrollPane(list)); tabbedPane.addTab("Contiki error", new JScrollPane(list));
} }
/* Compilation output */ /* Compilation output */
MessageList compilationOutput = null; MessageList compilationOutput = null;
if (exception instanceof MoteTypeCreationException if (exception instanceof MoteTypeCreationException
@ -3704,7 +3709,7 @@ public class GUI extends Observable {
private static void showWarningsDialog(final Frame parent, final String[] warnings) { private static void showWarningsDialog(final Frame parent, final String[] warnings) {
new RunnableInEDT<Boolean>() { new RunnableInEDT<Boolean>() {
public Boolean work() { public Boolean work() {
final JDialog dialog = new JDialog((Frame)parent, "Compilation warnings", false); final JDialog dialog = new JDialog(parent, "Compilation warnings", false);
Box buttonBox = Box.createHorizontalBox(); Box buttonBox = Box.createHorizontalBox();
/* Warnings message list */ /* Warnings message list */
@ -3748,7 +3753,7 @@ public class GUI extends Observable {
} }
}.invokeAndWait(); }.invokeAndWait();
} }
/** /**
* Runs work method in event dispatcher thread. * Runs work method in event dispatcher thread.
* Worker method returns a value. * Worker method returns a value.
@ -3885,9 +3890,9 @@ public class GUI extends Observable {
/** /**
* Tries to convert given file to be "portable". * Tries to convert given file to be "portable".
* The portable path is either relative to Contiki, or to the configuration (.csc) file. * The portable path is either relative to Contiki, or to the configuration (.csc) file.
* *
* If this method fails, it returns the original file. * If this method fails, it returns the original file.
* *
* @param file Original file * @param file Original file
* @return Portable file, or original file is conversion failed * @return Portable file, or original file is conversion failed
*/ */
@ -3897,7 +3902,7 @@ public class GUI extends Observable {
public File createPortablePath(File file, boolean allowConfigRelativePaths) { public File createPortablePath(File file, boolean allowConfigRelativePaths) {
File portable = null; File portable = null;
portable = createContikiRelativePath(file); portable = createContikiRelativePath(file);
if (portable != null) { if (portable != null) {
/*logger.info("Generated Contiki relative path '" + file.getPath() + "' to '" + portable.getPath() + "'");*/ /*logger.info("Generated Contiki relative path '" + file.getPath() + "' to '" + portable.getPath() + "'");*/
@ -3911,7 +3916,7 @@ public class GUI extends Observable {
return portable; return portable;
} }
} }
logger.warn("Path is not portable: '" + file.getPath()); logger.warn("Path is not portable: '" + file.getPath());
return file; return file;
} }
@ -3919,7 +3924,7 @@ public class GUI extends Observable {
/** /**
* Tries to restore a previously "portable" file to be "absolute". * Tries to restore a previously "portable" file to be "absolute".
* If the given file already exists, no conversion is performed. * If the given file already exists, no conversion is performed.
* *
* @see #createPortablePath(File) * @see #createPortablePath(File)
* @param file Portable file * @param file Portable file
* @return Absolute file * @return Absolute file
@ -3942,7 +3947,7 @@ public class GUI extends Observable {
/*logger.info("Restored config relative path '" + file.getPath() + "' to '" + absolute.getPath() + "'");*/ /*logger.info("Restored config relative path '" + file.getPath() + "' to '" + absolute.getPath() + "'");*/
return absolute; return absolute;
} }
/*logger.info("Portable path was not restored: '" + file.getPath());*/ /*logger.info("Portable path was not restored: '" + file.getPath());*/
return file; return file;
} }
@ -3962,10 +3967,10 @@ public class GUI extends Observable {
/* Replace Contiki's canonical path with Contiki identifier */ /* Replace Contiki's canonical path with Contiki identifier */
String portablePath = fileCanonical.replaceFirst( String portablePath = fileCanonical.replaceFirst(
java.util.regex.Matcher.quoteReplacement(contikiCanonical), java.util.regex.Matcher.quoteReplacement(contikiCanonical),
java.util.regex.Matcher.quoteReplacement(PATH_CONTIKI_IDENTIFIER)); java.util.regex.Matcher.quoteReplacement(PATH_CONTIKI_IDENTIFIER));
File portable = new File(portablePath); File portable = new File(portablePath);
/* Verify conversion */ /* Verify conversion */
File verify = restoreContikiRelativePath(portable); File verify = restoreContikiRelativePath(portable);
if (verify == null || !verify.exists()) { if (verify == null || !verify.exists()) {
@ -4028,10 +4033,10 @@ public class GUI extends Observable {
/* Replace config's canonical path with config identifier */ /* Replace config's canonical path with config identifier */
String portablePath = fileCanonical.replaceFirst( String portablePath = fileCanonical.replaceFirst(
java.util.regex.Matcher.quoteReplacement(configCanonical), java.util.regex.Matcher.quoteReplacement(configCanonical),
java.util.regex.Matcher.quoteReplacement(id)); java.util.regex.Matcher.quoteReplacement(id));
File portable = new File(portablePath); File portable = new File(portablePath);
/* Verify conversion */ /* Verify conversion */
File verify = restoreConfigRelativePath(portable); File verify = restoreConfigRelativePath(portable);
if (verify == null || !verify.exists()) { if (verify == null || !verify.exists()) {
@ -4087,11 +4092,11 @@ public class GUI extends Observable {
*/ */
public String getQuickHelp(); public String getQuickHelp();
} }
/** /**
* Load quick help for given object or identifier. Note that this method does not * Load quick help for given object or identifier. Note that this method does not
* show the quick help pane. * show the quick help pane.
* *
* @param obj If string: help identifier. Else, the class name of the argument * @param obj If string: help identifier. Else, the class name of the argument
* is used as help identifier. * is used as help identifier.
*/ */
@ -4106,7 +4111,7 @@ public class GUI extends Observable {
} else { } else {
key = obj.getClass().getName(); key = obj.getClass().getName();
} }
String help = null; String help = null;
if (obj instanceof HasQuickHelp) { if (obj instanceof HasQuickHelp) {
help = ((HasQuickHelp) obj).getQuickHelp(); help = ((HasQuickHelp) obj).getQuickHelp();
@ -4292,13 +4297,13 @@ public class GUI extends Observable {
} }
outputFile.delete(); outputFile.delete();
} }
final File finalOutputFile = outputFile; final File finalOutputFile = outputFile;
setExternalToolsSetting("EXECUTE_JAR_LAST", outputFile.getPath()); setExternalToolsSetting("EXECUTE_JAR_LAST", outputFile.getPath());
new Thread() { new Thread() {
public void run() { public void run() {
try { try {
ExecuteJAR.buildExecutableJAR(GUI.this, finalOutputFile); ExecuteJAR.buildExecutableJAR(GUI.this, finalOutputFile);
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
JOptionPane.showMessageDialog(GUI.getTopParentContainer(), JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
ex.getMessage(), ex.getMessage(),
@ -4359,7 +4364,7 @@ public class GUI extends Observable {
public void actionPerformed(final ActionEvent e) { public void actionPerformed(final ActionEvent e) {
new Thread(new Runnable() { new Thread(new Runnable() {
public void run() { public void run() {
Class<Plugin> pluginClass = Class<Plugin> pluginClass =
(Class<Plugin>) ((JMenuItem) e.getSource()).getClientProperty("class"); (Class<Plugin>) ((JMenuItem) e.getSource()).getClientProperty("class");
Mote mote = (Mote) ((JMenuItem) e.getSource()).getClientProperty("mote"); Mote mote = (Mote) ((JMenuItem) e.getSource()).getClientProperty("mote");
tryStartPlugin(pluginClass, myGUI, mySimulation, mote); tryStartPlugin(pluginClass, myGUI, mySimulation, mote);
@ -4434,5 +4439,5 @@ public class GUI extends Observable {
return mySimulation != null; return mySimulation != null;
} }
}; };
} }

View file

@ -64,9 +64,9 @@ public class LogScriptEngine {
private static Logger logger = Logger.getLogger(LogScriptEngine.class); private static Logger logger = Logger.getLogger(LogScriptEngine.class);
private static final long DEFAULT_TIMEOUT = 20*60*1000*Simulation.MILLISECOND; /* 1200s = 20 minutes */ private static final long DEFAULT_TIMEOUT = 20*60*1000*Simulation.MILLISECOND; /* 1200s = 20 minutes */
private ScriptEngine engine = private ScriptEngine engine =
new ScriptEngineManager().getEngineByName("JavaScript"); new ScriptEngineManager().getEngineByName("JavaScript");
/* Log output listener */ /* Log output listener */
private LogOutputListener logOutputListener = new LogOutputListener() { private LogOutputListener logOutputListener = new LogOutputListener() {
public void moteWasAdded(Mote mote) { public void moteWasAdded(Mote mote) {
@ -97,6 +97,11 @@ public class LogScriptEngine {
private boolean scriptActive = false; private boolean scriptActive = false;
private long timeout;
private long startTime;
private long startRealTime;
private long nextProgress;
private interface ScriptLog { private interface ScriptLog {
public void log(String log); public void log(String log);
public void testOK(); public void testOK();
@ -104,6 +109,10 @@ public class LogScriptEngine {
public void generateMessage(long delay, String msg); public void generateMessage(long delay, String msg);
} }
public LogScriptEngine(Simulation simulation) {
this.simulation = simulation;
}
/* Only called from the simulation loop */ /* Only called from the simulation loop */
private void stepScript() { private void stepScript() {
/* Release script - halt simulation */ /* Release script - halt simulation */
@ -130,10 +139,6 @@ public class LogScriptEngine {
} }
} }
public LogScriptEngine(Simulation simulation) {
this.simulation = simulation;
}
/* Only called from the simulation loop */ /* Only called from the simulation loop */
private void handleNewMoteOutput(Mote mote, int id, long time, String msg) { private void handleNewMoteOutput(Mote mote, int id, long time, String msg) {
try { try {
@ -195,37 +200,31 @@ public class LogScriptEngine {
} }
scriptActive = false; scriptActive = false;
if (semaphoreScript == null) {
/*logger.warn("semaphoreScript is not initialized");*/
}
if (semaphoreSim == null) {
/*logger.warn("semaphoreSim is not initialized");*/
}
if (scriptThread == null) {
/*logger.warn("scriptThread is not initialized");*/
}
timeoutEvent.remove(); timeoutEvent.remove();
timeoutProgressEvent.remove(); timeoutProgressEvent.remove();
simulation.getEventCentral().removeLogOutputListener(logOutputListener); simulation.getEventCentral().removeLogOutputListener(logOutputListener);
engine.put("SHUTDOWN", true); engine.put("SHUTDOWN", true);
try { try {
semaphoreScript.release(100); if (semaphoreScript != null) {
semaphoreScript.release(100);
}
} catch (Exception e) { } catch (Exception e) {
} finally { } finally {
semaphoreScript = null; semaphoreScript = null;
} }
try { try {
semaphoreSim.release(100); if (semaphoreSim != null) {
semaphoreSim.release(100);
}
} catch (Exception e) { } catch (Exception e) {
} finally { } finally {
semaphoreSim = null; semaphoreSim = null;
} }
if (scriptThread != null && if (scriptThread != null &&
scriptThread != Thread.currentThread() /* XXX May deadlock */ ) { scriptThread != Thread.currentThread() /* XXX May deadlock */ ) {
try { try {
scriptThread.join(); scriptThread.join();
@ -235,7 +234,6 @@ public class LogScriptEngine {
} }
} }
scriptThread = null; scriptThread = null;
} }
public void activateScript(String scriptCode) throws ScriptException { public void activateScript(String scriptCode) throws ScriptException {
@ -245,43 +243,29 @@ public class LogScriptEngine {
scriptActive = true; scriptActive = true;
if (semaphoreScript != null) { if (semaphoreScript != null) {
logger.warn("semaphoreScript is already initialized"); logger.warn("Semaphores were not reset correctly");
semaphoreScript.release(100);
semaphoreScript = null;
} }
if (semaphoreSim != null) { if (semaphoreSim != null) {
logger.warn("semaphoreSim is already initialized"); logger.warn("Semaphores were not reset correctly");
} semaphoreSim.release(100);
if (scriptThread != null) { semaphoreSim = null;
logger.warn("scriptThread is already initialized");
} }
scriptThread = null;
/* Parse current script */ /* Parse current script */
ScriptParser parser = new ScriptParser(scriptCode); ScriptParser parser = new ScriptParser(scriptCode);
String jsCode = parser.getJSCode(); String jsCode = parser.getJSCode();
long timeoutTime = parser.getTimeoutTime(); timeout = parser.getTimeoutTime();
if (timeoutTime < 0) { if (timeout < 0) {
logger.info("No timeout defined, using default (us): " + DEFAULT_TIMEOUT); timeout = DEFAULT_TIMEOUT;
timeoutTime = DEFAULT_TIMEOUT; logger.info("Default script timeout in " + (timeout/Simulation.MILLISECOND) + " ms");
} else {
logger.info("Script timeout in " + (timeout/Simulation.MILLISECOND) + " ms");
} }
final long duration = timeoutTime;
simulation.invokeSimulationThread(new Runnable() {
public void run() {
final long startTime = simulation.getSimulationTime();
final long interval = (long) (0.01*5*duration);
simulation.scheduleEvent(timeoutProgressEvent = new TimeEvent(0) {
public void execute(long t) {
int percent = (int) (5*(t-startTime)/interval);
logger.info("Test script at " + percent + "%");
simulation.scheduleEvent(this, t+interval);
}
}, startTime+interval);
simulation.scheduleEvent(timeoutEvent, startTime + duration);
}
});
engine.eval(jsCode); engine.eval(jsCode);
/* Setup script control */ /* Setup script control */
@ -352,95 +336,7 @@ public class LogScriptEngine {
simulation.getEventCentral().addLogOutputListener(logOutputListener); simulation.getEventCentral().addLogOutputListener(logOutputListener);
/* Create script output logger */ /* Create script output logger */
engine.put("log", new ScriptLog() { engine.put("log", scriptLog);
public void log(String msg) {
if (scriptLogObserver != null) {
scriptLogObserver.update(null, msg);
}
}
public void append(String filename, String msg) {
try{
FileWriter fstream = new FileWriter(filename, true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(msg);
out.close();
} catch (Exception e) {
logger.warn("Test append failed: " + filename + ": " + e.getMessage());
}
}
public void testOK() {
log("TEST OK\n");
if (GUI.isVisualized()) {
log("[if test was run without visualization, COOJA would now have been terminated]\n");
stopSimulation = true;
simulation.invokeSimulationThread(stopSimulationRunnable);
} else {
quitCooja = true;
simulation.invokeSimulationThread(quitRunnable);
}
timeoutEvent.remove();
timeoutProgressEvent.remove();
semaphoreSim.release(100);
throw new RuntimeException("test script killed");
}
public void writeFile(String filename, String msg) {
try{
FileWriter fstream = new FileWriter(filename, false);
BufferedWriter out = new BufferedWriter(fstream);
out.write(msg);
out.close();
} catch (Exception e) {
logger.warn("Write file failed: " + filename + ": " + e.getMessage());
}
}
public void testFailed() {
log("TEST FAILED\n");
if (GUI.isVisualized()) {
log("[if test was run without visualization, COOJA would now have been terminated]\n");
stopSimulation = true;
simulation.invokeSimulationThread(stopSimulationRunnable);
} else {
quitCooja = true;
simulation.invokeSimulationThread(quitRunnable);
}
semaphoreSim.release(100);
throw new RuntimeException("test script killed");
}
public void generateMessage(final long delay, final String msg) {
final Mote currentMote = (Mote) engine.get("mote");
final TimeEvent generateEvent = new TimeEvent(0) {
public void execute(long t) {
if (scriptThread == null ||
!scriptThread.isAlive()) {
logger.info("script thread not alive. try deactivating script.");
/*scriptThread.isInterrupted()*/
return;
}
/* Update script variables */
engine.put("mote", currentMote);
engine.put("id", currentMote.getID());
engine.put("time", currentMote.getSimulation().getSimulationTime());
engine.put("msg", msg);
stepScript();
}
};
simulation.invokeSimulationThread(new Runnable() {
public void run() {
simulation.scheduleEvent(
generateEvent,
simulation.getSimulationTime() + delay*Simulation.MILLISECOND);
}
});
}
});
Hashtable<Object, Object> hash = new Hashtable<Object, Object>(); Hashtable<Object, Object> hash = new Hashtable<Object, Object>();
engine.put("global", hash); engine.put("global", hash);
@ -449,27 +345,53 @@ public class LogScriptEngine {
scriptMote = new ScriptMote(); scriptMote = new ScriptMote();
engine.put("node", scriptMote); engine.put("node", scriptMote);
Runnable activate = new Runnable() {
public void run() {
startRealTime = System.currentTimeMillis();
startTime = simulation.getSimulationTime();
long endTime = startTime + timeout;
nextProgress = startTime + (endTime - startTime)/20;
timeoutProgressEvent.remove();
simulation.scheduleEvent(timeoutProgressEvent, nextProgress);
timeoutEvent.remove();
simulation.scheduleEvent(timeoutEvent, endTime);
}
};
if (simulation.isRunning()) {
simulation.invokeSimulationThread(activate);
} else {
activate.run();
}
} }
private TimeEvent timeoutEvent = new TimeEvent(0) { private TimeEvent timeoutEvent = new TimeEvent(0) {
public void execute(long t) { public void execute(long t) {
if (!scriptActive) { if (!scriptActive) {
return; return;
} }
logger.info("Timeout event @ " + t); logger.info("Timeout event @ " + t);
engine.put("TIMEOUT", true); engine.put("TIMEOUT", true);
stepScript(); stepScript();
} }
}; };
private TimeEvent timeoutProgressEvent = new TimeEvent(0) { private TimeEvent timeoutProgressEvent = new TimeEvent(0) {
public void execute(long t) { } public void execute(long t) {
}; nextProgress = t + timeout/20;
simulation.scheduleEvent(this, nextProgress);
double progress = 1.0*(t - startTime)/timeout;
long realDuration = System.currentTimeMillis()-startRealTime;
double estimatedLeft = 1.0*realDuration/progress - realDuration;
if (estimatedLeft == 0) estimatedLeft = 1;
logger.info(String.format("Test script at %2.2f%%, done in %2.1f sec", 100*progress, estimatedLeft/1000));
}
};
private Runnable stopSimulationRunnable = new Runnable() { private Runnable stopSimulationRunnable = new Runnable() {
public void run() { public void run() {
simulation.stopSimulation(); simulation.stopSimulation();
timeoutEvent.remove();
timeoutProgressEvent.remove();
} }
}; };
private Runnable quitRunnable = new Runnable() { private Runnable quitRunnable = new Runnable() {
@ -491,4 +413,83 @@ public class LogScriptEngine {
} }
}; };
private ScriptLog scriptLog = new ScriptLog() {
public void log(String msg) {
if (scriptLogObserver != null) {
scriptLogObserver.update(null, msg);
}
}
public void append(String filename, String msg) {
try{
FileWriter fstream = new FileWriter(filename, true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(msg);
out.close();
} catch (Exception e) {
logger.warn("Test append failed: " + filename + ": " + e.getMessage());
}
}
public void writeFile(String filename, String msg) {
try{
FileWriter fstream = new FileWriter(filename, false);
BufferedWriter out = new BufferedWriter(fstream);
out.write(msg);
out.close();
} catch (Exception e) {
logger.warn("Write file failed: " + filename + ": " + e.getMessage());
}
}
public void testOK() {
log("TEST OK\n");
deactive();
}
public void testFailed() {
log("TEST FAILED\n");
deactive();
}
private void deactive() {
deactivateScript();
if (GUI.isVisualized()) {
log("[if test was run without visualization, COOJA would now have been terminated]\n");
stopSimulation = true;
simulation.invokeSimulationThread(stopSimulationRunnable);
} else {
quitCooja = true;
simulation.invokeSimulationThread(quitRunnable);
}
throw new RuntimeException("test script killed");
}
public void generateMessage(final long delay, final String msg) {
final Mote currentMote = (Mote) engine.get("mote");
final TimeEvent generateEvent = new TimeEvent(0) {
public void execute(long t) {
if (scriptThread == null ||
!scriptThread.isAlive()) {
logger.info("script thread not alive. try deactivating script.");
/*scriptThread.isInterrupted()*/
return;
}
/* Update script variables */
engine.put("mote", currentMote);
engine.put("id", currentMote.getID());
engine.put("time", currentMote.getSimulation().getSimulationTime());
engine.put("msg", msg);
stepScript();
}
};
simulation.invokeSimulationThread(new Runnable() {
public void run() {
simulation.scheduleEvent(
generateEvent,
simulation.getSimulationTime() + delay*Simulation.MILLISECOND);
}
});
}
};
} }

View file

@ -92,8 +92,7 @@ public class ScriptRunner extends VisPlugin {
static boolean headless; static boolean headless;
{ {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); headless = GraphicsEnvironment.isHeadless();
headless = ge.isHeadless();
if (!headless) { if (!headless) {
DefaultSyntaxKit.initKit(); DefaultSyntaxKit.initKit();
} }
@ -183,10 +182,14 @@ public class ScriptRunner extends VisPlugin {
toggleButton = new JButton("Activate"); toggleButton = new JButton("Activate");
toggleButton.addActionListener(new ActionListener() { toggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) { public void actionPerformed(ActionEvent ev) {
if (toggleButton.getText().equals("Activate")) { try {
setScriptActive(true); if (!isActive()) {
} else { setScriptActive(true);
setScriptActive(false); } else {
setScriptActive(false);
}
} catch (Exception e) {
logger.fatal("Error: " + e.getMessage(), e);
} }
} }
}); });
@ -276,7 +279,8 @@ public class ScriptRunner extends VisPlugin {
updateTitle(); updateTitle();
} }
public void setScriptActive(boolean active) { public void setScriptActive(boolean active)
throws Exception {
if (active) { if (active) {
/* setScriptActive(true) */ /* setScriptActive(true) */
@ -612,7 +616,10 @@ public class ScriptRunner extends VisPlugin {
} }
public void closePlugin() { public void closePlugin() {
setScriptActive(false); try {
setScriptActive(false);
} catch (Exception e) {
}
} }
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) { public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
@ -628,14 +635,22 @@ public class ScriptRunner extends VisPlugin {
} else if ("active".equals(name)) { } else if ("active".equals(name)) {
boolean active = Boolean.parseBoolean(element.getText()); boolean active = Boolean.parseBoolean(element.getText());
if (GUI.isVisualized()) { if (GUI.isVisualized()) {
setScriptActive(active); try {
setScriptActive(active);
} catch (Exception e) {
logger.fatal("Error: " + e.getMessage(), e);
}
} }
} }
} }
if (!GUI.isVisualized()) { if (!GUI.isVisualized()) {
/* Automatically activate script */ /* Automatically activate script */
setScriptActive(true); try {
setScriptActive(true);
} catch (Exception e) {
logger.fatal("Error: " + e.getMessage(), e);
}
simulation.setDelayTime(0); simulation.setDelayTime(0);
simulation.startSimulation(); simulation.startSimulation();
} }