All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.portal.kernel.test.NewJVMJUnitTestRunner Maven / Gradle / Ivy

Go to download

Contains interfaces for the portal services. Interfaces are only loaded by the global class loader and are shared by all plugins.

There is a newer version: 7.0.0-nightly
Show newest version
/**
 * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.kernel.test;

import com.liferay.portal.kernel.process.ClassPathUtil;
import com.liferay.portal.kernel.process.ProcessCallable;
import com.liferay.portal.kernel.process.ProcessException;
import com.liferay.portal.kernel.process.ProcessExecutor;
import com.liferay.portal.kernel.util.MethodKey;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;

import java.io.Serializable;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.manipulation.Sorter;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;

/**
 * @author Shuyang Zhou
 */
public class NewJVMJUnitTestRunner extends BlockJUnit4ClassRunner {

	public NewJVMJUnitTestRunner(Class clazz) throws InitializationError {
		super(clazz);

		_classPath = ClassPathUtil.getJVMClassPath(false);

		sort(new Sorter(new DescriptionComparator()));
	}

	protected static void attachProcess(String message) {
		if (!Boolean.getBoolean("attached")) {
			ProcessExecutor.ProcessContext.attach(
				message, 1000,
				new ProcessExecutor.ShutdownHook() {

					@Override
					public boolean shutdown(
						int shutdownCode, Throwable shutdownThrowable) {

						System.exit(shutdownCode);

						return true;
					}

				});

			System.setProperty("attached", StringPool.TRUE);
		}
	}

	protected List createArguments(FrameworkMethod frameworkMethod) {
		List arguments = new ArrayList();

		String agentLine = System.getProperty("junit.cobertura.agent");

		if (Validator.isNotNull(agentLine)) {
			arguments.add(agentLine);
			arguments.add("-Djunit.cobertura.agent=" + agentLine);
		}

		boolean coberturaParentDynamicallyInstrumented = Boolean.getBoolean(
			"cobertura.parent.dynamically.instrumented");

		if (coberturaParentDynamicallyInstrumented) {
			arguments.add("-Dcobertura.parent.dynamically.instrumented=true");
		}

		boolean junitCodeCoverage = Boolean.getBoolean("junit.code.coverage");

		if (junitCodeCoverage) {
			arguments.add("-Djunit.code.coverage=true");
		}

		boolean junitDebug = Boolean.getBoolean("junit.debug");

		if (junitDebug) {
			arguments.add(_JPDA_OPTIONS);
			arguments.add("-Djunit.debug=true");
		}

		arguments.add("-Djava.net.preferIPv4Stack=true");

		String fileName = System.getProperty(
			"net.sourceforge.cobertura.datafile");

		if (fileName != null) {
			arguments.add("-Dnet.sourceforge.cobertura.datafile=" + fileName);
		}

		return arguments;
	}

	@Override
	protected Statement methodBlock(FrameworkMethod frameworkMethod) {
		Thread currentThread = Thread.currentThread();

		ClassLoader contextClassLoader = currentThread.getContextClassLoader();

		PortalClassLoaderUtil.setClassLoader(contextClassLoader);

		TestClass testClass = getTestClass();

		List beforeFrameworkMethods =
			testClass.getAnnotatedMethods(Before.class);

		List afterFrameworkMethods =
			testClass.getAnnotatedMethods(After.class);

		List arguments = createArguments(frameworkMethod);

		Class clazz = testClass.getJavaClass();

		return new RunInNewJVMStatment(
			_classPath, arguments, clazz, beforeFrameworkMethods,
			frameworkMethod, afterFrameworkMethods);
	}

	protected ProcessCallable processProcessCallable(
		ProcessCallable processCallable,
		MethodKey testMethodKey) {

		return processCallable;
	}

	private static final String _JPDA_OPTIONS =
		"-agentlib:jdwp=transport=dt_socket,address=8001,server=y,suspend=y";

