1 /*******************************************************************************
2 * Copyright (c) 2000, 2009 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.test.internal.performance.results.model;
12
13 import java.io.BufferedOutputStream;
14 import java.io.DataOutputStream;
15 import java.io.File;
16 import java.io.FileNotFoundException;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.util.Arrays;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.test.internal.performance.results.db.*;
22 import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants;
23 import org.eclipse.test.internal.performance.results.utils.Util;
24
25 public class PerformanceResultsElement extends ResultsElement {
26
27 // Singleton pattern
28 public static PerformanceResultsElement PERF_RESULTS_MODEL = new PerformanceResultsElement();
29
30 String[] buildNames;
31 String lastBuildName;
32 boolean fingerprints = true;
33
PerformanceResultsElement()34 public PerformanceResultsElement() {
35 super();
36 }
37
createChild(AbstractResults testResults)38 ResultsElement createChild(AbstractResults testResults) {
39 return new ComponentResultsElement(testResults, this);
40 }
41
getBaselines()42 public String[] getBaselines() {
43 getBuildNames();
44 if (this.buildNames == null) {
45 return new String[0];
46 }
47 int length = this.buildNames.length;
48 String[] baselines = new String[length];
49 int count = 0;
50 for (int i=0; i<length; i++) {
51 if (this.buildNames[i].startsWith("R-")) {
52 baselines[count++] = this.buildNames[i];
53 }
54 }
55 if (count < length) {
56 System.arraycopy(baselines, 0, baselines = new String [count], 0, count);
57 }
58 return baselines;
59 }
60
getBuildNames()61 String[] getBuildNames() {
62 if (this.buildNames == null) {
63 this.buildNames = DB_Results.DB_CONNECTION
64 ? DB_Results.getBuilds()
65 : this.results == null
66 ? new String[0]
67 : getPerformanceResults().getAllBuildNames();
68 }
69 return this.buildNames;
70 }
71
getBuilds()72 public Object[] getBuilds() {
73 getBuildNames();
74 int length = this.buildNames == null ? 0 : this.buildNames.length;
75 BuildResultsElement[] elements = new BuildResultsElement[length];
76 for (int i=0; i<length; i++) {
77 elements[i] = new BuildResultsElement(this.buildNames[i], this);
78 }
79 return elements;
80 }
81
getComponents()82 public String[] getComponents() {
83 if (!isInitialized()) {
84 String[] components = DB_Results.getComponents();
85 int length = components.length;
86 if (length == 0) {
87 DB_Results.queryAllScenarios();
88 components = DB_Results.getComponents();
89 }
90 return components;
91 }
92 return getPerformanceResults().getComponents();
93 }
94
95 /**
96 * Returns the names of the configurations.
97 *
98 * @return An array of String
99 */
getConfigs()100 public String[] getConfigs() {
101 if (!isInitialized()) {
102 String[] configs = DB_Results.getConfigs();
103 int length = configs.length;
104 if (length == 0) {
105 DB_Results.queryAllScenarios();
106 configs = DB_Results.getConfigs();
107 }
108 return configs;
109 }
110 return getPerformanceResults().getConfigNames(false);
111 }
112
113 /**
114 * Returns the descriptions of the configurations.
115 *
116 * @return An array of String
117 */
getConfigDescriptions()118 public String[] getConfigDescriptions() {
119 if (!isInitialized()) {
120 String[] descriptions = DB_Results.getConfigDescriptions();
121 int length = descriptions.length;
122 if (length == 0) {
123 DB_Results.queryAllScenarios();
124 descriptions = DB_Results.getConfigDescriptions();
125 }
126 return descriptions;
127 }
128 return getPerformanceResults().getConfigBoxes(false);
129 }
130
getElements()131 public Object[] getElements() {
132 if (!isInitialized()) {
133 String[] components = getComponents();
134 int length = components.length;
135 ComponentResultsElement[] elements = new ComponentResultsElement[length];
136 for (int i=0; i<length; i++) {
137 elements[i] = new ComponentResultsElement(components[i], this);
138 }
139 return elements;
140 }
141 return getChildren(null);
142 }
143
getPerformanceResults()144 public PerformanceResults getPerformanceResults() {
145 return (PerformanceResults) this.results;
146 }
147
hasRead(BuildResultsElement buildResultsElement)148 boolean hasRead(BuildResultsElement buildResultsElement) {
149 String[] builds = this.results == null ? getBuildNames() : getPerformanceResults().getAllBuildNames();
150 if (Arrays.binarySearch(builds, buildResultsElement.getName(), Util.BUILD_DATE_COMPARATOR) < 0) {
151 return false;
152 }
153 return true;
154 }
155
isInitialized()156 public boolean isInitialized() {
157 return super.isInitialized() && this.results.size() > 0;
158 }
159
readLocal(File dataDir, IProgressMonitor monitor, String lastBuild)160 public void readLocal(File dataDir, IProgressMonitor monitor, String lastBuild) {
161 reset(lastBuild);
162 PerformanceResults performanceResults = getPerformanceResults();
163 performanceResults.setLastBuildName(lastBuild);
164 performanceResults.readLocal(dataDir, monitor);
165 }
166
reset(String buildName)167 public void reset(String buildName) {
168 if (buildName == null) {
169 this.results = new PerformanceResults(this.lastBuildName, null, null, System.out);
170 } else {
171 this.results = new PerformanceResults(buildName, null, null, System.out);
172 }
173 this.children = null;
174 this.buildNames = null;
175 }
176
resetBuildNames()177 public void resetBuildNames() {
178 this.buildNames = null;
179 }
180
updateBuild(String buildName, boolean force, File dataDir, IProgressMonitor monitor)181 public void updateBuild(String buildName, boolean force, File dataDir, IProgressMonitor monitor) {
182 if (this.results == null) {
183 reset(buildName);
184 }
185 getPerformanceResults().updateBuild(buildName, force, dataDir, monitor);
186 }
187
updateBuilds(String[] builds, boolean force, File dataDir, IProgressMonitor monitor)188 public void updateBuilds(String[] builds, boolean force, File dataDir, IProgressMonitor monitor) {
189 if (this.results == null) {
190 reset(null);
191 }
192 getPerformanceResults().updateBuilds(builds, force, dataDir, monitor);
193 }
194
195 /**
196 * Set whether only fingerprints should be taken into account or not.
197 *
198 * @param fingerprints
199 */
setFingerprints(boolean fingerprints)200 public void setFingerprints(boolean fingerprints) {
201 this.fingerprints = fingerprints;
202 resetStatus();
203 }
204
setLastBuildName(String lastBuildName)205 public void setLastBuildName(String lastBuildName) {
206 this.lastBuildName = lastBuildName;
207 this.name = null;
208 }
209
210 /*
211 * Write the component status in the given file
212 */
writeStatus(File resultsFile, int kind)213 public StringBuffer writeStatus(File resultsFile, int kind) {
214 if (this.results == null) {
215 return null;
216 }
217 boolean values = (kind & IPerformancesConstants.STATUS_VALUES) != 0;
218 // Write status only for component with error
219 StringBuffer excluded = new StringBuffer();
220 try {
221 DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(resultsFile)));
222 try {
223 StringBuffer buffer = new StringBuffer();
224 // Print build name
225 buffer.append("Status for ");
226 buffer.append(getPerformanceResults().getName());
227 buffer.append(Util.LINE_SEPARATOR);
228 // Print status options
229 if ((kind & ~IPerformancesConstants.STATUS_VALUES) > 0) {
230 buffer.append("Options: ");
231 buffer.append(Util.LINE_SEPARATOR);
232 final int errorLevel = kind & IPerformancesConstants.STATUS_ERROR_LEVEL_MASK;
233 if (errorLevel != 0) {
234 buffer.append(" error level: ");
235 switch (errorLevel) {
236 case IPerformancesConstants.STATUS_ERROR_NONE:
237 buffer.append("include all failures whatever the error level is");
238 break;
239 case IPerformancesConstants.STATUS_ERROR_NOTICEABLE:
240 buffer.append("all failures with at least a noticeable error (> 3%) are excluded!");
241 break;
242 case IPerformancesConstants.STATUS_ERROR_SUSPICIOUS:
243 buffer.append("all failures with at least a suspicious error (> 25%) are excluded!");
244 break;
245 case IPerformancesConstants.STATUS_ERROR_WEIRD:
246 buffer.append("all failures with at least a weird error (> 50%) are excluded!");
247 break;
248 case IPerformancesConstants.STATUS_ERROR_INVALID:
249 buffer.append("all failures with an invalid error (> 100%) are excluded!");
250 break;
251 }
252 buffer.append(Util.LINE_SEPARATOR);
253 }
254 final int smallValue = kind & IPerformancesConstants.STATUS_SMALL_VALUE_MASK;
255 if (smallValue > 0) {
256 buffer.append(" small value: ");
257 switch (smallValue) {
258 case IPerformancesConstants.STATUS_SMALL_VALUE_BUILD:
259 buffer.append("all failures with a small build value (<100ms) are excluded!");
260 break;
261 case IPerformancesConstants.STATUS_SMALL_VALUE_DELTA:
262 buffer.append("all failures with a small delta value (<100ms) are excluded!");
263 break;
264 case IPerformancesConstants.STATUS_SMALL_VALUE_MASK:
265 buffer.append("all failures with a small build or delta value (<100ms) are excluded!");
266 break;
267 }
268 buffer.append(Util.LINE_SEPARATOR);
269 }
270 final int stats = kind & IPerformancesConstants.STATUS_STATISTICS_MASK;
271 if (stats > 0) {
272 buffer.append(" statistics: ");
273 switch (stats) {
274 case IPerformancesConstants.STATUS_STATISTICS_ERRATIC:
275 buffer.append("all failures with erratic baseline results (variation > 20%) are excluded!");
276 break;
277 case IPerformancesConstants.STATUS_STATISTICS_UNSTABLE:
278 buffer.append("all failures with unstable baseline results (10% < variation < 20%) are excluded!");
279 break;
280 }
281 buffer.append(Util.LINE_SEPARATOR);
282 }
283 int buildsNumber = kind & IPerformancesConstants.STATUS_BUILDS_NUMBER_MASK;
284 buffer.append(" builds to confirm a regression: ");
285 buffer.append(buildsNumber);
286 buffer.append(Util.LINE_SEPARATOR);
287 }
288 // Print columns title
289 buffer.append("Component");
290 buffer.append(" Scenario");
291 buffer.append(" Machine");
292 if (values) {
293 buffer.append(" Build ");
294 buffer.append(" History ");
295 }
296 buffer.append(" Comment");
297 buffer.append(Util.LINE_SEPARATOR);
298 if (values) {
299 buffer.append(" value");
300 buffer.append(" baseline");
301 buffer.append(" variation");
302 buffer.append(" delta");
303 buffer.append(" error");
304 buffer.append(" n");
305 buffer.append(" mean");
306 buffer.append(" deviation");
307 buffer.append(" coeff");
308 buffer.append(Util.LINE_SEPARATOR);
309 }
310 stream.write(buffer.toString().getBytes());
311 StringBuffer componentBuffer = writableStatus(new StringBuffer(), kind, excluded);
312 if (componentBuffer.length() > 0) {
313 stream.write(componentBuffer.toString().getBytes());
314 }
315 }
316 finally {
317 stream.close();
318 }
319 } catch (FileNotFoundException e) {
320 System.err.println("Can't create output file"+resultsFile); //$NON-NLS-1$
321 } catch (IOException e) {
322 e.printStackTrace();
323 }
324 return excluded;
325 }
326
327 }
328