1 package org.apache.maven.surefire.common.junit4;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.junit.runner.Description;
23 import org.junit.runner.notification.Failure;
24 import org.junit.runner.notification.RunListener;
25 import org.junit.runner.notification.RunNotifier;
26 import org.junit.runner.notification.StoppedByUserException;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Iterator;
31 import java.util.Queue;
32 import java.util.concurrent.ConcurrentLinkedQueue;
33 import java.util.concurrent.atomic.AtomicInteger;
34
35 import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.cutTestClassAndMethod;
36 import static org.apache.maven.surefire.util.internal.ConcurrencyUtils.countDownToZero;
37
38
39
40
41
42
43
44
45
46 public class Notifier
47 extends RunNotifier
48 {
49 private final Collection<RunListener> listeners = new ArrayList<RunListener>();
50
51 private final Queue<String> testClassNames = new ConcurrentLinkedQueue<String>();
52
53 private final AtomicInteger skipAfterFailureCount;
54
55 private final JUnit4RunListener reporter;
56
57 private volatile boolean failFast;
58
59 public Notifier( JUnit4RunListener reporter, int skipAfterFailureCount )
60 {
61 addListener( reporter );
62 this.reporter = reporter;
63 this.skipAfterFailureCount = new AtomicInteger( skipAfterFailureCount );
64 }
65
66 private Notifier()
67 {
68 reporter = null;
69 skipAfterFailureCount = null;
70 }
71
72 public static Notifier pureNotifier()
73 {
74 return new Notifier()
75 {
76 @Override
77 public Notifier asFailFast( boolean failFast )
78 {
79 throw new UnsupportedOperationException( "pure notifier" );
80 }
81 };
82 }
83
84 public Notifier asFailFast( boolean failFast )
85 {
86 this.failFast = failFast;
87 return this;
88 }
89
90 public final boolean isFailFast()
91 {
92 return failFast;
93 }
94
95 @Override
96 public final void fireTestStarted( Description description ) throws StoppedByUserException
97 {
98
99
100 super.fireTestStarted( description );
101 if ( !testClassNames.isEmpty() )
102 {
103 testClassNames.remove( cutTestClassAndMethod( description ).getClazz() );
104 }
105 }
106
107 @Override
108 public final void fireTestFailure( Failure failure )
109 {
110 if ( failFast )
111 {
112 fireStopEvent();
113 }
114 super.fireTestFailure( failure );
115 }
116
117 @Override
118 public final void addListener( RunListener listener )
119 {
120 listeners.add( listener );
121 super.addListener( listener );
122 }
123
124 public final Notifier addListeners( Collection<RunListener> given )
125 {
126 for ( RunListener listener : given )
127 {
128 addListener( listener );
129 }
130 return this;
131 }
132
133 public final Notifier addListeners( RunListener... given )
134 {
135 for ( RunListener listener : given )
136 {
137 addListener( listener );
138 }
139 return this;
140 }
141
142 @Override
143 public final void removeListener( RunListener listener )
144 {
145 listeners.remove( listener );
146 super.removeListener( listener );
147 }
148
149 public final void removeListeners()
150 {
151 for ( Iterator<RunListener> it = listeners.iterator(); it.hasNext(); )
152 {
153 RunListener listener = it.next();
154 it.remove();
155 super.removeListener( listener );
156 }
157 }
158
159 public final Queue<String> getRemainingTestClasses()
160 {
161 return failFast ? testClassNames : null;
162 }
163
164 public final void copyListenersTo( Notifier copyTo )
165 {
166 copyTo.addListeners( listeners );
167 }
168
169
170
171
172 private void fireStopEvent()
173 {
174 if ( countDownToZero( skipAfterFailureCount ) )
175 {
176 pleaseStop();
177 }
178
179 reporter.testExecutionSkippedByUser();
180 }
181 }