001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *  
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018     
019    package org.apache.geronimo.mavenplugins.testsuite.report;
020    
021    import org.apache.maven.reporting.MavenReportException;
022    import org.codehaus.plexus.util.DirectoryScanner;
023    import org.codehaus.plexus.util.StringUtils;
024    import org.xml.sax.SAXException;
025    
026    import javax.xml.parsers.ParserConfigurationException;
027    import java.io.File;
028    import java.io.IOException;
029    import java.text.NumberFormat;
030    import java.util.ArrayList;
031    import java.util.HashMap;
032    import java.util.List;
033    import java.util.ListIterator;
034    import java.util.Locale;
035    import java.util.Map;
036    
037    public class SurefireReportParser
038    {
039        private NumberFormat numberFormat = NumberFormat.getInstance();
040    
041        private File reportsDirectory;
042    
043        private List testSuites = new ArrayList();
044    
045        private Locale locale;
046    
047        private static final int PCENT = 100;
048    
049        public SurefireReportParser()
050        {
051        }
052    
053        public SurefireReportParser( File reportsDirectory, Locale locale )
054        {
055            this.reportsDirectory = reportsDirectory;
056    
057            setLocale( locale );
058        }
059    
060        public List parseXMLReportFiles()
061            throws MavenReportException
062        {
063            if ( reportsDirectory.exists() )
064            {
065                String[] xmlReportFiles = getIncludedFiles( reportsDirectory, "*.xml", "*.txt" );
066    
067                for ( int index = 0; index < xmlReportFiles.length; index++ )
068                {
069                    ReportTestSuite testSuite = new ReportTestSuite();
070                    
071                    String currentReport = xmlReportFiles[index];
072    
073                    try
074                    {
075                        testSuite.parse( reportsDirectory + "/" + currentReport );
076                    }
077                    catch ( ParserConfigurationException e )
078                    {
079                        throw new MavenReportException( "Error setting up parser for JUnit XML report", e );
080                    }
081                    catch ( SAXException e )
082                    {
083                        throw new MavenReportException( "Error parsing JUnit XML report " + currentReport, e );
084                    }
085                    catch ( IOException e )
086                    {
087                        throw new MavenReportException( "Error reading JUnit XML report " + currentReport, e );
088                    }
089    
090                    testSuites.add( testSuite );
091                }
092            }
093    
094            return testSuites;
095        }
096    
097        protected String parseTestSuiteName( String lineString )
098        {
099            return lineString.substring( lineString.lastIndexOf( "." ) + 1, lineString.length() );
100        }
101    
102        protected String parseTestSuitePackageName( String lineString )
103        {
104            return lineString.substring( lineString.indexOf( ":" ) + 2, lineString.lastIndexOf( "." ) );
105        }
106    
107        protected String parseTestCaseName( String lineString )
108        {
109            return lineString.substring( 0, lineString.indexOf( "(" ) );
110        }
111    
112        public Map getSummary( List suites )
113        {
114            Map totalSummary = new HashMap();
115    
116            ListIterator iter = suites.listIterator();
117    
118            int totalNumberOfTests = 0;
119    
120            int totalNumberOfErrors = 0;
121    
122            int totalNumberOfFailures = 0;
123    
124            int totalNumberOfSkipped = 0;
125    
126            float totalElapsedTime = 0.0f;
127    
128            while ( iter.hasNext() )
129            {
130                ReportTestSuite suite = (ReportTestSuite) iter.next();
131    
132                totalNumberOfTests += suite.getNumberOfTests();
133    
134                totalNumberOfErrors += suite.getNumberOfErrors();
135    
136                totalNumberOfFailures += suite.getNumberOfFailures();
137    
138                totalNumberOfSkipped += suite.getNumberOfSkipped();
139    
140                totalElapsedTime += suite.getTimeElapsed();
141            }
142    
143            String totalPercentage = computePercentage( totalNumberOfTests, totalNumberOfErrors, totalNumberOfFailures,
144                                                        totalNumberOfSkipped );
145    
146            totalSummary.put( "totalTests", Integer.toString( totalNumberOfTests ) );
147    
148            totalSummary.put( "totalErrors", Integer.toString( totalNumberOfErrors ) );
149    
150            totalSummary.put( "totalFailures", Integer.toString( totalNumberOfFailures ) );
151    
152            totalSummary.put( "totalSkipped", Integer.toString( totalNumberOfSkipped ) );
153    
154            totalSummary.put( "totalElapsedTime", numberFormat.format( totalElapsedTime ) );
155    
156            totalSummary.put( "totalPercentage", totalPercentage );
157    
158            return totalSummary;
159        }
160    
161        public void setReportsDirectory( File reportsDirectory )
162        {
163            this.reportsDirectory = reportsDirectory;
164        }
165    
166        public File getReportsDirectory()
167        {
168            return this.reportsDirectory;
169        }
170    
171        public final void setLocale( Locale locale )
172        {
173            this.locale = locale;
174            numberFormat = NumberFormat.getInstance( locale );
175        }
176    
177        public Locale getLocale()
178        {
179            return this.locale;
180        }
181    
182        public void setNumberFormat( NumberFormat numberFormat )
183        {
184            this.numberFormat = numberFormat;
185        }
186    
187        public NumberFormat getNumberFormat()
188        {
189            return this.numberFormat;
190        }
191    
192        public Map getSuitesGroupByPackage( List testSuitesList )
193        {
194            ListIterator iter = testSuitesList.listIterator();
195    
196            Map suitePackage = new HashMap();
197    
198            while ( iter.hasNext() )
199            {
200                ReportTestSuite suite = (ReportTestSuite) iter.next();
201    
202                List suiteList = new ArrayList();
203    
204                if ( suitePackage.get( suite.getPackageName() ) != null )
205                {
206                    suiteList = (List) suitePackage.get( suite.getPackageName() );
207                }
208    
209                suiteList.add( suite );
210    
211                suitePackage.put( suite.getPackageName(), suiteList );
212            }
213    
214            return suitePackage;
215        }
216    
217        public String computePercentage( int tests, int errors, int failures, int skipped )
218        {
219            float percentage;
220            if ( tests == 0 )
221            {
222                percentage = 0;
223            }
224            else
225            {
226                percentage = ( (float) ( tests - errors - failures - skipped ) / (float) tests ) * PCENT;
227            }
228    
229            return numberFormat.format( percentage );
230        }
231    
232        public List getFailureDetails( List testSuitesList )
233        {
234            ListIterator iter = testSuitesList.listIterator();
235    
236            List failureDetailList = new ArrayList();
237    
238            while ( iter.hasNext() )
239            {
240                ReportTestSuite suite = (ReportTestSuite) iter.next();
241    
242                List testCaseList = suite.getTestCases();
243    
244                if ( testCaseList != null )
245                {
246                    ListIterator caseIter = testCaseList.listIterator();
247    
248                    while ( caseIter.hasNext() )
249                    {
250                        ReportTestCase tCase = (ReportTestCase) caseIter.next();
251    
252                        if ( tCase.getFailure() != null )
253                        {
254                            failureDetailList.add( tCase );
255                        }
256                    }
257                }
258            }
259    
260            return failureDetailList;
261        }
262    
263        private String[] getIncludedFiles( File directory, String includes, String excludes )
264        {
265            DirectoryScanner scanner = new DirectoryScanner();
266    
267            scanner.setBasedir( directory );
268    
269            scanner.setIncludes( StringUtils.split( includes, "," ) );
270    
271            scanner.setExcludes( StringUtils.split( excludes, "," ) );
272    
273            scanner.scan();
274    
275            return scanner.getIncludedFiles();
276        }
277    }