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 34 public PerformanceResultsElement() { 35 super(); 36 } 37 38 ResultsElement createChild(AbstractResults testResults) { 39 return new ComponentResultsElement(testResults, this); 40 } 41 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 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 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 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 */ 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 */ 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 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 144 public PerformanceResults getPerformanceResults() { 145 return (PerformanceResults) this.results; 146 } 147 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 156 public boolean isInitialized() { 157 return super.isInitialized() && this.results.size() > 0; 158 } 159 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 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 177 public void resetBuildNames() { 178 this.buildNames = null; 179 } 180 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 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 */ 200 public void setFingerprints(boolean fingerprints) { 201 this.fingerprints = fingerprints; 202 resetStatus(); 203 } 204 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 */ 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