Home | History | Annotate | Download | only in model
      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.util.ArrayList;
     14 import java.util.List;
     15 import java.util.Vector;
     16 
     17 import org.eclipse.test.internal.performance.data.Dim;
     18 import org.eclipse.test.internal.performance.eval.StatisticsUtil;
     19 import org.eclipse.test.internal.performance.results.db.*;
     20 import org.eclipse.test.internal.performance.results.utils.Util;
     21 import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
     22 import org.eclipse.ui.views.properties.IPropertyDescriptor;
     23 import org.eclipse.ui.views.properties.PropertyDescriptor;
     24 import org.eclipse.ui.views.properties.TextPropertyDescriptor;
     25 
     26 public class BuildResultsElement extends ResultsElement {
     27 
     28 	// Property descriptors
     29     static final String P_ID_BUILD_DATE = "BuildResultsElement.date"; //$NON-NLS-1$
     30     static final String P_ID_BUILD_BASELINE = "BuildResultsElement.baseline"; //$NON-NLS-1$
     31     static final String P_ID_BUILD_COMMENT = "BuildResultsElement.comment"; //$NON-NLS-1$
     32     static final String P_ID_BUILD_SUMMARY_KIND = "BuildResultsElement.summarykind"; //$NON-NLS-1$
     33     static final String P_ID_BUILD_IS_BASELINE = "BuildResultsElement.isbaseline"; //$NON-NLS-1$
     34     static final String P_ID_BUILD_FAILURE = "BuildResultsElement.failure"; //$NON-NLS-1$
     35     static final String P_ID_BUILD_DELTA = "BuildResultsElement.delta"; //$NON-NLS-1$
     36     static final String P_ID_BUILD_ERROR = "BuildResultsElement.error"; //$NON-NLS-1$
     37     static final String P_ID_BUILD_TTEST = "BuildResultsElement.ttest"; //$NON-NLS-1$
     38 
     39     static final String P_STR_BUILD_DATE = "date"; //$NON-NLS-1$
     40     static final String P_STR_BUILD_COMMENT = "comment"; //$NON-NLS-1$
     41     static final String P_STR_BUILD_SUMMARY_KIND = "summary kind"; //$NON-NLS-1$
     42     static final String P_STR_BUILD_IS_BASELINE = "is baseline"; //$NON-NLS-1$
     43     static final String P_STR_BUILD_BASELINE = "baseline"; //$NON-NLS-1$
     44     static final String P_STR_BUILD_FAILURE = "failure"; //$NON-NLS-1$
     45     static final String P_STR_BUILD_DELTA = "delta with baseline"; //$NON-NLS-1$
     46     static final String P_STR_BUILD_ERROR = "delta error"; //$NON-NLS-1$
     47     static final String P_STR_BUILD_TTEST = "student's ttest"; //$NON-NLS-1$
     48 
     49 	private static final TextPropertyDescriptor BUILD_DATE_DESCRIPTOR = new TextPropertyDescriptor(P_ID_BUILD_DATE, P_STR_BUILD_DATE);
     50 	private static final TextPropertyDescriptor BUILD_COMMENT_DESCRIPTOR = new TextPropertyDescriptor(P_ID_BUILD_COMMENT, P_STR_BUILD_COMMENT);
     51 	private static final TextPropertyDescriptor BUILD_SUMMARY_DESCRIPTOR = new TextPropertyDescriptor(P_ID_BUILD_SUMMARY_KIND, P_STR_BUILD_SUMMARY_KIND);
     52 	private static final PropertyDescriptor BUILD_IS_BASELINE_DESCRIPTOR = new PropertyDescriptor(P_ID_BUILD_IS_BASELINE, P_STR_BUILD_IS_BASELINE);
     53 	private static final PropertyDescriptor BUILD_BASELINE_DESCRIPTOR = new PropertyDescriptor(P_ID_BUILD_BASELINE, P_STR_BUILD_BASELINE);
     54 	private static final TextPropertyDescriptor BUILD_TEST_FAILURE_DESCRIPTOR = new TextPropertyDescriptor(P_ID_BUILD_FAILURE, P_STR_BUILD_FAILURE);
     55 	private static final PropertyDescriptor BUILD_TEST_DELTA_DESCRIPTOR = new PropertyDescriptor(P_ID_BUILD_DELTA, P_STR_BUILD_DELTA);
     56 	private static final PropertyDescriptor BUILD_TEST_ERROR_DESCRIPTOR = new PropertyDescriptor(P_ID_BUILD_ERROR, P_STR_BUILD_ERROR);
     57 	private static final PropertyDescriptor BUILD_STUDENTS_TTEST_DESCRIPTOR = new PropertyDescriptor(P_ID_BUILD_TTEST, P_STR_BUILD_TTEST);
     58 
     59     private static Vector DESCRIPTORS;
     60     static Vector initDescriptors(int status) {
     61 		DESCRIPTORS = new Vector();
     62 		// Status category
     63 		DESCRIPTORS.add(getInfosDescriptor(status));
     64 		DESCRIPTORS.add(getWarningsDescriptor(status));
     65 		DESCRIPTORS.add(ERROR_DESCRIPTOR);
     66 		ERROR_DESCRIPTOR.setCategory("Status");
     67 		// Results category
     68         DESCRIPTORS.add(BUILD_DATE_DESCRIPTOR);
     69 		BUILD_DATE_DESCRIPTOR.setCategory("Results");
     70         DESCRIPTORS.add(BUILD_BASELINE_DESCRIPTOR);
     71 		BUILD_BASELINE_DESCRIPTOR.setCategory("Results");
     72         DESCRIPTORS.add(BUILD_COMMENT_DESCRIPTOR);
     73 		BUILD_COMMENT_DESCRIPTOR.setCategory("Results");
     74         DESCRIPTORS.add(BUILD_SUMMARY_DESCRIPTOR);
     75 		BUILD_SUMMARY_DESCRIPTOR.setCategory("Results");
     76         DESCRIPTORS.add(BUILD_IS_BASELINE_DESCRIPTOR);
     77 		BUILD_IS_BASELINE_DESCRIPTOR.setCategory("Results");
     78         DESCRIPTORS.add(BUILD_TEST_FAILURE_DESCRIPTOR);
     79 		BUILD_TEST_FAILURE_DESCRIPTOR.setCategory("Results");
     80         DESCRIPTORS.add(BUILD_TEST_DELTA_DESCRIPTOR);
     81 		BUILD_TEST_DELTA_DESCRIPTOR.setCategory("Results");
     82         DESCRIPTORS.add(BUILD_TEST_ERROR_DESCRIPTOR);
     83 		BUILD_TEST_ERROR_DESCRIPTOR.setCategory("Results");
     84         DESCRIPTORS.add(BUILD_STUDENTS_TTEST_DESCRIPTOR);
     85 		BUILD_STUDENTS_TTEST_DESCRIPTOR.setCategory("Results");
     86 		// Survey category
     87 		DESCRIPTORS.add(COMMENT_DESCRIPTOR);
     88 		COMMENT_DESCRIPTOR.setCategory("Survey");
     89         return DESCRIPTORS;
     90 	}
     91     static ComboBoxPropertyDescriptor getInfosDescriptor(int status) {
     92 		List list = new ArrayList();
     93 		if ((status & SMALL_VALUE) != 0) {
     94 			list.add("This test and/or its variation has a small value, hence it may not be necessary to spend time on fixing it if a regression occurs");
     95 		}
     96 		if ((status & STUDENT_TTEST) != 0) {
     97 			list.add("The student-t test error on this test is over the threshold");
     98 		}
     99 		String[] infos = new String[list.size()];
    100 		if (list.size() > 0) {
    101 			list.toArray(infos);
    102 		}
    103 		ComboBoxPropertyDescriptor infoDescriptor = new ComboBoxPropertyDescriptor(P_ID_STATUS_INFO, P_STR_STATUS_INFO, infos);
    104 		infoDescriptor.setCategory("Status");
    105 		return infoDescriptor;
    106 	}
    107     static PropertyDescriptor getWarningsDescriptor(int status) {
    108 		List list = new ArrayList();
    109 		if ((status & BIG_ERROR) != 0) {
    110 			list.add("The error on this test is over the 3% threshold, hence its result may not be really reliable");
    111 		}
    112 		if ((status & NOT_RELIABLE) != 0) {
    113 			list.add("The results history shows that the variation of its delta is over 20%, hence its result is surely not reliable");
    114 		}
    115 		if ((status & NOT_STABLE) != 0) {
    116 			list.add("The results history shows that the variation of its delta is between 10% and 20%, hence its result may not be really reliable");
    117 		}
    118 		if ((status & NO_BASELINE) != 0) {
    119 			list.add("There's no baseline to compare with");
    120 		}
    121 		if ((status & SINGLE_RUN) != 0) {
    122 			list.add("This test has only one run, hence no error can be computed to verify if it's stable enough to be reliable");
    123 		}
    124 		String[] warnings = new String[list.size()];
    125 		if (list.size() > 0) {
    126 			list.toArray(warnings);
    127 		}
    128 		ComboBoxPropertyDescriptor warningDescriptor = new ComboBoxPropertyDescriptor(P_ID_STATUS_WARNING, P_STR_STATUS_WARNING, warnings);
    129 		warningDescriptor.setCategory("Status");
    130 		return warningDescriptor;
    131     }
    132     static Vector getDescriptors() {
    133     	return DESCRIPTORS;
    134 	}
    135 
    136 	    // Model info
    137 	boolean important;
    138 	boolean milestone;
    139 
    140 public BuildResultsElement(AbstractResults results, ResultsElement parent) {
    141 	super(results, parent);
    142 	initInfo();
    143 }
    144 
    145 public BuildResultsElement(String name, ResultsElement parent) {
    146 	super(name, parent);
    147 	initInfo();
    148 }
    149 
    150 public int compareTo(Object o) {
    151 	if (o instanceof BuildResultsElement && getName() != null) {
    152 		BuildResultsElement element = (BuildResultsElement)o;
    153 		if (element.getName() != null) {
    154 			String buildDate = Util.getBuildDate(element.name);
    155 			return Util.getBuildDate(this.name).compareTo(buildDate);
    156 		}
    157 	}
    158 	return super.compareTo(o);
    159 }
    160 
    161 ResultsElement createChild(AbstractResults testResults) {
    162 	return null;
    163 }
    164 
    165 private BuildResults getBuildResults() {
    166 	return (BuildResults) this.results;
    167 }
    168 
    169 public Object[] getChildren(Object o) {
    170 	if (this.results == null) {
    171 		return new Object[0];
    172 	}
    173 	if (this.children == null) {
    174 		initChildren();
    175 	}
    176 	return this.children;
    177 }
    178 
    179 public Object getEditableValue() {
    180 	if (this.results == null)  {
    181 		return "Build "+this.name;
    182 	}
    183 	return this.results.toString();
    184 }
    185 
    186 /* (non-Javadoc)
    187  * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
    188  */
    189 public IPropertyDescriptor[] getPropertyDescriptors() {
    190 	Vector descriptors = getDescriptors();
    191 	if (descriptors == null) {
    192 		descriptors = initDescriptors(getStatus());
    193 	}
    194 	int size = descriptors.size();
    195 	IPropertyDescriptor[] descriptorsArray = new IPropertyDescriptor[size];
    196 	descriptorsArray[0] = getInfosDescriptor(getStatus());
    197 	descriptorsArray[1] = getWarningsDescriptor(getStatus());
    198 	for (int i=2; i<size; i++) {
    199 		descriptorsArray[i] = (IPropertyDescriptor) descriptors.get(i);
    200 	}
    201 	return descriptorsArray;
    202 }
    203 
    204 /* (non-Javadoc)
    205  * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
    206  */
    207 public Object getPropertyValue(Object propKey) {
    208 	BuildResults buildResults = getBuildResults();
    209 	if (buildResults != null) {
    210 		ConfigResults configResults = (ConfigResults) buildResults.getParent();
    211 		BuildResults baselineResults = configResults.getBaselineBuildResults(buildResults.getName());
    212 	    if (propKey.equals(P_ID_BUILD_DATE))
    213 	        return buildResults.getDate();
    214 	    if (propKey.equals(P_ID_BUILD_COMMENT))
    215 	        return buildResults.getComment();
    216 	    if (propKey.equals(P_ID_BUILD_SUMMARY_KIND)) {
    217 	    	int summaryKind = buildResults.getSummaryKind();
    218 			if (summaryKind == 1) {
    219 	    		return "global";
    220 	    	}
    221 	    	if (summaryKind >= 0) {
    222 	    		return "component";
    223 	    	}
    224 	    	return "none";
    225 	    }
    226 	    if (propKey.equals(P_ID_BUILD_IS_BASELINE))
    227 	        return new Boolean(buildResults.isBaseline());
    228 	    if (propKey.equals(P_ID_BUILD_FAILURE))
    229 	        return buildResults.getFailure();
    230 	    if (baselineResults != null) {
    231 		    if (propKey.equals(P_ID_BUILD_BASELINE)) {
    232 		        return baselineResults.getName();
    233 		    }
    234 			double buildValue = buildResults.getValue();
    235 			double baselineValue = baselineResults.getValue();
    236 			double delta = (baselineValue - buildValue) / baselineValue;
    237 			if (Double.isNaN(delta)) {
    238 			    if (propKey.equals(P_ID_BUILD_DELTA) || propKey.equals(P_ID_BUILD_ERROR)) {
    239 			        return new Double(Double.NaN);
    240 			    }
    241 			} else  if (propKey.equals(P_ID_BUILD_DELTA)) {
    242 				return new Double(delta);
    243 		    } else {
    244 				long baselineCount = baselineResults.getCount();
    245 				long currentCount = buildResults.getCount();
    246 				if (baselineCount > 1 && currentCount > 1) {
    247 					if (propKey.equals(P_ID_BUILD_TTEST)) {
    248 						double ttestValue = Util.computeTTest(baselineResults, buildResults);
    249 						int degreeOfFreedom = (int) (baselineResults.getCount()+buildResults.getCount()-2);
    250 						if (ttestValue >= 0 && StatisticsUtil.getStudentsT(degreeOfFreedom, StatisticsUtil.T90) >= ttestValue) {
    251 							return new Double(ttestValue);
    252 						}
    253 					}
    254 				    if (propKey.equals(P_ID_BUILD_ERROR)) {
    255 						double baselineError = baselineResults.getError();
    256 						double currentError = buildResults.getError();
    257 						double error = Double.isNaN(baselineError)
    258 								? currentError / baselineValue
    259 								: Math.sqrt(baselineError*baselineError + currentError*currentError) / baselineValue;
    260 				        return new Double(error);
    261 				    }
    262 				} else {
    263 				    if (propKey.equals(P_ID_BUILD_ERROR))
    264 				        return new Double(-1);
    265 				}
    266 			}
    267 	    }
    268 	}
    269 	if (propKey.equals(P_ID_STATUS_ERROR)) {
    270 		if ((getStatus() & BIG_DELTA) != 0) {
    271 			return "The delta on this test is over the 10% threshold, hence may indicate a possible regression.";
    272 		}
    273 	}
    274 	return super.getPropertyValue(propKey);
    275 }
    276 
    277 /**
    278  * Return the statistics of the build along its history.
    279  *
    280  * @return An array of double built as follows:
    281  * <ul>
    282  * <li>0:	numbers of values</li>
    283  * <li>1:	mean of values</li>
    284  * <li>2:	standard deviation of these values</li>
    285  * <li>3:	coefficient of variation of these values</li>
    286  * </ul>
    287  */
    288 double[] getStatistics() {
    289 	if (this.statistics  == null) {
    290 		this.statistics = ((ConfigResults)getBuildResults().getParent()).getStatistics(Util.BASELINE_BUILD_PREFIXES);
    291 	}
    292 	return this.statistics;
    293 }
    294 
    295 void initChildren() {
    296 	BuildResults buildResults = (BuildResults) this.results;
    297 	Dim[] dimensions = buildResults.getDimensions();
    298 	int length = dimensions.length;
    299 	this.children = new DimResultsElement[length];
    300 	for (int i=0; i<length; i++) {
    301 		this.children[i] = new DimResultsElement(this.results, this, dimensions[i]);
    302 	}
    303 }
    304 
    305 /*
    306  * Init information
    307  */
    308 void initInfo() {
    309 	this.milestone = Util.isMilestone(getName());
    310 	this.important = this.milestone || Util.getNextMilestone(this.name) == null;
    311 }
    312 
    313 void initStatus() {
    314 	if (this.results == null) {
    315 		if (this.parent.isInitialized()) {
    316 			if (((PerformanceResultsElement) this.parent).hasRead(this)) {
    317 				this.status = READ;
    318 			} else {
    319 				this.status = UNREAD;
    320 			}
    321 		} else {
    322 			this.status = UNKNOWN;
    323 		}
    324 	} else if (getBuildResults().isBaseline()) {
    325 		// TODO (frederic) report high variation in baseline results along history
    326 		this.status = READ;
    327 	} else {
    328 		initStatus(getBuildResults());
    329 	}
    330 }
    331 
    332 /**
    333  * Returns whether the build is important to be shown.
    334  * This is the case for milestone builds or for the last builds.
    335  *
    336  * @return <code>true</code>  or <code>false</code> .
    337  */
    338 public boolean isImportant() {
    339 	return this.important;
    340 }
    341 
    342 /**
    343  * Returns whether the build is a milestone one or not.
    344  *
    345  * @return <code>true</code>  or <code>false</code> .
    346  */
    347 public boolean isMilestone() {
    348 	return this.milestone;
    349 }
    350 
    351 public boolean isRead() {
    352 	return (getStatus()  & STATE_MASK) == READ;
    353 }
    354 
    355 public boolean isUnknown() {
    356 	return (getStatus()  & STATE_MASK) == UNKNOWN;
    357 }
    358 
    359 /* (non-Javadoc)
    360  * @see java.lang.Object#toString()
    361  */
    362 public String toString() {
    363 	return getName();
    364 }
    365 public boolean isBefore(String build) {
    366 	if (this.results != null) {
    367 		return Util.getBuildDate(this.name).compareTo(Util.getBuildDate(build)) <= 0;
    368 	}
    369 	return true;
    370 }
    371 
    372 }
    373