Search in sources :

Example 1 with World

use of org.jenkinsci.test.acceptance.guice.World in project acceptance-test-harness by jenkinsci.

the class TSRJenkinsAcceptanceTestRule method apply.

@Override
public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
    final Description description = Description.createTestDescription(method.getMethod().getDeclaringClass(), method.getName(), method.getAnnotations());
    return new Statement() {

        @Inject
        JenkinsController controller;

        @Inject
        Injector injector;

        @Override
        public void evaluate() throws Throwable {
            World world = World.get();
            Injector injector = world.getInjector();
            world.startTestScope(description.getDisplayName());
            injector.injectMembers(target);
            injector.injectMembers(this);
            System.out.println("=== Starting " + description.getDisplayName());
            try {
                decorateWithRules(base).evaluate();
            } catch (AssumptionViolatedException e) {
                throw e;
            } catch (Exception | AssertionError e) {
                // Errors and failures
                controller.diagnose(e);
                throw e;
            } finally {
                world.endTestScope();
            }
        }

        /**
         * Look for annotations on a test and honor {@link RuleAnnotation}s in them.
         */
        private Statement decorateWithRules(Statement body) {
            Set<Class<? extends Annotation>> annotations = new HashSet<>();
            collectAnnotationTypes(method.getMethod(), annotations);
            collectAnnotationTypes(target.getClass(), annotations);
            Description testDescription = Description.createTestDescription(target.getClass(), method.getName(), method.getAnnotations());
            for (Class<? extends Annotation> a : annotations) {
                RuleAnnotation r = a.getAnnotation(RuleAnnotation.class);
                if (r != null) {
                    TestRule tr = injector.getInstance(r.value());
                    body = tr.apply(body, testDescription);
                }
            }
            return body;
        }

        private void collectAnnotationTypes(AnnotatedElement e, Collection<Class<? extends Annotation>> types) {
            for (Annotation a : e.getAnnotations()) {
                types.add(a.annotationType());
            }
        }
    };
}
Also used : Description(org.junit.runner.Description) AssumptionViolatedException(org.junit.internal.AssumptionViolatedException) Statement(org.junit.runners.model.Statement) AnnotatedElement(java.lang.reflect.AnnotatedElement) World(org.jenkinsci.test.acceptance.guice.World) AssumptionViolatedException(org.junit.internal.AssumptionViolatedException) Annotation(java.lang.annotation.Annotation) TestRule(org.junit.rules.TestRule) JenkinsController(org.jenkinsci.test.acceptance.controller.JenkinsController) Injector(com.google.inject.Injector) Collection(java.util.Collection) HashSet(java.util.HashSet)

Example 2 with World

use of org.jenkinsci.test.acceptance.guice.World in project acceptance-test-harness by jenkinsci.

the class JenkinsAcceptanceTestRule method apply.

