Package org.cloudfoundry.ide.eclipse.server.tests.sts.util

Source Code of org.cloudfoundry.ide.eclipse.server.tests.sts.util.ManagedTestSuite$ShutdownWatchdog

/*******************************************************************************
* Copyright (c) 2012, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License,
* Version 2.0 (the "License�); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.tests.sts.util;

import java.net.ProxySelector;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;

import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestFailure;
import junit.framework.TestListener;
import junit.framework.TestResult;
import junit.framework.TestSuite;

import org.cloudfoundry.ide.eclipse.server.tests.util.CloudFoundryTestUtil;
import org.eclipse.core.internal.jobs.JobManager;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

/**
* Prints the name of each test to System.err when it started and dumps a stack
* trace of all thread to System.err if a test takes longer than 10 minutes.
*
* Copied from:
*
* com.springsource.tests.util.ManagedTestSuite
*
*
* @author Steffen Pingel
* @author Kris De Volder
* @see com.springsource.tests.util.ManagedTestSuite
*/
public class ManagedTestSuite extends TestSuite {

  private class DumpThreadTask extends TimerTask {

    private final Test test;

    private final Thread testThread;

    public DumpThreadTask(Test test, Thread testThread) {
      this.test = test;
      this.testThread = testThread;
    }

    private void dumpJobs() {
      StringBuffer sb = new StringBuffer();
      sb.append(MessageFormat.format("Jobs:\n", test.toString()));
      Job[] jobs = Job.getJobManager().find(null);
      for (Job job : jobs) {
        sb.append(job.getName().toString());
        sb.append(" [");
        sb.append(JobManager.printState(job.getState()));
        sb.append(", ");
        sb.append(job.getClass().getName());
        sb.append("]");
        sb.append("\n");
      }
      System.err.println(sb.toString());
    }

    @Override
    public void run() {
      // dump all thread for diagnosis
      StringBuffer sb = new StringBuffer();
      sb.append(MessageFormat.format("Test {0} is taking too long:\n", test.toString()));
      Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
      for (Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
        sb.append(entry.getKey().toString());
        sb.append("\n");
        for (StackTraceElement element : entry.getValue()) {
          sb.append("  ");
          sb.append(element.toString());
          sb.append("\n");
        }
        sb.append("\n");
      }
      System.err.println(sb.toString());

      dumpJobs();

      // killTest("Test is taking too long");

      // attempt to close any modal dialogs
      if (test instanceof ShutdownWatchdog) {
        Display.getDefault().asyncExec(new Runnable() {
          public void run() {
            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            if (window != null) {
              Shell shell = window.getShell();
              Shell[] shells = window.getShell().getDisplay().getShells();
              for (Shell child : shells) {
                if (child != shell) {
                  child.close();
                }
              }
            }
          }
        });
      }
    }

    @SuppressWarnings("deprecation")
    private void killTest(String debugInfo) {
      try {
        // Yes, the stop method is deprecated, but I don't know another
        // way to attempt to stop a runaway test without the cooperation
        // of the test/thread itself. This may not work as desired in
        // all cases, but is almost certainly better than leaving the
        // "stuck" test hanging.
        System.err.println("[TIMEOUT] " + test);
        testThread.stop(new Error(debugInfo));
      }
      catch (Throwable e) {
        e.printStackTrace();
      }
    }
  };

  private class Listener implements TestListener {

    private DumpThreadTask task;

    private final Timer timer = new Timer(true);

    public void addError(Test test, Throwable t) {
      System.err.println("[ERROR]");
    }

    public void addFailure(Test test, AssertionFailedError t) {
      System.err.println("[FAILURE]");
    }

    private void dumpList(String header, Enumeration<TestFailure> failures) {
      System.err.println(header);
      while (failures.hasMoreElements()) {
        TestFailure failure = failures.nextElement();
        System.err.print("  ");
        System.err.println(failure.toString());
      }
    }

    public void dumpResults(TestResult result) {
      System.err.println();
      dumpList("Failures: ", result.failures());

      System.err.println();
      dumpList("Errors: ", result.errors());

      int failedCount = result.errorCount() + result.failureCount();
      System.err.println();
      System.err.println(MessageFormat.format("{0} out of {1} tests failed", failedCount, result.runCount()));
    }

    public void endTest(Test test) {
      if (task != null) {
        task.cancel();
        task = null;
      }
    }

    public void startTest(Test test) {
      Thread testThread = Thread.currentThread();
      System.err.println("Running " + test.toString());
      task = new DumpThreadTask(test, testThread);
      timer.schedule(task, DELAY);
    }

  }

  public class ShutdownWatchdog implements Test {

    public int countTestCases() {
      return 1;
    }

    public void run(TestResult result) {
      // do nothing
    }

    @Override
    public String toString() {
      return "ShutdownWatchdog";
    }

  }

  public long DELAY = 10 * 60 * 1000;

  private final Listener listener = new Listener();

  public ManagedTestSuite() {
  }

  public ManagedTestSuite(String name) {
    super(name);
  }

  @Override
  public void run(TestResult result) {
    result.addListener(listener);
    dumpSystemInfo();
    super.run(result);
    listener.dumpResults(result);

    // add dummy test to dump threads in case shutdown hangs
    listener.startTest(new ShutdownWatchdog());
  }

  private void dumpSystemInfo() {
    try {

      Properties p = System.getProperties();
      if (Platform.isRunning()) {
        p.put("build.system", Platform.getOS() + "-" + Platform.getOSArch() + "-" + Platform.getWS());
      }
      else {
        p.put("build.system", "standalone");
      }
      String info = "System: ${os.name} ${os.version} (${os.arch}) / ${build.system} / ${java.vendor} ${java.vm.name} ${java.version}";
      for (Entry<Object, Object> entry : p.entrySet()) {
        info = info.replaceFirst(Pattern.quote("${" + entry.getKey() + "}"), entry.getValue().toString());
      }
      System.err.println(info);
      System.err.print("Proxy : " + CloudFoundryTestUtil.getProxy("google.com", IProxyData.HTTP_PROXY_TYPE)
          + " (Platform)");
      try {
        System.err.print(" / " + ProxySelector.getDefault().select(new URI("http://google.com")) + " (Java)");
      }
      catch (URISyntaxException e) {
        // ignore
      }
      System.err.println();
      System.err.println();
    }
    catch (ConcurrentModificationException e) {
      // Not sure why but sometimes thrown by the code that is dumping out
      // system properties!
      // Catch and print it, but don't abort the test runner simply
      // because this info can't be dumped.
      e.printStackTrace();
    }
  }

}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.tests.sts.util.ManagedTestSuite$ShutdownWatchdog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.