View Javadoc

1   package org.apache.maven.surefire.junitcore;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * * Represents the test-state of a testset that is run.
37   */
38  public class TestSet
39  {
40      private final Description testSetDescription;
41  
42      private final AtomicInteger numberOfCompletedChildren = new AtomicInteger( 0 );
43  
44      // While the two parameters below may seem duplicated, it is not entirely the case,
45      // since numberOfTests has the correct value from the start, while testMethods grows as method execution starts.
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 }