@Override
public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
    final Description description = Description.createTestDescription(target.getClass(), method.getName(), method.getAnnotations());
    return new Statement() {

        @Inject
        JenkinsController controller;

        @Inject
        Injector injector;

        @Override
        public void evaluate() throws Throwable {
            World world = World.get();
            Injector injector = world.getInjector();
            world.startTestScope(description.getDisplayName());
            injector.injectMembers(this);
            try {
                decorateWithRules(base).evaluate();
            } catch (AssumptionViolatedException e) {
                System.out.printf("Skipping %s%n", description.getDisplayName());
                e.printStackTrace();
                throw e;
            } finally {
                world.endTestScope();
            }
        }

        /**
         * Detect the outermost exception of given type.
         */
        private Throwable causedBy(Throwable caught, Class<? extends Throwable> type) {
            for (Throwable cur = caught; cur != null; cur = cur.getCause()) {
                if (type.isInstance(cur))
                    return cur;
            }
            return null;
        }

        /**
         * Look for annotations on a test and honor {@link RuleAnnotation}s in them.
         */
        private Statement decorateWithRules(Statement body) {
            TreeMap<Integer, Set<TestRule>> rules = new TreeMap<Integer, Set<TestRule>>(new Comparator<Integer>() {

                @Override
                public int compare(Integer o1, Integer o2) {
                    // Reversed since we apply the TestRule inside out:
                    return Integer.compare(o2, o1);
                }
            });
            collectRuleAnnotations(method, target, rules);
            collectGlobalRules(rules);
            // Make sure Jenkins is started between -1 and 0
            if (rules.get(0) == null) {
                rules.put(0, new LinkedHashSet<TestRule>());
            }
            rules.get(0).add(jenkinsBoot(rules));
            for (Set<TestRule> rulesGroup : rules.values()) {
                for (TestRule rule : rulesGroup) {
                    try {
                        body = rule.apply(body, description);
                    } catch (Exception e) {
                        throw new RuleFailedException(e, rule);
                    }
                }
            }
            return body;
        }

        private void collectGlobalRules(TreeMap<Integer, Set<TestRule>> rules) {
            Iterable<Class> impls;
            try {
                impls = Index.list(GlobalRule.class, getClass().getClassLoader(), Class.class);
            } catch (IOException e) {
                throw new Error("Unable to collect global annotations", e);
            }
            for (Class<?> rule : impls) {
                if (!TestRule.class.isAssignableFrom(rule)) {
                    throw new Error("GlobalRule is applicable for TestRules only");
                }
                addRule(rules, rule.getAnnotation(GlobalRule.class).priority(), (Class<? extends TestRule>) rule);
            }
        }

        private void collectRuleAnnotations(final FrameworkMethod method, final Object target, TreeMap<Integer, Set<TestRule>> rules) {
            Set<Class<? extends Annotation>> annotations = new HashSet<>();
            collectAnnotationTypes(method.getMethod(), annotations);
            collectAnnotationTypes(target.getClass(), annotations);
            for (Class<? extends Annotation> a : annotations) {
                RuleAnnotation r = a.getAnnotation(RuleAnnotation.class);
                if (r != null) {
                    addRule(rules, r.priority(), r.value());
                }
            }
        }

        private void collectAnnotationTypes(AnnotatedElement e, Collection<Class<? extends Annotation>> types) {
            for (Annotation a : e.getAnnotations()) {
                types.add(a.annotationType());
            }
        }

        private void addRule(TreeMap<Integer, Set<TestRule>> rules, int prio, Class<? extends TestRule> impl) {
            if (rules.get(prio) == null) {
                rules.put(prio, new LinkedHashSet<TestRule>());
            }
            rules.get(prio).add(injector.getInstance(impl));
        }

        private TestRule jenkinsBoot(final TreeMap<Integer, Set<TestRule>> rules) {
            return new TestRule() {

                @Override
                public Statement apply(final Statement base, Description description) {
                    return new Statement() {

                        @Override
                        public void evaluate() throws Throwable {
                            controller.start();
                            // Now it is safe to inject Jenkins
                            injector.injectMembers(target);
                            for (Set<TestRule> rg : rules.values()) {
                                for (TestRule rule : rg) {
                                    injector.injectMembers(rule);
                                }
                            }
                            base.evaluate();
                        }
                    };
                }
            };
        }
    };
}
Also used : Description(org.junit.runner.Description) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) AssumptionViolatedException(org.junit.internal.AssumptionViolatedException) AnnotatedElement(java.lang.reflect.AnnotatedElement) World(org.jenkinsci.test.acceptance.guice.World) JenkinsController(org.jenkinsci.test.acceptance.controller.JenkinsController) Injector(com.google.inject.Injector) FrameworkMethod(org.junit.runners.model.FrameworkMethod) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Statement(org.junit.runners.model.Statement) IOException(java.io.IOException) TreeMap(java.util.TreeMap) IOException(java.io.IOException) AssumptionViolatedException(org.junit.internal.AssumptionViolatedException) NoSuchElementException(org.openqa.selenium.NoSuchElementException) Annotation(java.lang.annotation.Annotation) TestRule(org.junit.rules.TestRule) Collection(java.util.Collection)

Example 3 with World

use of org.jenkinsci.test.acceptance.guice.World in project acceptance-test-harness by jenkinsci.

the class JenkinsControllerPoolProcess method run.

public void run() throws Exception {
    // so the actual length of the queue has to be n-1.
    if (n == 1)
        queue = new SynchronousQueue<>();
    else
        queue = new LinkedBlockingDeque<>(n - 1);
    World w = World.get();
    w.getInjector().injectMembers(this);
    new Thread() {

        /**
         * Just keeps on creating new controllers and put it into the queue.
         * Because queue is blocking, this will only prelaunch up to 3.
         */
        @Override
        public void run() {
            try {
                FallbackConfig f = new FallbackConfig();
                while (true) {
                    lifecycle.startTestScope();
                    JenkinsController c = f.createController(injector, factories);
                    c.start();
                    queue.put(new QueueItem(c, lifecycle.export()));
                }
            } catch (Throwable e) {
                // fail fatally
                e.printStackTrace();
                System.exit(1);
            }
        }
    }.start();
    processServerSocket();
}
Also used : FallbackConfig(org.jenkinsci.test.acceptance.FallbackConfig) JenkinsController(org.jenkinsci.test.acceptance.controller.JenkinsController) IJenkinsController(org.jenkinsci.test.acceptance.controller.IJenkinsController) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) SynchronousQueue(java.util.concurrent.SynchronousQueue) World(org.jenkinsci.test.acceptance.guice.World)

Aggregations

JenkinsController (org.jenkinsci.test.acceptance.controller.JenkinsController)3 World (org.jenkinsci.test.acceptance.guice.World)3 Injector (com.google.inject.Injector)2 Annotation (java.lang.annotation.Annotation)2 AnnotatedElement (java.lang.reflect.AnnotatedElement)2 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 AssumptionViolatedException (org.junit.internal.AssumptionViolatedException)2 TestRule (org.junit.rules.TestRule)2 Description (org.junit.runner.Description)2 Statement (org.junit.runners.model.Statement)2 IOException (java.io.IOException)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 LinkedBlockingDeque (java.util.concurrent.LinkedBlockingDeque)1 SynchronousQueue (java.util.concurrent.SynchronousQueue)1 FallbackConfig (org.jenkinsci.test.acceptance.FallbackConfig)1 IJenkinsController (org.jenkinsci.test.acceptance.controller.IJenkinsController)1 FrameworkMethod (org.junit.runners.model.FrameworkMethod)1