1 package org.apache.maven.surefire.junitcore;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.concurrent.atomic.AtomicBoolean;
26 import java.util.concurrent.atomic.AtomicInteger;
27 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
28 import org.apache.maven.surefire.report.ReportEntry;
29 import org.apache.maven.surefire.report.RunListener;
30 import org.apache.maven.surefire.report.SimpleReportEntry;
31 import org.apache.maven.surefire.util.NestedRuntimeException;
32
33 import org.junit.runner.Description;
34
35
36
37
38 public class TestSet
39 {
40 private final Description testSetDescription;
41
42 private final AtomicInteger numberOfCompletedChildren = new AtomicInteger( 0 );
43
44
45
46
47 private final AtomicInteger numberOfTests = new AtomicInteger( 0 );
48
49 private final List<TestMethod> testMethods = Collections.synchronizedList( new ArrayList<TestMethod>() );
50
51 private static final InheritableThreadLocal<TestSet> testSet = new InheritableThreadLocal<TestSet>();
52
53 private final AtomicBoolean allScheduled = new AtomicBoolean();
54
55 private final AtomicBoolean played = new AtomicBoolean();
56
57 private volatile LogicalStream beforeClass;
58
59 private volatile LogicalStream afterClass;
60
61 public TestSet( Description testSetDescription )
62 {
63 this.testSetDescription = testSetDescription;
64 }
65
66 public void replay( RunListener target )
67 {
68 if ( !played.compareAndSet( false, true ) )
69 {
70 return;
71 }
72
73 try
74 {
75 ReportEntry report = createReportEntry( null );
76
77 target.testSetStarting( report );
78
79 if ( beforeClass != null )
80 {
81 beforeClass.writeDetails( ( (ConsoleOutputReceiver) target ) );
82 }
83
84 int elapsed = 0;
85 for ( TestMethod testMethod : testMethods )
86 {
87 elapsed += testMethod.getElapsed();
88 testMethod.replay( target );
89 }
90
91 report = createReportEntry( elapsed );
92
93 if ( afterClass != null )
94 {
95 afterClass.writeDetails( ( (ConsoleOutputReceiver) target ) );
96 }
97 target.testSetCompleted( report );
98 }
99 catch ( Exception e )
100 {
101 throw new NestedRuntimeException( e );
102 }
103 }
104
105 public TestMethod createThreadAttachedTestMethod( ReportEntry description )
106 {
107 TestMethod testMethod = new TestMethod( description, this );
108 addTestMethod( testMethod );
109 testMethod.attachToThread();
110 return testMethod;
111 }
112
113 private ReportEntry createReportEntry( Integer elapsed )
114 {
115 boolean isJunit3 = testSetDescription.getTestClass() == null;
116 String classNameToUse =
117 isJunit3 ? testSetDescription.getChildren().get( 0 ).getClassName() : testSetDescription.getClassName();
118 return new SimpleReportEntry( classNameToUse, classNameToUse, elapsed );
119 }
120
121 public void incrementTestMethodCount()
122 {
123 numberOfTests.incrementAndGet();
124 }
125
126 private void addTestMethod( TestMethod testMethod )
127 {
128 testMethods.add( testMethod );
129 }
130
131 public void incrementFinishedTests( RunListener reporterManager, boolean reportImmediately )
132 {
133 numberOfCompletedChildren.incrementAndGet();
134 if ( allScheduled.get() && isAllTestsDone() && reportImmediately )
135 {
136 replay( reporterManager );
137 }
138 }
139
140 public void setAllScheduled( RunListener reporterManager )
141 {
142 allScheduled.set( true );
143 if ( isAllTestsDone() )
144 {
145 replay( reporterManager );
146 }
147 }
148
149 private boolean isAllTestsDone()
150 {
151 return testMethods.size() == numberOfCompletedChildren.get();
152 }
153
154 public void attachToThread()
155 {
156 testSet.set( this );
157 }
158
159 public static TestSet getThreadTestSet()
160 {
161 return testSet.get();
162 }
163
164 public LogicalStream getClassLevelLogicalStream()
165 {
166 if ( numberOfCompletedChildren.get() > 0 )
167 {
168 if ( afterClass == null )
169 {
170 afterClass = new LogicalStream();
171 }
172 return afterClass;
173 }
174 else
175 {
176 if ( beforeClass == null )
177 {
178 beforeClass = new LogicalStream();
179 }
180 return beforeClass;
181 }
182 }
183
184
185 }