View Javadoc

1   /*
2    * DaCapo Benchmark Maven Plugin
3    * Copyright (C) 2010 Technische Universität Darmstadt
4    * info@scalabench.org
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.scalabench.plugins.dacapo;
19  
20  import static java.lang.String.format;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.SortedMap;
27  import java.util.TreeMap;
28  
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.MojoFailureException;
31  import org.scalabench.dacapo.callback.MarshallingSupport;
32  import org.scalabench.dacapo.callback.summary.Invocation;
33  import org.scalabench.dacapo.callback.summary.Iteration;
34  import org.scalabench.dacapo.callback.summary.Summary;
35  import org.scalabench.plugins.dacapo.util.SizeNameComparator;
36  
37  /**
38   * Perform sanity checks for integration testing.
39   * 
40   * Note: This goal only verifies the results. 
41   * 
42   * @since 0.1.0
43   * 
44   * @threadSafe
45   * @goal verify
46   * @phase verify
47   */
48  public class VerifyMojo extends AbstractIntegrationTestMojo {
49      
50      /**
51       * Set this to <code>true</code> to ignore failures during testing. Its use is <em>not recommended</em>, but quite
52       * convenient on occasion.
53       * 
54       * @parameter default-value="false" expression="${maven.test.failure.ignore}"
55       */
56      private boolean testFailureIgnore;
57      
58      /**
59       * The summary file to write integration test results to.
60       * 
61       * @parameter default-value="${project.build.directory}/dacapo-benchmark-reports/dacapo-benchmark-summary.xml"
62       */
63      private File summaryFile;
64      
65      public boolean isTestFailureIgnore() {
66          return testFailureIgnore;
67      }
68      
69      @Override
70      public void execute() throws MojoExecutionException, MojoFailureException {
71          if (isSkipExecution()) {
72              logInfo("Tests are skipped.");
73          } else { 
74              verifySummaryFile();
75          }
76      }
77      
78      private void verifySummaryFile() throws MojoExecutionException, MojoFailureException {
79          final Summary summary = loadSummaryFromFile();
80          reportBenchmarkInvocations(summary);
81      }
82      
83      private Summary loadSummaryFromFile() throws MojoExecutionException {
84          final Summary summary;
85          
86          logInfo("Verifying DaCapo benchmark summary file: %s", summaryFile);
87          
88          try {
89              summary = MarshallingSupport.loadSummary(summaryFile);
90          } catch (IOException e) {
91              throw new MojoExecutionException(format("Failed to load summary file: %s", summaryFile), e);
92          }
93          
94          if (!getBenchmarkName().equals(summary.getBenchmark()))
95              throw new MojoExecutionException(format("Found summary for wrong benchmark: %s", summary.getBenchmark()));
96          
97          return summary;
98      }
99      
100     public void reportBenchmarkInvocations(Summary result) throws MojoFailureException {
101         final SortedMap<String, List<Invocation>> invocationsPerSize =
102             new TreeMap<String, List<Invocation>>(new SizeNameComparator());
103         
104         for (Invocation invocation : result.getInvocations()) {
105             List<Invocation> invocations;
106             if ((invocations = invocationsPerSize.get(invocation.getSize())) == null)
107                 invocationsPerSize.put(invocation.getSize(), invocations = new ArrayList<Invocation>());
108             invocations.add(invocation);
109         }
110         
111         int failedInvocations = 0;
112         
113         for (String size : invocationsPerSize.keySet()) {
114             for (Invocation invocation : invocationsPerSize.get(size)) {
115                 final int failedIterations = countFailedIterations(invocation.getIterations());
116                 if (failedIterations > 0) {
117                     logError("Failed %2$d iterations of \"%1$s\" input size",  size, failedIterations);
118                     failedInvocations++;
119                 }
120             }
121             
122             if (failedInvocations > 0) {
123                 logError("Failed %2$d invocations of \"%1$s\" input size", size, failedInvocations);
124             }
125         }
126         
127         if (failedInvocations != 0) {
128             if (isTestFailureIgnore())
129                 logError("There are test failures.");
130             else
131                 throw new MojoFailureException("There are test failures.");
132         }
133     }
134     
135     public static int countFailedIterations(List<? extends Iteration> iterations) {
136         int failedIterations = 0;
137         
138         for (Iteration iteration : iterations)
139             if (!iteration.isValid())
140                 failedIterations++;
141         
142         return failedIterations;
143     }
144 }