From: Ed Warnicke Date: Fri, 13 Dec 2013 14:45:20 +0000 (+0000) Subject: This sanity test is sporatically failing in Jenkins for no good reason. Reverting... X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~197^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=2b7a9155e28c3a42765f1f05320357dbb2e6eab7 This sanity test is sporatically failing in Jenkins for no good reason. Reverting to restabalize Revert "Bug 116 - Revisit SanityTest" This reverts commit effdf86b58e39060b75e6090596b123ec6e8ef69. Change-Id: Iff90bdb275681451952b9ab21eb0d04c07786be2 Signed-off-by: Ed Warnicke --- diff --git a/opendaylight/commons/controller-maven-plugin/pom.xml b/opendaylight/commons/controller-maven-plugin/pom.xml deleted file mode 100644 index 1ab4e7067b..0000000000 --- a/opendaylight/commons/controller-maven-plugin/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ - - 4.0.0 - - - org.opendaylight.controller - commons.opendaylight - 1.4.1-SNAPSHOT - ../../commons/opendaylight - - - controller-maven-plugin - 0.1.0-SNAPSHOT - maven-plugin - - controller-maven-plugin - Maven Plugin for controlling the launch of the controller. - http://maven.apache.org - - - UTF-8 - - - - - - org.apache.maven - maven-plugin-api - 2.0 - - - - org.apache.maven.plugin-tools - maven-plugin-annotations - 3.2 - provided - - - - com.sun - tools - system - 7 - ${java.home}/../lib/tools.jar - - - junit - junit - 4.8.1 - test - - - - - - - - org.apache.maven.plugins - maven-plugin-plugin - 3.2 - - controller-maven-plugin - true - - - - mojo-descriptor - - descriptor - - - - help-goal - - helpmojo - - - - - - - - diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/AbstractControllerMojo.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/AbstractControllerMojo.java deleted file mode 100644 index 39ca71c62c..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/AbstractControllerMojo.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.maven.plugin; - -import java.io.File; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Parameter; - -import org.opendaylight.controller.maven.plugin.util.JavaProcess; -import org.opendaylight.controller.maven.plugin.util.ProcessMonitor; - -/** - * Base controller mojo which handles common operations - */ -public abstract class AbstractControllerMojo extends AbstractMojo { - public static final String OS_NAME = System.getProperty("os.name"); - public static final boolean WIN = OS_NAME.toUpperCase().contains("WINDOWS"); - public static final String JAVA_HOME = "JAVA_HOME"; - public static final boolean skip = Boolean.getBoolean("controller.startup.skip"); - public static final String MAIN_CLASS = "org.eclipse.equinox.launcher.Main"; - public static final String CTRL_PROP = "opendaylight.controller"; - - /** - * The home directory where controller is installed - */ - @Parameter( required = false ) - protected File controllerHome; - - /** - * The address on which controller is listening - */ - @Parameter( defaultValue = "localhost") - protected String controllerHost; - - /** - * The admin web port - */ - @Parameter( defaultValue = "8080") - protected int controllerWebPort; - - /** - * The openflow port - */ - @Parameter( defaultValue = "6633") - protected int controllerOFPort; - - /** - * Additional environment variables passed when starting the controller - * process. - */ - @Parameter(required = false) - protected Properties controllerShellVariables; - - /** - * The script name to invoke - */ - @Parameter(required = false) - protected String controllerStartScriptName; - - /** - * The username - */ - @Parameter(required = false) - protected String controllerUsername; - - /** - * The password - */ - @Parameter(required = false) - protected String controllerPassword; - - /** - * pidFile location - */ - @Parameter(required = false) - protected File pidFile; - - protected final ProcessMonitor procMon = ProcessMonitor.load(); - - public abstract void start() throws MojoExecutionException, MojoFailureException; - - public void execute() throws MojoExecutionException, MojoFailureException { - if (skip) return; - validateArgs(); - start(); - } - - protected URL getWebUrl() { - try { - return new URL("http", controllerHost, controllerWebPort, "/"); - } catch (MalformedURLException e) { - throw new IllegalArgumentException( - "controller host:port is Malformed: " + controllerHost + " " + controllerWebPort, e); - } - - } - - protected void validateArgs() throws IllegalArgumentException { - // System property and environment variable override the default setting - String odlHome = System.getProperty("controllerHome"); - if (odlHome != null) { - controllerHome = new File(odlHome); - } - if (controllerHome == null) { - getLog().error("controllerHome cannot be determined from controllerHome " - + "property or ONE_HOME env variable"); - throw new IllegalArgumentException("controllerHome cannot be determined."); - } - if (!controllerHome.exists()) { - throw new IllegalArgumentException( - "controllerHome does not exist: " + controllerHome); - } - if (controllerUsername == null) { - controllerUsername = System.getProperty("controllerUsername"); - } - if (controllerPassword == null) { - controllerPassword= System.getProperty("controllerPassword"); - } - URL u = getWebUrl(); - getLog().info("Controller Home : " + controllerHome); - getLog().info("Controller Url : " + u); - getLog().info("Controller credentials: " + controllerUsername - + "/" + controllerPassword); - } - - protected Process invokeScript(List args, String log) - throws MojoFailureException, MojoExecutionException - { - ProcessBuilder pb = new ProcessBuilder(); - List cmd = new ArrayList(); - cmd.add(getScript()); - if (args != null) { - for (String s : args) { - // on windows args containing equals symbols need to be quoted - if (WIN && s.contains("=") && !s.startsWith("\"")) { - cmd.add("\"" + s + "\""); - } else { - cmd.add(s); - } - } - } - pb.command(cmd); - pb.directory(controllerHome); - pb.redirectErrorStream(true); - pb.inheritIO(); - Map env = pb.environment(); - if (controllerShellVariables != null) { - for (Enumeration e = controllerShellVariables.propertyNames(); e.hasMoreElements();) { - String n = (String) e.nextElement(); - env.put(n, controllerShellVariables.getProperty(n)); - } - } - String jh = env.get(JAVA_HOME); - if (jh == null) env.put(JAVA_HOME, System.getProperty("java.home")); - try { - getLog().info("Invoking process " + pb.command()); - return pb.start(); - } catch (IOException e) { - throw new MojoExecutionException(e.getMessage()); - } - } - - private String getScript() throws MojoFailureException { - File script = null; - if (controllerStartScriptName != null && !"".equals(controllerStartScriptName) ) { - script = new File(controllerStartScriptName); - if (!script.exists()) { - // try relative path - script = new File(controllerHome, controllerStartScriptName); - } - if (script.exists()) return script.getAbsolutePath(); - throw new MojoFailureException("Script not found: " + controllerStartScriptName); - } - // try default - script = new File(controllerHome, "run." + (WIN ? "bat" : "sh") ); - if (script.exists()) return script.getAbsolutePath(); - throw new MojoFailureException("Cannot find a default script to launch."); - } - - protected boolean canConnect() { - try { - URL url = getWebUrl(); - HttpURLConnection con; - con = (HttpURLConnection) url.openConnection(); - return (con.getResponseCode() > 0); - } catch (IOException e) { - return false; - } - } - - public void killControllers() { - getLog().info("Checking environment for stray processes."); - List jvms = procMon.getProcesses(MAIN_CLASS, CTRL_PROP); - for (JavaProcess j : jvms) { - getLog().info("Killing running process: " + j); - ProcessMonitor.kill(j.getPid()); - } - // cleanup pid files - getLog().info("Checking left over pid file: " + pidFile); - if (pidFile != null && pidFile.exists()) { - getLog().info("Cleaning up pid file : " + pidFile); - pidFile.delete(); - } - } - - public boolean isControllerRunning() { - return !procMon.getProcesses(MAIN_CLASS, CTRL_PROP).isEmpty(); - } - -} diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StartControllerMojo.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StartControllerMojo.java deleted file mode 100644 index 0a3bee42f4..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StartControllerMojo.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.maven.plugin; - -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - - -/** - * Starts the controller - */ -@Mojo( name = "run", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST ) -public class StartControllerMojo extends AbstractControllerMojo { - public static final String REDIRECT_LOG = "controller.out"; - - /** - * The timeout value for starting the controller. Defaults to 60 secs - */ - @Parameter(defaultValue = "60") - public int timeoutSecs = 60; - - /** - * The startArgs for starting the controller - */ - @Parameter(required = false) - protected List startArgs = new ArrayList(); - - /** - * The time to wait after successfully connecting to the controller and - * before returning from execution. - */ - @Parameter(required = false) - protected int warmupTimeSecs = 10; - - - @Override - public void start() throws MojoExecutionException, MojoFailureException { - killControllers(); - // if we can still connect to a controller, bail out - if (canConnect()) { - getLog().error("A controller is already running. Shutdown and retry."); - throw new MojoFailureException("Controller is already running."); - } - startArgs.add("-D" + CTRL_PROP); - Process process = invokeScript(startArgs, REDIRECT_LOG); - getLog().info("Controller starting... (waiting for open ports)"); - try { - waitForListening(process); - getLog().info("Controller port open. Waiting for warmup: " - + warmupTimeSecs); - Thread.sleep(warmupTimeSecs*1000); - } catch (Exception e) { - throw new MojoExecutionException(e.getMessage()); - } - getLog().info("Controller started successfully."); - } - - protected boolean waitForListening(Process process) - throws MalformedURLException, InterruptedException, MojoExecutionException - { - long timeElapsedMillis = 0L; - long sleepTimeMillis = 2000L; // 2 secs - long timeoutMillis = timeoutSecs * 1000; - - while (timeElapsedMillis < timeoutMillis) { - long timeRemaining = timeoutMillis - timeElapsedMillis; - sleepTimeMillis *= 2; - long toSleep = (sleepTimeMillis > timeRemaining) - ? timeRemaining : sleepTimeMillis; - Thread.sleep(toSleep); - timeElapsedMillis += toSleep; - if (canConnect()) { - return true; - } - if (!isControllerRunning()) { - throw new MojoExecutionException("Process seems to have exited prematurely."); - } - } - return false; - } -} diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StopControllerMojo.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StopControllerMojo.java deleted file mode 100644 index 579778d150..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/StopControllerMojo.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.maven.plugin; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Stop controller - */ -@Mojo( name = "stop", defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST ) -public class StopControllerMojo extends AbstractControllerMojo { - private static final boolean SKIP_STOP = Boolean.getBoolean("skipControllerStop"); - - @Override - public void start() throws MojoExecutionException, MojoFailureException { - if (SKIP_STOP) { - getLog().info("Controller STOP is skipped per configuration " + - "(-DskipControllerStop=true)."); - return; - } - if (canConnect()) { - List args = new ArrayList(); - args.add("-stop"); - Process proc = invokeScript(args, null); - try { - int status = proc.waitFor(); - if (status == 0) { - getLog().info("Controller stopped."); - } else { - getLog().error("Error stopping controller. See stdout log for details."); - } - } catch (InterruptedException ie) { - throw new MojoExecutionException("Error stopping controller : " + ie.getMessage()); - } - } else { - getLog().info("Controller not running."); - } - // cleanup for any hung processes - killControllers(); - } - -} diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JavaProcess.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JavaProcess.java deleted file mode 100644 index 95da34ffad..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JavaProcess.java +++ /dev/null @@ -1,57 +0,0 @@ - -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.maven.plugin.util; - -import java.util.Properties; - -public class JavaProcess { - private final int pid; - private final String mainClass; - private final Properties systemProperties = new Properties(); - - public JavaProcess(int id, String cls) { - this.pid = id; - this.mainClass = cls; - } - - public void setSystemProperties(String line) { - if (line == null || line.length() == 0) return; - String[] tokens = line.split("\\s"); - for (String t : tokens) setSystemProperty(t); - } - - public void setSystemProperty(String line) { - if (line.startsWith("-D")) { - int x = line.indexOf('='); - if (x > -1) { - systemProperties.put(line.substring(2, x), line.substring(x+1)); - } else { - systemProperties.put(line.substring(2), ""); - } - } - } - - public int getPid() { - return pid; - } - - public String getMainClass() { - return mainClass; - } - - public Properties getSystemProperties() { - return systemProperties; - } - - @Override - public String toString() { - return "pid:" + pid + " class:" + mainClass + - " system-properties:" + systemProperties.toString(); - } -} diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JpsProcessMonitor.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JpsProcessMonitor.java deleted file mode 100644 index 8474266df2..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/JpsProcessMonitor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.maven.plugin.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -/** - * Uses JPS tool to monitor java local processes - */ -public class JpsProcessMonitor extends ProcessMonitor { - private final String jpsTool; - - public JpsProcessMonitor() { - String jh = System.getProperty("java.home"); - File jps = new File(jh + SEP + "bin" + SEP + "jps"); - if (!jps.exists()) { - // try one dir above - jps = new File(jh + SEP + ".." + SEP + "bin" + SEP + "jps"); - if (!jps.exists()) { - throw new IllegalStateException("jps tool cannot be located."); - } - } - jpsTool = jps.getAbsolutePath(); - } - - @Override - public List getProcesses() { - if (jpsTool == null) return super.getProcesses(); - List jvms = new ArrayList(); - try { - ProcessBuilder pb = new ProcessBuilder(); - pb.command(new String[] { jpsTool, "-mlvV"} ); - pb.redirectErrorStream(true); - Process process = pb.start(); - BufferedReader br = new BufferedReader( - new InputStreamReader(process.getInputStream())); - String line = null; - while ( (line = br.readLine()) != null) { - JavaProcess j = parseLine(line); - if (j != null) jvms.add(j); - } - } catch (Exception e) { - e.printStackTrace(); - } - return jvms; - } - - public static JavaProcess parseLine(String line) { - String[] tokens = line.split("\\s"); - if (tokens.length < 2) { - System.out.println("Unable to parse line: " + line); - return null; - } - int idx = 0; - int pid = Integer.parseInt(tokens[idx++]); - String mainClass = ""; - if (!tokens[idx].startsWith("-")) { - mainClass = tokens[idx++]; - } - JavaProcess proc = new JavaProcess(pid, mainClass); - for (int i=idx; i -1; - - - - public void log(String msg) { - System.out.println("" + msg); - } - - public List getProcesses() { - return Collections.emptyList(); - } - - public List getProcesses(String mainClass, String systemPropertyKey) { - List result = new ArrayList(); - for (JavaProcess info : getProcesses()) { - if (info.getMainClass().equals(mainClass)) { - if (info.getSystemProperties().containsKey(systemPropertyKey)) { - result.add(info); - } - } - } - return result; - } - - public int kill(String mainClass) { - for (JavaProcess info : getProcesses()) { - if (info.getMainClass().equals(mainClass)) { - log("Killing process matching class: " + mainClass); - return kill(info.getPid()); - } - } - return -1; - } - - public static int kill(int pid) { - String cmd = WIN ? "TASKKILL /F /PID " + pid : "kill -SIGTERM " + pid; - try { - Process p = Runtime.getRuntime().exec(cmd); - p.waitFor(); - return p.exitValue(); - } catch (Exception e) { - e.printStackTrace(); - return -1; - } - } - - public static ProcessMonitor load() { - // load the providers dynamically to allow error handling - ProcessMonitor pm = load("org.opendaylight.controller.maven.plugin.util.VMProcessMonitor"); - if (pm == null) { - pm = load("org.opendaylight.controller.maven.plugin.util.JpsProcessMonitor"); - } - return (pm == null ? new ProcessMonitor() : pm); - } - - private static ProcessMonitor load(String clz) { - try { - Class c = Class.forName(clz); - return (ProcessMonitor) c.newInstance(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - // simple driver for basic manual testing - public static void main(String[] args) throws Exception { - ProcessMonitor pm = ProcessMonitor.load(); - System.out.println("==== " + pm); - for (JavaProcess info : pm.getProcesses()) { - System.out.println(info.toString()); - } - pm.kill("Foo"); - System.out.println("==== controller processses "); - for (JavaProcess info : pm.getProcesses( - "org.eclipse.equinox.launcher.Main", "opendaylight.controller")) - { - System.out.println(info.toString()); - pm.kill(info.getPid()); - } - } - -} diff --git a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/VMProcessMonitor.java b/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/VMProcessMonitor.java deleted file mode 100644 index fdf232a63c..0000000000 --- a/opendaylight/commons/controller-maven-plugin/src/main/java/org/opendaylight/controller/maven/plugin/util/VMProcessMonitor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.maven.plugin.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import sun.jvmstat.monitor.HostIdentifier; -import sun.jvmstat.monitor.MonitoredHost; -import sun.jvmstat.monitor.MonitoredVm; -import sun.jvmstat.monitor.MonitoredVmUtil; -import sun.jvmstat.monitor.VmIdentifier; - -public class VMProcessMonitor extends ProcessMonitor { - - @Override - public List getProcesses() { - Set activeVmPids = null; - List result = new ArrayList(); - MonitoredHost monitoredHost = null; - MonitoredVm mvm = null; - try { - monitoredHost = MonitoredHost.getMonitoredHost( - new HostIdentifier((String) null)); - activeVmPids = monitoredHost.activeVms(); - } catch (Exception e) { - throw new IllegalStateException("Error accessing VM", e); - } - for (Integer vmPid : activeVmPids) { - try { - mvm = monitoredHost.getMonitoredVm( - new VmIdentifier(vmPid.toString())); - JavaProcess proc = new JavaProcess(vmPid, - MonitoredVmUtil.mainClass(mvm, true)); - proc.setSystemProperties(MonitoredVmUtil.jvmArgs(mvm)); - proc.setSystemProperties(MonitoredVmUtil.jvmFlags(mvm)); - result.add(proc); - } catch(Exception e2) { - log("Error connecting to pid: " + vmPid + " reason:" - + e2.getMessage()); - e2.printStackTrace(); - } finally { - if (mvm != null) { - mvm.detach(); - } - } - } - return result; - } - - -} diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 07c89166f9..dd73815b34 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -70,8 +70,6 @@ 0.5.3.201107060350 1.3.1 2.3.7 - 2.5 - 1.3.1 4.8.1 0.3.0-SNAPSHOT 0.5.9-SNAPSHOT diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 033d0573f9..4c0b81f7d7 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -461,7 +461,6 @@ - integrationtests false @@ -470,41 +469,57 @@ org.apache.maven.plugins - maven-invoker-plugin - 1.5 + maven-dependency-plugin + 2.8 + + + copy + package + + copy + + + - false - ../sanitytest - - pom.xml - - true - true - - clean - verify - - - - - integration-test - - install - run - - - - + + + org.opendaylight.controller + sanitytest + ${controller.version} + jar + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + sanity-test + package + + exec + + + + + ${java.home}/bin/java + + -cp + ./target/dependency/* + org.opendaylight.controller.distribution.Sanity + + + + ${java.home} + + + + - - - - org.opendaylight.controller - controller-maven-plugin - 0.1.0-SNAPSHOT - - @@ -1332,6 +1347,13 @@ ${commons.httpclient.version} + + org.opendaylight.controller + sanitytest + ${controller.version} + + + @@ -1374,8 +1396,6 @@ - - diff --git a/opendaylight/distribution/opendaylight/runsanity.bat b/opendaylight/distribution/opendaylight/runsanity.bat new file mode 100644 index 0000000000..f219828bad --- /dev/null +++ b/opendaylight/distribution/opendaylight/runsanity.bat @@ -0,0 +1,23 @@ +rem Inject the sanitytest jar as a controller plugin +copy .\target\dependency\sanitytest*.jar .\target\distribution.opendaylight-osgipackage\opendaylight\plugins + +rem Store the current working directory in a variable so that we can get back to it later +set cwd=%cd% + +rem Switch to the distribution folder +cd .\target\distribution.opendaylight-osgipackage\opendaylight + +rem Run the controller +cmd.exe /c run.bat + +rem Store the exit value of the controller in a variable +set success=%ERRORLEVEL% + +rem Switch back to the directory from which this script was invoked +cd %cwd% + +rem Remove the sanitytest jar from the plugins directory +del .\target\distribution.opendaylight-osgipackage\opendaylight\plugins\sanitytest*.jar + +rem Exit using the exit code that we had captured earlier after running the controller +exit /b %SUCCESS% \ No newline at end of file diff --git a/opendaylight/distribution/opendaylight/runsanity.sh b/opendaylight/distribution/opendaylight/runsanity.sh new file mode 100755 index 0000000000..4ee9555b97 --- /dev/null +++ b/opendaylight/distribution/opendaylight/runsanity.sh @@ -0,0 +1,24 @@ +# Inject the sanitytest jar as a controller plugin +cp ./target/dependency/sanitytest*.jar ./target/distribution.opendaylight-osgipackage/opendaylight/plugins + +# Store the current working directory in a variable so that we can get back to it later +cwd=`pwd` + +# Switch to the distribution folder +cd ./target/distribution.opendaylight-osgipackage/opendaylight/ + +# Run the controller +./run.sh + +# Store the exit value of the controller in a variable +success=`echo $?` + +# Switch back to the directory from which this script was invoked +cd $cwd + +# Remove the sanitytest jar from the plugins directory +rm ./target/distribution.opendaylight-osgipackage/opendaylight/plugins/sanitytest*.jar + +# Exit using the exit code that we had captured earlier after running the controller +exit $success + diff --git a/opendaylight/distribution/opendaylight/src/assemble/bin.xml b/opendaylight/distribution/opendaylight/src/assemble/bin.xml index 1e8f34e5b7..8fea175614 100644 --- a/opendaylight/distribution/opendaylight/src/assemble/bin.xml +++ b/opendaylight/distribution/opendaylight/src/assemble/bin.xml @@ -27,6 +27,7 @@ com.sun.jersey:jersey-json com.sun.jersey:jersey-server org.opendaylight.controller:logging.bridge + org.opendaylight.controller:sanitytest ${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension} diff --git a/opendaylight/distribution/opendaylight/src/main/resources/run.bat b/opendaylight/distribution/opendaylight/src/main/resources/run.bat index a8e33d2632..9d6ac8d1de 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/run.bat +++ b/opendaylight/distribution/opendaylight/src/main/resources/run.bat @@ -140,7 +140,7 @@ SET RUN_CMD="%JAVA_HOME%\bin\java.exe" -Dopendaylight.controller %extraJVMOpts% ECHO %RUN_CMD% if "%startEnabled%" NEQ "" ( - START /B cmd /C CALL %RUN_CMD% + START /B cmd /C CALL %RUN_CMD% > %basedir%\logs\controller.out 2>&1 ECHO Running controller in the background. ) else ( %RUN_CMD% diff --git a/opendaylight/distribution/sanitytest/pom.xml b/opendaylight/distribution/sanitytest/pom.xml index ce710d120e..9d5ba5cc95 100644 --- a/opendaylight/distribution/sanitytest/pom.xml +++ b/opendaylight/distribution/sanitytest/pom.xml @@ -16,153 +16,43 @@ sanitytest 0.4.1-SNAPSHOT - jar - - - ${project.basedir}/../opendaylight/target/distribution.opendaylight-osgipackage/opendaylight - ${distro.dir}/run.bat - - 127.0.0.1 - 300 - - - - - non-windows - - - !windows - - - - ${distro.dir}/run.sh - /tmp/opendaylight.PID - - - - + bundle org.osgi org.osgi.core provided - - - junit - junit - test - - - - org.ow2.chameleon.management - chameleon-mbeans - test - - - - - org.apache.maven.plugins - maven-install-plugin - ${install.plugin.version} + org.apache.felix + maven-bundle-plugin + ${bundle.plugin.version} + true - true + + + org.opendaylight.controller.sanitytest + + + javax.xml.bind.annotation, + org.osgi.service.component, + org.slf4j, + org.eclipse.osgi.framework.console, + org.osgi.framework, + org.eclipse.osgi.baseadaptor, + org.eclipse.osgi.framework.adaptor, + org.osgi.framework.wiring + + + org.opendaylight.controller.sanitytest.internal.Activator + + + ${project.basedir}/META-INF - - - default-install - none - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - ${enforcer.plugin.version} - - - enforce-files-exist - pre-integration-test - - enforce - - - - - - ${distro.script} - - - - true - - - - - - - org.opendaylight.controller - controller-maven-plugin - 0.1.0-SNAPSHOT - - ${distro.dir} - localhost - 8080 - admin - admin - ${distro.script} - ${distro.pid} - - - - - start-controller - pre-integration-test - - - -start - -jmx - -Djava.rmi.server.hostname=${sanitytest.bind.address} - - 60 - - - run - - - - - stop-controller - post-integration-test - - stop - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${failsafe.version} - - - ${distro.dir} - ${sanitytest.bind.address} - ${sanitytest.timeout} - - - - - - diff --git a/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/distribution/Sanity.java b/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/distribution/Sanity.java new file mode 100644 index 0000000000..7fc25e2b81 --- /dev/null +++ b/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/distribution/Sanity.java @@ -0,0 +1,48 @@ +package org.opendaylight.controller.distribution; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.ArrayList; +import java.util.List; + +public class Sanity { + + static void copy(InputStream in, OutputStream out) throws IOException { + while (true) { + int c = in.read(); + if (c == -1) break; + out.write((char)c); + } + } + + public static void main(String[] args) throws IOException, InterruptedException { + String cwd = System.getProperty("user.dir"); + + System.out.println("Current working directory = " + cwd); + + String os = System.getProperty("os.name").toLowerCase(); + List script = new ArrayList(); + + if(os.contains("windows")){ + script.add("cmd.exe"); + script.add("/c"); + script.add("runsanity.bat"); + } else { + script.add("./runsanity.sh"); + } + + ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.inheritIO().command(script); + Process p = processBuilder.start(); + + copy(p.getInputStream(), System.out); + + p.waitFor(); + + System.out.println("Test exited with exitValue = " + p.exitValue()); + + System.exit(p.exitValue()); + } +} diff --git a/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/sanitytest/internal/Activator.java b/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/sanitytest/internal/Activator.java new file mode 100644 index 0000000000..08f0700168 --- /dev/null +++ b/opendaylight/distribution/sanitytest/src/main/java/org/opendaylight/controller/sanitytest/internal/Activator.java @@ -0,0 +1,101 @@ +package org.opendaylight.controller.sanitytest.internal; + +import java.util.Timer; +import java.util.TimerTask; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.wiring.BundleRevision; + +public class Activator implements BundleActivator { + //10 Second initial, 1 second subsequent + private static final int INITIAL_DELAY = 10000; + private static final int SUBSEQUENT_DELAY = 1000; + private static final int MAX_ATTEMPTS = 120; + + + private String stateToString(int state) { + switch (state) { + case Bundle.ACTIVE: + return "ACTIVE"; + case Bundle.INSTALLED: + return "INSTALLED"; + case Bundle.RESOLVED: + return "RESOLVED"; + case Bundle.UNINSTALLED: + return "UNINSTALLED"; + case Bundle.STARTING: + return "STARTING"; + default: + return "Not CONVERTED: state value is " + state; + } + } + + public void start(final BundleContext bundleContext) throws Exception { + Timer monitorTimer = new Timer("monitor timer", true); + monitorTimer.schedule(new TimerTask() { + @Override + public void run() { + int countup = 0; + boolean failed = false; + boolean resolved = false; + while (!resolved) { + resolved = true; + failed = false; + for(Bundle bundle : bundleContext.getBundles()){ + /* + * A bundle should be ACTIVE, unless it a fragment, in which case it should be RESOLVED + */ + int state = bundle.getState(); + if ((bundle.adapt(BundleRevision.class).getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { + //fragment + if (state != Bundle.RESOLVED) { + System.out.println("------ Failed to activate/resolve fragment = " + bundle.getSymbolicName() + " state = " + stateToString(bundle.getState())); + failed = true; + if (state == Bundle.STARTING) + resolved = false; + } + } else { + if(state != Bundle.ACTIVE) { + System.out.println("------ Failed to activate/resolve bundle = " + bundle.getSymbolicName() + " state = " + stateToString(bundle.getState())); + failed = true; + if (state == Bundle.STARTING) + resolved = false; + } + } + } + if (!resolved) { + countup++; + if (countup < MAX_ATTEMPTS) { + System.out.println("all bundles haven't finished starting, will repeat"); + try { + Thread.sleep(SUBSEQUENT_DELAY); + } catch (Exception e) { + System.out.println("Thread.sleep interuptted."); + break; + } + } else + resolved = true; + } + } + + if(failed){ + System.out.flush(); + System.out.println("exiting with 1 as failed"); + System.out.close(); + Runtime.getRuntime().exit(1); + } else { + System.out.flush(); + System.out.println("exiting with 0 as succeeded"); + System.out.close(); + Runtime.getRuntime().exit(0); + } + } + }, INITIAL_DELAY); + } + + public void stop(BundleContext bundleContext) throws Exception { + + } +} diff --git a/opendaylight/distribution/sanitytest/src/test/java/org/opendaylight/controller/distribution/test/SanityIT.java b/opendaylight/distribution/sanitytest/src/test/java/org/opendaylight/controller/distribution/test/SanityIT.java deleted file mode 100644 index 931e88fc4f..0000000000 --- a/opendaylight/distribution/sanitytest/src/test/java/org/opendaylight/controller/distribution/test/SanityIT.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.distribution.test; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.Socket; -import java.net.URL; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; -import java.util.jar.Attributes; -import java.util.jar.JarFile; - -import javax.management.JMX; -import javax.management.MBeanServerConnection; -import javax.management.Notification; -import javax.management.NotificationListener; -import javax.management.ObjectName; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.osgi.framework.Bundle; -import org.osgi.framework.Constants; -import org.ow2.chameleon.management.beans.BundleMXBean; -import org.ow2.chameleon.management.beans.OSGiPlatformMXBean; - -/** - * This integration test assumes a running local controller. The test does the - * following: - * 1) Wait for HTTP, JMX and OF ports to open - * 2) Establishes a JMX connection and registers a bundle notification listener - * 3) Waits till all bundles reach expected states or the timeout period elapses - */ -public class SanityIT { - private static final int OF_PORT = Integer.getInteger("ctrl.of.port", 6633); - private static final int HTTP_PORT = Integer.getInteger("ctrl.http.port", 8080); - private static final int JMX_PORT = Integer.getInteger("ctrl.jmx.port", 1088); - private static final int RMI_PORT = Integer.getInteger("ctrl.rmi.port", 1099); - private static final String CTRL_HOST = System.getProperty("ctrl.host", "127.0.0.1"); - private static final String CTRL_HOME = System.getProperty("ctrl.home"); - private static final long TIMEOUT_MILLIS = - Integer.getInteger("ctrl.start.timeout", 3*60) * 1000L; - private static final String JMX_URL = - "service:jmx:rmi:///jndi/rmi://" + CTRL_HOST + ":" + JMX_PORT + "/jmxrmi"; - - private static final Set bundles = - Collections.synchronizedSet(new HashSet()); - private static final Set fragments = - Collections.synchronizedSet(new HashSet()); - - @BeforeClass - public static void loadBundles() throws IOException { - log(" ctrl.home: " + CTRL_HOME); - log(" ctrl.host: " + CTRL_HOST); - log("ctrl.start.timeout: " + TIMEOUT_MILLIS); - log(" jmx.url: " + JMX_URL); - - Assert.assertNotNull(CTRL_HOME); - File ctrlHome = new File(CTRL_HOME); - Assert.assertTrue(ctrlHome.exists() && ctrlHome.isDirectory()); - File configDir = new File(ctrlHome, "configuration"); - Assert.assertTrue(configDir.exists() && configDir.isDirectory()); - File configIni = new File(configDir, "config.ini"); - Assert.assertTrue(configIni.exists()); - Properties config = new Properties(); - config.load(new FileInputStream(configIni)); - processBundles(configDir, config.getProperty("osgi.bundles")); - processBundles(new File(ctrlHome, "plugins")); - log("Bundles found in installation: " + bundles.size()); - log("Fragments found in installation: " + fragments.size()); - } - -@Test - public void sanityTest() throws Exception { - // wait for http, jmx & of ports to open - long startTime = System.currentTimeMillis(); - waitForListening(OF_PORT, false, startTime); - waitForListening(JMX_PORT, false, startTime); - waitForListening(HTTP_PORT, false, startTime); - - // open jmx connection - JMXServiceURL serviceUrl = new JMXServiceURL(JMX_URL); - JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null); - final MBeanServerConnection conn = jmxConnector.getMBeanServerConnection(); - - ObjectName fmkName = new ObjectName("org.ow2.chameleon:type=framework"); - OSGiPlatformMXBean fmkBean= JMX.newMBeanProxy(conn, fmkName, - OSGiPlatformMXBean.class, true); - conn.addNotificationListener(fmkName, new NotificationListener() { - - @Override - public void handleNotification(Notification n, Object handback) { - try { - //log("Notification: source: " + n.getSource()); - ObjectName bundleName = new ObjectName( - "org.ow2.chameleon:type=bundle,id=" + n.getUserData()); - BundleMXBean bundleBean = JMX.newMXBeanProxy(conn, - bundleName, BundleMXBean.class, true); - log("Bundle state change: " + bundleBean.getSymbolicName() + - " : " + stateToString(bundleBean.getState())); - handleBundleEvent(bundleBean); - // if its a system bundle, notify the main thread - if (bundleBean.getBundleId() == 0 && - bundleBean.getState() == Bundle.ACTIVE) - { - synchronized(SanityIT.this) { - SanityIT.this.notify(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }, null, null); - - if (checkAllBundles(conn) > 0) { - log("Waiting for system bundle to start... (times out in: " + TIMEOUT_MILLIS + "ms)"); - long timeElapsed = System.currentTimeMillis() - startTime; - synchronized(this) { - this.wait(TIMEOUT_MILLIS - timeElapsed); - } - log("System bundle started. Revalidating bundle states for all bundles..."); - - // Sometimes, the system bundle starts earlier than other bundles(?). The - // following loop will cover that case. - do { - Thread.sleep(2000); // 2s seems appropriate given the default timeout - if (checkAllBundles(conn) == 0) { - break; - } - } while(System.currentTimeMillis() - startTime < TIMEOUT_MILLIS); - } - try { - jmxConnector.close(); - } catch (Exception ignore) { - // dont want the tests to fail in case we can't close jmx connection - ignore.printStackTrace(); - } - if (bundles.size() + fragments.size() == 0) { - log("All bundles have reached expected state"); - } else { - log("The following bundles did not reach expected state: "); - for (String s : bundles) log("Bundle: " + s); - for (String s : fragments) log("Fragment: " + s); - - } - Assert.assertTrue(bundles.size() == 0 && fragments.size() == 0); - } - - private static int checkAllBundles(MBeanServerConnection conn) throws Exception { - ObjectName allBundlesName = new ObjectName("org.ow2.chameleon:*"); - Set bundleNames = conn.queryNames(allBundlesName, null); - for (ObjectName bundleName : bundleNames) { - if ("bundle".equals(bundleName.getKeyProperty("type"))) { - BundleMXBean bundleBean = JMX.newMBeanProxy(conn, bundleName, - BundleMXBean.class, true); - handleBundleEvent(bundleBean); - } - } - int remaining = bundles.size() + fragments.size(); - if (remaining > 0) { - log("Bundles not in expected states: " + remaining + " Waiting..."); - } - return remaining; - } - - private synchronized static void handleBundleEvent(BundleMXBean bundleBean) { - String name = bundleBean.getSymbolicName(); - int state = bundleBean.getState(); - // BUG in BundleMXBeanImpl - can't get bundle headers :( - // String fragHost = bundleBean.getBundleHeaders().get(Constants.FRAGMENT_HOST); - if (bundles.contains(name) && (state == Bundle.RESOLVED || state == Bundle.ACTIVE)) { - bundles.remove(name); - } else if (fragments.contains(name) && state == Bundle.RESOLVED) { - fragments.remove(name); - } - //log("Bundles to be started: " + bundles.size()); - } - - - // reference\:file\:../lib/org.apache.felix.fileinstall-3.1.6.jar@1:start,\ - private static void processBundles(File dir, String property) { - Assert.assertTrue(property == null || property.length() > 0); - for(String s : property.split(",")) { - int idx = s.indexOf("@"); - s = s.substring(15, (idx == -1 ? s.length() : idx)); - if (!s.endsWith(".jar")) s = s + ".jar"; - processJar(new File(dir, s)); - } - } - - public static void processBundles(File dir) throws IOException { - if (!dir.exists()) throw new FileNotFoundException("Cannot find dir:" + dir); - dir.listFiles(new FileFilter() { - - @Override - public boolean accept(File file) { - //p("---- " + file); - if (file.getName().endsWith(".jar")) { - return processJar(file); - } - return false; - } - }); - } - - public static boolean processJar(File file) { - try { - //log("----" + file); - JarFile jar = new JarFile(file, false); - Attributes jarAttributes = jar.getManifest().getMainAttributes(); - String bundleName = jarAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME); - String fragHost = jarAttributes.getValue(Constants.FRAGMENT_HOST); - if (bundleName == null) { - log("Found a non bundle file:" + file); - return false; - } else { - int idx = bundleName.indexOf(';'); - if (idx > -1) { - bundleName = bundleName.substring(0, idx); - } - } - - if (fragHost == null) { - if (!bundles.add(bundleName)) { - throw new IllegalStateException( - "Found duplicate bundles with same symbolic name: " - + bundleName); - } - } else { - // fragments attaching to framework can't be detected - if (fragHost.contains("extension:=\"framework\"")) return false; - if (!fragments.add(bundleName)) { - throw new IllegalStateException( - "Found duplicate fragments with same symbolic name: " - + bundleName); - } - } - } catch (IOException e) { - throw new IllegalStateException("Error processing jar: " + file , e); - } - return true; - } - - public static long waitForListening(int port, boolean isHTTP, long beginTime) - throws InterruptedException { - long timeElapsedMillis = System.currentTimeMillis() - beginTime; - long sleepTimeMillis = 500L; // 0.5 secs - - while (timeElapsedMillis < TIMEOUT_MILLIS) { - long timeRemaining = TIMEOUT_MILLIS - timeElapsedMillis; - sleepTimeMillis *= 2; // exponential backoff - long toSleep = (sleepTimeMillis > timeRemaining) - ? timeRemaining : sleepTimeMillis; - Thread.sleep(toSleep); - timeElapsedMillis = System.currentTimeMillis() - beginTime; - if (isHTTP ? connectHTTP(port) : connectTCP(port)) { - log("Port is open: " + port); - return timeElapsedMillis; - } - } - throw new IllegalStateException("Timeout waiting for port: " + port); - } - - private static void log(String msg) { - System.out.format("[SanityIT] [%s] %s %s", new Date().toString(), msg, - System.lineSeparator()); - } - - public static boolean connectTCP(int port) { - String host = CTRL_HOST.length() == 0 ? null : CTRL_HOST; - try { - Socket sock = new Socket(host, port); - sock.getPort(); - try { - sock.close(); - } catch (IOException ignore) { - // Can't close socket. Ingore and let downstream validate health - } - return true; - } catch (IOException ioe) { - return false; - } - } - - public static boolean connectHTTP(int port) { - String host = CTRL_HOST.length() == 0 ? "localhost" : CTRL_HOST; - try { - URL url = new URL("http", host, port, "/"); - HttpURLConnection con; - con = (HttpURLConnection) url.openConnection(); - return (con.getResponseCode() > 0); - } catch (IOException e) { - return false; - } - } - - private String stateToString(int state) { - switch (state) { - case Bundle.ACTIVE: return "ACTIVE"; - case Bundle.INSTALLED: return "INSTALLED"; - case Bundle.RESOLVED: return "RESOLVED"; - case Bundle.UNINSTALLED: return "UNINSTALLED"; - case Bundle.STARTING: return "STARTING"; - case Bundle.STOPPING: return "STOPPING"; - default: return "UNKNOWN: " + state; - } - } - - - - -} diff --git a/pom.xml b/pom.xml index 6ece420d5a..f7f9bc2256 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,6 @@ opendaylight/commons/opendaylight opendaylight/commons/parent opendaylight/commons/logback_settings - opendaylight/commons/controller-maven-plugin @@ -150,6 +149,7 @@ opendaylight/statisticsmanager/integrationtest opendaylight/commons/integrationtest opendaylight/containermanager/it.implementation + opendaylight/distribution/sanitytest/