View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.junitcore.pc;
20  
21  import java.util.Collection;
22  import java.util.concurrent.ConcurrentLinkedQueue;
23  import java.util.concurrent.ExecutorService;
24  import java.util.concurrent.LinkedBlockingQueue;
25  import java.util.concurrent.ThreadFactory;
26  import java.util.concurrent.ThreadPoolExecutor;
27  import java.util.concurrent.TimeUnit;
28  
29  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
30  import org.apache.maven.surefire.api.util.internal.DaemonThreadFactory;
31  import org.junit.runner.Description;
32  import org.junit.runners.model.RunnerScheduler;
33  
34  /**
35   * Used to execute tests annotated with net.jcip.annotations.NotThreadSafe.
36   * <br>
37   *
38   * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
39   * @see ParallelComputerBuilder
40   * @since 2.18
41   */
42  final class SingleThreadScheduler {
43      private final ConsoleLogger logger;
44  
45      private final ExecutorService pool = newPool();
46  
47      private final Scheduler master;
48  
49      private static ExecutorService newPool() {
50          ThreadFactory tf = DaemonThreadFactory.newDaemonThreadFactory("maven-surefire-plugin@NotThreadSafe");
51          return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), tf);
52      }
53  
54      SingleThreadScheduler(ConsoleLogger logger) {
55          this.logger = logger;
56          SchedulingStrategy strategy = SchedulingStrategies.createParallelSharedStrategy(logger, pool);
57          master = new Scheduler(logger, null, strategy);
58      }
59  
60      RunnerScheduler newRunnerScheduler() {
61          SchedulingStrategy strategy = SchedulingStrategies.createParallelSharedStrategy(logger, pool);
62          return new Scheduler(logger, null, master, strategy);
63      }
64  
65      /**
66       * @see Scheduler#describeStopped(boolean)
67       */
68      ShutdownResult describeStopped(boolean shutdownNow) {
69          ShutdownResult shutdownResult = master.describeStopped(shutdownNow);
70          return new ShutdownResult(
71                  copyExisting(shutdownResult.getTriggeredTests()), copyExisting(shutdownResult.getIncompleteTests()));
72      }
73  
74      /**
75       * @see Scheduler#shutdownThreadPoolsAwaitingKilled()
76       */
77      boolean shutdownThreadPoolsAwaitingKilled() {
78          return master.shutdownThreadPoolsAwaitingKilled();
79      }
80  
81      private Collection<Description> copyExisting(Collection<Description> descriptions) {
82          Collection<Description> activeChildren = new ConcurrentLinkedQueue<>(descriptions);
83          ParallelComputerUtil.removeUnusedDescriptions(activeChildren);
84          return activeChildren;
85      }
86  }