/******************************************************************************* * Copyright (c) 2005, 2015 SAP. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * SAP - initial API and implementation ******************************************************************************/ package org.eclipse.persistence.testing.framework.wdf; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.List; import java.util.Map; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import org.eclipse.persistence.config.PersistenceUnitProperties; import org.eclipse.persistence.platform.database.DatabasePlatform; import org.eclipse.persistence.testing.framework.wdf.customizer.AdjustArrayTypeCustomizer; import org.eclipse.persistence.testing.framework.wdf.server.Notification; import org.eclipse.persistence.testing.framework.wdf.server.ServerTestRunner; import org.junit.Assert; import org.junit.runner.Description; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; public class SkipBugzillaTestRunner extends BlockJUnit4ClassRunner { private static final String TEST_TO_BE_INVESTIGATED_RUN = "test.to-be-investigated.run"; private static final String TEST_ISSUE_RUN = "test.issue.run"; private static final String TEST_BUGZILLA_RUN = "test.bugzilla.run"; @Override public void run(RunNotifier notifier) { if (Boolean.valueOf(System.getProperty("servertest"))) { runOnServer(notifier); } else { super.run(notifier); } } /** * Delegates test execution to the server. On the server, JUnit will be * invoked to run the tests with a special run listener, which collects * the notifications (events). On the client, the recorded notifications will be * replayed on the run notifier passed to this message. * @param notifier the run notifier to replay the notifications recorded on the server */ private void runOnServer(RunNotifier notifier) { Properties properties = new Properties(); String url = getMandatorySystemProperty("server.url"); properties.put("java.naming.provider.url", url); Context context; try { context = new InitialContext(properties); String testrunner = getMandatorySystemProperty("server.testrunner.wdf"); String dataSourceName = getMandatorySystemProperty("datasource.name"); Object object = context.lookup(testrunner); ServerTestRunner runner = (ServerTestRunner) PortableRemoteObject.narrow(object, ServerTestRunner.class); String testClassName = getTestClass().getJavaClass().getName(); List<Notification> notifications = runner.runTestClass(testClassName, dataSourceName, testProperties); for (Notification notification : notifications) { notification.notify(notifier); } } catch (NamingException e) { throw new RuntimeException(e); } } private String getMandatorySystemProperty(final String propertyName) { String url = System.getProperty(propertyName); if (url == null) { Assert.fail("System property '" + propertyName + "' must be set."); } return url; } final long bugid; final long issueid; final boolean runAllBugzilla; final boolean runAllIssues; final boolean runAllUnknown; final boolean runOnlyUnknown; final Class<? extends DatabasePlatform> databasePlatformClass; private final Map<String, String> testProperties; @SuppressWarnings("unchecked") public SkipBugzillaTestRunner(Class<?> klass) throws Throwable { super(klass); testProperties = AbstractBaseTest.getTestProperties(); addProperty(TEST_BUGZILLA_RUN); addProperty(TEST_ISSUE_RUN); addProperty(TEST_TO_BE_INVESTIGATED_RUN); String databasePlatformClassName = testProperties.get(PersistenceUnitProperties.TARGET_DATABASE); if (databasePlatformClassName != null) { databasePlatformClass = (Class<? extends DatabasePlatform>) Class.forName(databasePlatformClassName); AdjustArrayTypeCustomizer.setDatabasePlatformClass(databasePlatformClass); } else { databasePlatformClass = null; // FIXME } String testBugzillaRun = (String) testProperties.get(TEST_BUGZILLA_RUN); if ("all".equals(testBugzillaRun)) { runAllBugzilla = true; bugid = -1; } else { runAllBugzilla = false; if (testBugzillaRun != null) { bugid = Long.parseLong(testBugzillaRun); } else { bugid = -1; } } String testIssueRun = (String) testProperties.get(TEST_ISSUE_RUN); if ("all".equals(testIssueRun)) { runAllIssues = true; issueid = -1; } else { runAllIssues = false; if (testIssueRun != null) { issueid = Long.parseLong(testIssueRun); } else { issueid = -1; } } String testToBeInvestigatedRun = (String) testProperties.get(TEST_TO_BE_INVESTIGATED_RUN); if ("all".equals(testToBeInvestigatedRun)) { runAllUnknown = true; runOnlyUnknown = false; } else if ("only".equals(testToBeInvestigatedRun)) { runAllUnknown = false; runOnlyUnknown = true; } else { runAllUnknown = false; runOnlyUnknown = false; } } private void addProperty(final String name) { String value = System.getProperty(name); if(value != null) { testProperties.put(name, value); } } @Override protected void runChild(FrameworkMethod method, RunNotifier notifier) { try { skipMethod(method, notifier, SKIP_SKIPPER); skipMethod(method, notifier, BUGZILLA_SKIPPER); skipMethod(method, notifier, ISSUE_SKIPPER); skipMethod(method, notifier, TO_BE_INVESTIGATED_SKIPPER); super.runChild(method, notifier); } catch (SkipException ex) { Description description = describeChild(method); notifier.fireTestIgnored(description); } } private <T extends Annotation> void skipMethod(FrameworkMethod method, RunNotifier notifier, Skipper<T> skipper) throws SkipException { Method reflectMethod = method.getMethod(); T a = skipper.getAnnotation(reflectMethod); if (a == null) { if (skipper.skipOthers()) { throw new SkipException(); } return; } if (skipper.runAll()) { return; } if (skipper.runThis(a)) { return; } Class<? extends DatabasePlatform>[] databases = skipper.getDatabases(a); String[] databaseNames = skipper.getDatabaseNames(a); if ((databases == null || databases.length == 0) && (databaseNames == null || databaseNames.length == 0)) { // all databases are unsupported throw new SkipException(); } if (databasePlatformClass != null) { if (databases != null) { for (Class<? extends DatabasePlatform> clazz : databases) { if (clazz.isAssignableFrom(databasePlatformClass)) { // the current database platform is not supported throw new SkipException(); } } } if (databaseNames != null) { for (String name : databaseNames) { if (databasePlatformClass.getName().equals(name)) { // the current database platform is not supported throw new SkipException(); } } } } return; } private static class SkipException extends Exception { private static final long serialVersionUID = 1L; } private Skipper<Skip> SKIP_SKIPPER = new Skipper<Skip>() { @Override public Skip getAnnotation(Method method) { return method.getAnnotation(Skip.class); } @Override public Class<? extends DatabasePlatform>[] getDatabases(Skip skip) { return skip.databases(); } @Override public boolean runAll() { return false; } @Override public boolean runThis(Skip skip) { if(skip.server()) { return !ServerInfoHolder.isOnServer(); } return false; } @Override public boolean skipOthers() { return false; } @Override public String[] getDatabaseNames(Skip skip) { return skip.databaseNames(); } }; private final Skipper<Bugzilla> BUGZILLA_SKIPPER = new Skipper<Bugzilla>() { @Override public Bugzilla getAnnotation(Method method) { return method.getAnnotation(Bugzilla.class); } @Override public Class<? extends DatabasePlatform>[] getDatabases(Bugzilla t) { return t.databases(); } @Override public boolean runAll() { return runAllBugzilla; } @Override public boolean runThis(Bugzilla t) { return t.bugid() == bugid; } @Override public boolean skipOthers() { return false; } @Override public String[] getDatabaseNames(Bugzilla t) { return t.databaseNames(); } }; private final Skipper<Issue> ISSUE_SKIPPER = new Skipper<Issue>() { @Override public Issue getAnnotation(Method method) { return method.getAnnotation(Issue.class); } @Override public Class<? extends DatabasePlatform>[] getDatabases(Issue t) { return t.databases(); } @Override public boolean runAll() { return runAllIssues; } @Override public boolean runThis(Issue t) { return t.issueid() == issueid; } @Override public boolean skipOthers() { return false; } @Override public String[] getDatabaseNames(Issue t) { return t.databaseNames(); } }; private final Skipper<ToBeInvestigated> TO_BE_INVESTIGATED_SKIPPER = new Skipper<ToBeInvestigated>() { @Override public ToBeInvestigated getAnnotation(Method method) { return method.getAnnotation(ToBeInvestigated.class); } @Override public Class<? extends DatabasePlatform>[] getDatabases(ToBeInvestigated t) { return t.databases(); } @Override public boolean runAll() { return runAllUnknown || runOnlyUnknown; } @Override public boolean runThis(ToBeInvestigated t) { return false; } @Override public boolean skipOthers() { return runOnlyUnknown; } @Override public String[] getDatabaseNames(ToBeInvestigated t) { return t.databaseNames(); } }; private interface Skipper<T extends Annotation> { T getAnnotation(Method method); boolean runAll(); boolean runThis(T t); boolean skipOthers(); Class<? extends DatabasePlatform>[] getDatabases(T t); String[] getDatabaseNames(T t); } }