• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package vogar;
18 
19 import java.io.File;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashSet;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import vogar.tasks.BuildActionTask;
28 import vogar.tasks.PrepareTarget;
29 import vogar.tasks.PrepareUserDirTask;
30 import vogar.tasks.RetrieveFilesTask;
31 import vogar.tasks.RmTask;
32 import vogar.tasks.Task;
33 import vogar.util.TimeUtilities;
34 
35 /**
36  * Compiles, installs, runs and reports on actions.
37  */
38 public final class Driver {
39     private final Run run;
40 
Driver(Run run)41     public Driver(Run run) {
42         this.run = run;
43     }
44 
45     private int successes = 0;
46     private int failures = 0;
47     private int skipped = 0;
48     private int warnings = 0;
49 
50     private Task prepareTargetTask;
51     private Set<Task> installVogarTasks;
52 
53     private final Map<String, Action> actions = Collections.synchronizedMap(
54             new LinkedHashMap<String, Action>());
55     private final Map<String, Outcome> outcomes = Collections.synchronizedMap(
56             new LinkedHashMap<String, Outcome>());
57     public boolean recordResults = true;
58 
59     /**
60      * Builds and executes the actions in the given files.
61      */
buildAndRun(Collection<File> files, Collection<String> classes)62     public boolean buildAndRun(Collection<File> files, Collection<String> classes) {
63         if (!actions.isEmpty()) {
64             throw new IllegalStateException("Drivers are not reusable");
65         }
66 
67         run.mkdir.mkdirs(run.localTemp);
68 
69         filesToActions(files);
70         classesToActions(classes);
71 
72         if (actions.isEmpty()) {
73             run.console.info("Nothing to do.");
74             return false;
75         }
76 
77         run.console.info("Actions: " + actions.size());
78         final long t0 = System.currentTimeMillis();
79 
80         prepareTargetTask = new PrepareTarget(run, run.target);
81         run.taskQueue.enqueue(prepareTargetTask);
82 
83         installVogarTasks = run.mode.installTasks();
84         run.taskQueue.enqueueAll(installVogarTasks);
85         registerPrerequisites(Collections.singleton(prepareTargetTask), installVogarTasks);
86 
87         for (Action action : actions.values()) {
88             action.setUserDir(new File(run.runnerDir, action.getName()));
89             Outcome outcome = outcomes.get(action.getName());
90             if (outcome != null) {
91                 addEarlyResult(outcome);
92             } else if (run.expectationStore.get(action.getName()).getResult()
93                     == Result.UNSUPPORTED) {
94                 addEarlyResult(new Outcome(action.getName(), Result.UNSUPPORTED,
95                     "Unsupported according to expectations file"));
96             } else {
97                 enqueueActionTasks(action);
98             }
99         }
100 
101         if (run.cleanAfter) {
102             Set<Task> shutdownTasks = new HashSet<Task>();
103             shutdownTasks.add(new RmTask(run.rm, run.localTemp));
104             shutdownTasks.add(run.target.rmTask(run.runnerDir));
105             for (Task task : shutdownTasks) {
106                 task.after(run.taskQueue.getTasks());
107             }
108             run.taskQueue.enqueueAll(shutdownTasks);
109         }
110 
111         run.taskQueue.printTasks();
112         run.taskQueue.runTasks();
113         if (run.taskQueue.hasFailedTasks()) {
114             run.taskQueue.printProblemTasks();
115             return false;
116         }
117 
118         if (run.reportPrinter.isReady()) {
119             run.console.info("Printing XML Reports... ");
120             int numFiles = run.reportPrinter.generateReports(outcomes.values());
121             run.console.info(numFiles + " XML files written.");
122         }
123 
124         long t1 = System.currentTimeMillis();
125 
126         Map<String, AnnotatedOutcome> annotatedOutcomes = run.outcomeStore.read(this.outcomes);
127         if (recordResults) {
128             run.outcomeStore.write(outcomes);
129         }
130 
131         run.console.summarizeOutcomes(annotatedOutcomes.values());
132 
133         List<String> jarStringList = run.jarSuggestions.getStringList();
134         if (!jarStringList.isEmpty()) {
135             run.console.warn(
136                     "consider adding the following to the classpath:",
137                     jarStringList);
138         }
139 
140         if (failures > 0 || skipped > 0 || warnings > 0) {
141             run.console.info(String.format(
142                     "Outcomes: %s. Passed: %d, Failed: %d, Skipped: %d, Warnings: %d. Took %s.",
143                     (successes + failures + warnings + skipped), successes, failures, skipped, warnings,
144                     TimeUtilities.msToString(t1 - t0)));
145         } else {
146             run.console.info(String.format("Outcomes: %s. All successful. Took %s.",
147                     successes, TimeUtilities.msToString(t1 - t0)));
148         }
149         return failures == 0;
150     }
151 
enqueueActionTasks(Action action)152     private void enqueueActionTasks(Action action) {
153         Expectation expectation = run.expectationStore.get(action.getName());
154         boolean useLargeTimeout = expectation.getTags().contains("large");
155         File jar = run.hostJar(action);
156         Task build = new BuildActionTask(run, action, this, jar);
157         run.taskQueue.enqueue(build);
158 
159         Task prepareUserDir = new PrepareUserDirTask(run.target, action);
160         prepareUserDir.after(installVogarTasks);
161         run.taskQueue.enqueue(prepareUserDir);
162 
163         Set<Task> install = run.mode.installActionTasks(action, jar);
164         registerPrerequisites(Collections.singleton(build), install);
165         registerPrerequisites(installVogarTasks, install);
166         registerPrerequisites(Collections.singleton(prepareTargetTask), install);
167         run.taskQueue.enqueueAll(install);
168 
169         Task execute = run.mode.executeActionTask(action, useLargeTimeout)
170                 .afterSuccess(installVogarTasks)
171                 .afterSuccess(build)
172                 .afterSuccess(prepareUserDir)
173                 .afterSuccess(install);
174         run.taskQueue.enqueue(execute);
175 
176         Task retrieveFiles = new RetrieveFilesTask(run, action.getUserDir()).after(execute);
177         run.taskQueue.enqueue(retrieveFiles);
178 
179         if (run.cleanAfter) {
180             run.taskQueue.enqueue(new RmTask(run.rm, run.localFile(action))
181                     .after(execute).after(retrieveFiles));
182             Set<Task> cleanupTasks = run.mode.cleanupTasks(action);
183             for (Task task : cleanupTasks) {
184                 task.after(execute).after(retrieveFiles);
185             }
186             run.taskQueue.enqueueAll(cleanupTasks);
187         }
188     }
189 
registerPrerequisites(Set<Task> allBefore, Set<Task> allAfter)190     private void registerPrerequisites(Set<Task> allBefore, Set<Task> allAfter) {
191         for (Task task : allAfter) {
192             task.afterSuccess(allBefore);
193         }
194     }
195 
classesToActions(Collection<String> classNames)196     private void classesToActions(Collection<String> classNames) {
197         for (String className : classNames) {
198             Action action = new Action(className, className, null, null, null);
199             actions.put(action.getName(), action);
200         }
201     }
202 
filesToActions(Collection<File> files)203     private void filesToActions(Collection<File> files) {
204         for (File file : files) {
205             new ActionFinder(run.console, actions, outcomes).findActions(file);
206         }
207     }
208 
addEarlyResult(Outcome earlyFailure)209     public synchronized void addEarlyResult(Outcome earlyFailure) {
210         if (earlyFailure.getResult() == Result.UNSUPPORTED) {
211             run.console.verbose("skipped " + earlyFailure.getName());
212             skipped++;
213 
214         } else {
215             for (String line : earlyFailure.getOutputLines()) {
216                 run.console.streamOutput(earlyFailure.getName(), line + "\n");
217             }
218             recordOutcome(earlyFailure);
219         }
220     }
221 
recordOutcome(Outcome outcome)222     public synchronized void recordOutcome(Outcome outcome) {
223         outcomes.put(outcome.getName(), outcome);
224         Expectation expectation = run.expectationStore.get(outcome);
225         ResultValue resultValue = outcome.getResultValue(expectation);
226 
227         if (resultValue == ResultValue.OK) {
228             successes++;
229         } else if (resultValue == ResultValue.FAIL) {
230             failures++;
231         } else if (resultValue == ResultValue.WARNING) {
232             warnings++;
233         } else { // ResultValue.IGNORE
234             skipped++;
235         }
236 
237         Result result = outcome.getResult();
238         run.console.outcome(outcome.getName());
239         run.console.printResult(outcome.getName(), result, resultValue, expectation);
240 
241         JarSuggestions singleOutcomeJarSuggestions = new JarSuggestions();
242         singleOutcomeJarSuggestions.addSuggestionsFromOutcome(outcome, run.classFileIndex,
243                 run.classpath);
244         List<String> jarStringList = singleOutcomeJarSuggestions.getStringList();
245         if (!jarStringList.isEmpty()) {
246             run.console.warn(
247                     "may have failed because some of these jars are missing from the classpath:",
248                     jarStringList);
249         }
250         run.jarSuggestions.addSuggestions(singleOutcomeJarSuggestions);
251     }
252 }
253