View Javadoc
1   package org.junit.runner.notification;
2   
3   import org.junit.runner.Description;
4   import org.junit.runner.Result;
5   
6   /**
7    * Thread-safe decorator for {@link RunListener} implementations that synchronizes
8    * calls to the delegate.
9    *
10   * <p>This class synchronizes all listener calls on a RunNotifier instance. This is done because
11   * prior to JUnit 4.12, all listeners were called in a synchronized block in RunNotifier,
12   * so no two listeners were ever called concurrently. If we instead made the methods here
13   * sychronized, clients that added multiple listeners that called common code might see
14   * issues due to the reduced synchronization.
15   *
16   * @author Tibor Digana (tibor17)
17   * @author Kevin Cooney (kcooney)
18   * @since 4.12
19   *
20   * @see RunNotifier
21   */
22  @RunListener.ThreadSafe
23  final class SynchronizedRunListener extends RunListener {
24      private final RunListener listener;
25      private final Object monitor;
26  
27      SynchronizedRunListener(RunListener listener, Object monitor) {
28          this.listener = listener;
29          this.monitor = monitor;
30      }
31  
32      @Override
33      public void testRunStarted(Description description) throws Exception {
34          synchronized (monitor) {
35              listener.testRunStarted(description);
36          }
37      }
38  
39      @Override
40      public void testRunFinished(Result result) throws Exception {
41          synchronized (monitor) {
42              listener.testRunFinished(result);
43          }
44      }
45  
46      @Override
47      public void testStarted(Description description) throws Exception {
48          synchronized (monitor) {
49              listener.testStarted(description);
50          }
51      }
52  
53      @Override
54      public void testFinished(Description description) throws Exception {
55          synchronized (monitor) {
56              listener.testFinished(description);
57          }
58      }
59  
60      @Override
61      public void testFailure(Failure failure) throws Exception {
62          synchronized (monitor) {
63              listener.testFailure(failure);
64          }
65      }
66  
67      @Override
68      public void testAssumptionFailure(Failure failure) {
69          synchronized (monitor) {
70              listener.testAssumptionFailure(failure);
71          }
72      }
73  
74      @Override
75      public void testIgnored(Description description) throws Exception {
76          synchronized (monitor) {
77              listener.testIgnored(description);
78          }
79      }
80  
81      @Override
82      public int hashCode() {
83          return listener.hashCode();
84      }
85  
86      @Override
87      public boolean equals(Object other) {
88          if (this == other) {
89              return true;
90          }
91          if (!(other instanceof SynchronizedRunListener)) {
92              return false;
93          }
94          SynchronizedRunListener that = (SynchronizedRunListener) other;
95          
96          return listener.equals(that.listener);
97      }
98  
99      @Override
100     public String toString() {
101         return listener.toString() + " (with synchronization wrapper)";
102     }
103 }