	private String _classPath;

	private static class TestProcessCallable
		implements ProcessCallable {

		public TestProcessCallable(
			String testClassName, List beforeMethodKeys,
			MethodKey testMethodKey, List afterMethodKeys) {

			_testClassName = testClassName;
			_beforeMethodKeys = beforeMethodKeys;
			_testMethodKey = testMethodKey;
			_afterMethodKeys = afterMethodKeys;
		}

		@Override
		public Serializable call() throws ProcessException {
			attachProcess("Attached " + toString());

			Thread currentThread = Thread.currentThread();

			ClassLoader contextClassLoader =
				currentThread.getContextClassLoader();

			try {
				Class clazz = contextClassLoader.loadClass(_testClassName);

				Object object = clazz.newInstance();

				for (MethodKey beforeMethodKey : _beforeMethodKeys) {
					beforeMethodKey = beforeMethodKey.transform(
						contextClassLoader);

					_invoke(beforeMethodKey, object);
				}

				MethodKey testMethodKey = _testMethodKey.transform(
					contextClassLoader);

				_invoke(testMethodKey, object);

				for (MethodKey afterMethodKey : _afterMethodKeys) {
					afterMethodKey = afterMethodKey.transform(
						contextClassLoader);

					_invoke(afterMethodKey, object);
				}
			}
			catch (Exception e) {
				throw new ProcessException(e);
			}

			return StringPool.BLANK;
		}

		@Override
		public String toString() {
			StringBundler sb = new StringBundler(4);

			sb.append(_testClassName);
			sb.append(StringPool.PERIOD);
			sb.append(_testMethodKey.getMethodName());
			sb.append("()");

			return sb.toString();
		}

		private void _invoke(MethodKey methodKey, Object object)
			throws Exception {

			Method method = methodKey.getMethod();

			method.invoke(object);
		}

		private static final long serialVersionUID = 1L;

		private List _afterMethodKeys;
		private List _beforeMethodKeys;
		private String _testClassName;
		private MethodKey _testMethodKey;

	}

	private class RunInNewJVMStatment extends Statement {

		public RunInNewJVMStatment(
			String classPath, List arguments, Class testClass,
			List beforeFrameworkMethods,
			FrameworkMethod testFrameworkMethod,
			List afterFrameworkMethods) {

			_classPath = classPath;
			_arguments = arguments;
			_testClassName = testClass.getName();

			_beforeMethodKeys = new ArrayList(
				beforeFrameworkMethods.size());

			for (FrameworkMethod frameworkMethod : beforeFrameworkMethods) {
				_beforeMethodKeys.add(
					new MethodKey(frameworkMethod.getMethod()));
			}

			_testMethodKey = new MethodKey(testFrameworkMethod.getMethod());

			_afterMethodKeys = new ArrayList(
				afterFrameworkMethods.size());

			for (FrameworkMethod frameworkMethod : afterFrameworkMethods) {
				_afterMethodKeys.add(
					new MethodKey(frameworkMethod.getMethod()));
			}
		}

		@Override
		public void evaluate() throws Throwable {
			ProcessCallable processCallable =
				new TestProcessCallable(
					_testClassName, _beforeMethodKeys, _testMethodKey,
					_afterMethodKeys);

			processCallable = processProcessCallable(
				processCallable, _testMethodKey);

			Future future = ProcessExecutor.execute(
				_classPath, _arguments, processCallable);

			try {
				future.get();
			}
			catch (ExecutionException ee) {
				Throwable cause = ee.getCause();

				while ((cause instanceof ProcessException) ||
					   (cause instanceof InvocationTargetException)) {

					cause = cause.getCause();
				}

				throw cause;
			}
		}

		private List _afterMethodKeys;
		private List _arguments;
		private List _beforeMethodKeys;
		private String _classPath;
		private String _testClassName;
		private MethodKey _testMethodKey;

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy