1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.scalabench.plugins.dacapo;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.LinkedList;
25 import java.util.List;
26
27 import org.apache.maven.artifact.Artifact;
28 import org.apache.maven.execution.MavenSession;
29 import org.apache.maven.plugin.MojoExecutionException;
30 import org.apache.maven.plugin.MojoFailureException;
31 import org.apache.maven.toolchain.Toolchain;
32 import org.apache.maven.toolchain.ToolchainManager;
33 import org.codehaus.plexus.util.FileUtils;
34 import org.codehaus.plexus.util.StringUtils;
35 import org.codehaus.plexus.util.cli.CommandLineException;
36 import org.codehaus.plexus.util.cli.CommandLineUtils;
37 import org.codehaus.plexus.util.cli.Commandline;
38 import org.dacapo.parser.Config;
39 import org.scalabench.dacapo.callback.XmlSummaryCallback;
40 import org.scalabench.plugins.dacapo.util.SizeNameComparator;
41 import org.sonatype.aether.RepositorySystem;
42 import org.sonatype.aether.RepositorySystemSession;
43 import org.sonatype.aether.collection.CollectRequest;
44 import org.sonatype.aether.graph.Dependency;
45 import org.sonatype.aether.repository.RemoteRepository;
46 import org.sonatype.aether.resolution.ArtifactRequest;
47 import org.sonatype.aether.resolution.ArtifactResolutionException;
48 import org.sonatype.aether.resolution.ArtifactResult;
49 import org.sonatype.aether.resolution.DependencyRequest;
50 import org.sonatype.aether.resolution.DependencyResolutionException;
51 import org.sonatype.aether.resolution.DependencyResult;
52 import org.sonatype.aether.util.artifact.DefaultArtifact;
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class IntegrationTestMojo extends AbstractIntegrationTestMojo {
67
68
69
70
71
72
73
74
75 private File configurationDirectory;
76
77
78
79
80
81
82 private int testInvocations;
83
84
85
86
87
88
89 private int testIterations;
90
91
92
93
94
95
96 private File summaryFile;
97
98
99
100
101
102
103 private RepositorySystem repoSystem;
104
105
106
107
108
109
110
111 private RepositorySystemSession repoSession;
112
113
114
115
116
117
118
119
120 private List<RemoteRepository> remoteRepos;
121
122
123
124
125
126
127 private ToolchainManager toolchainManager;
128
129
130
131
132
133
134
135
136
137 private MavenSession session;
138
139 private static final DefaultArtifact CALLBACK_ARTIFACT =
140 new DefaultArtifact("org.scalabench.dacapo", "dacapo-benchmark-callback", "jar", "0.1.0-SNAPSHOT");
141
142 public File getConfigurationFile() {
143 return new File(getConfigurationDirectory(), getBenchmarkName() + ".cnf");
144 }
145
146 public File getConfigurationDirectory() {
147 return configurationDirectory;
148 }
149
150 public int getTestInvocations() {
151 return testInvocations;
152 }
153
154 public int getTestIterations() {
155 return testIterations;
156 }
157
158 public File getSummaryFile() {
159 return summaryFile;
160 }
161
162 @Override
163 public void execute() throws MojoExecutionException, MojoFailureException {
164 if (isSkipExecution()) {
165 logInfo("Tests are skipped.");
166 } else {
167 integrationTestBenchmark();
168 }
169 }
170
171 private void integrationTestBenchmark() throws MojoExecutionException, MojoFailureException {
172 final String javaExecutable = getJavaExecutable();
173 final Config config = Config.parse(getConfigurationFile());
174 final List<String> sizes = new LinkedList<String>(config.getSizes());
175
176 Collections.sort(sizes, new SizeNameComparator());
177
178 for (final String size : sizes) {
179 for (int invocation = 1; invocation <= getTestInvocations(); invocation++) {
180 logInfo("Running %4$d iterations with input size \"%1$s\" (invocation %2$d of %3$d)",
181 size, invocation, getTestInvocations(), getTestIterations());
182 performInvocation(javaExecutable, size);
183 }
184 }
185 }
186
187 private String getJavaExecutable() throws MojoExecutionException {
188 String javaExecutable;
189
190 if ((javaExecutable = getJavaPathFromBuildContext()) != null) {
191 logInfo("Selected toolchain (JDK) from build context: %s", javaExecutable);
192 return javaExecutable;
193 } else if ((javaExecutable = getDefaultJavaPath()) != null) {
194 logInfo("Selected default toolchain (JDK): %s", javaExecutable);
195 return javaExecutable;
196 } else {
197 throw new MojoExecutionException("Unable to locate toolchain (JDK)");
198 }
199 }
200
201 private String getJavaPathFromBuildContext() {
202 final Toolchain toolchain = toolchainManager.getToolchainFromBuildContext("jdk", session);
203 return toolchain == null ? null : toolchain.findTool("java");
204 }
205
206 private String getDefaultJavaPath() {
207 final String javaHome = System.getProperty("java.home");
208 return javaHome == null ? null : javaHome + File.separator + "bin" + File.separator + "java";
209 }
210
211 private void performInvocation(String javaExecutable, String size) throws MojoExecutionException, MojoFailureException {
212 final File workingDirectory = createWorkingDirectory(size);
213 logDebug("Created working directory: %s", workingDirectory);
214
215 try {
216 final Commandline cl = createCommandLine(javaExecutable, workingDirectory, size);
217 logDebug("Forking command line: %s ", cl);
218 CommandLineUtils.executeCommandLine(cl, null, null, 0);
219 } catch (CommandLineException e) {
220 throw new MojoFailureException("Forked process failed", e);
221 } finally {
222 deleteWorkingDirectory(workingDirectory);
223 }
224 }
225
226 private File createWorkingDirectory(String size) throws MojoFailureException {
227 final File workingDirectory = FileUtils.createTempFile(getBenchmarkName(), size, null);
228
229 if (!workingDirectory.mkdir())
230 throw new MojoFailureException("Cannot create working directory: " + workingDirectory);
231
232 return workingDirectory;
233 }
234
235 private void deleteWorkingDirectory(File workingDirectory) throws MojoFailureException {
236 try {
237 FileUtils.deleteDirectory(workingDirectory);
238 } catch (IOException e) {
239 throw new MojoFailureException("Cannot delete working directory", e);
240 }
241 }
242
243 private Commandline createCommandLine(String javaExecutable, File workingDirectory, String size)
244 throws MojoFailureException {
245 final Commandline commandLine = new Commandline();
246
247 commandLine.setExecutable(javaExecutable);
248 commandLine.setWorkingDirectory(workingDirectory);
249 commandLine.addArguments(new String[] {
250 "-D" + XmlSummaryCallback.SUMMARY_FILE_PROPERTY + "=" + getSummaryFile(),
251 "-classpath", StringUtils.join(getRuntimeClasspath().iterator(), File.pathSeparator),
252 "Harness",
253 getBenchmarkName(),
254 "--size", size,
255 "--iterations", Integer.toString(getTestIterations()),
256 "--callback", XmlSummaryCallback.class.getName()
257 });
258
259 return commandLine;
260 }
261
262 private ArrayList<File> getRuntimeClasspath() throws MojoFailureException {
263 final ArrayList<File> classpath = new ArrayList<File>();
264
265 classpath.addAll(getProjectClasspath());
266 classpath.addAll(getCallbackClasspath());
267
268 return classpath;
269 }
270
271 private List<File> getProjectClasspath() {
272 final List<File> projectClasspath = new ArrayList<File>();
273
274 projectClasspath.add(getProject().getArtifact().getFile());
275
276 for (final Artifact artifact : getProject().getArtifacts())
277 projectClasspath.add(artifact.getFile());
278
279 return projectClasspath;
280 }
281
282 private List<File> getCallbackClasspath() throws MojoFailureException {
283 try {
284 final List<File> callbackClasspath = new ArrayList<File>();
285
286 callbackClasspath.add(getCallbackArtifactFile());
287 callbackClasspath.addAll(getCallbackDependencyFiles());
288
289 return callbackClasspath;
290 } catch (DependencyResolutionException e) {
291 throw new MojoFailureException("Cannot construct classpath for benchmark callback", e);
292 } catch (ArtifactResolutionException e) {
293 throw new MojoFailureException("Cannot construct classpath for benchmark callback", e);
294 }
295 }
296
297 private File getCallbackArtifactFile() throws ArtifactResolutionException {
298 final ArtifactRequest request = new ArtifactRequest(CALLBACK_ARTIFACT, remoteRepos, null);
299 final ArtifactResult result = repoSystem.resolveArtifact(repoSession, request);
300 return result.getArtifact().getFile();
301 }
302
303 private List<File> getCallbackDependencyFiles() throws DependencyResolutionException {
304 final Dependency callbackDependency = new Dependency(CALLBACK_ARTIFACT, Artifact.SCOPE_RUNTIME);
305 final DependencyRequest request = new DependencyRequest(new CollectRequest(callbackDependency, remoteRepos), null);
306 final DependencyResult results = repoSystem.resolveDependencies(repoSession, request);
307 final List<File> dependencyFiles = new ArrayList<File>();
308
309 for (final ArtifactResult artifactResult : results.getArtifactResults())
310 dependencyFiles.add(artifactResult.getArtifact().getFile());
311
312 return dependencyFiles;
313 }
314 }