blob: 84531b932fac3e4d279692e593a6aec26637ac38 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2012 EclipseSource Muenchen GmbH.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
******************************************************************************/
package org.eclipse.emf.emfstore.fuzzy.emf.diff;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.emfstore.fuzzy.emf.FuzzyUtil;
import org.eclipse.emf.emfstore.fuzzy.emf.config.TestConfig;
import org.eclipse.emf.emfstore.fuzzy.emf.config.TestRun;
/**
* An implementation of {@link TestRunProvider} to provide {@link TestRun}s created by the CI-Server Hudson.
*
* @author Julian Sommerfeldt
*
*/
public class HudsonTestRunProvider extends TestRunProvider {
private static final String JOB = "job/";
private static SAXReader saxReader = new SAXReader();
private String hudsonUrl;
private static String jobUrl;
private int firstBuildNumber;
private int secondBuildNumber;
/**
* The prefix for hudson peroperties.
*/
public static final String PROP_HUDSON = ".hudson";
/**
* The hudson url property.
*/
public static final String PROP_URL = ".url";
/**
* The hudson artifact folder property.
*/
public static final String PROP_ARTIFACT_FOLDER = ".artifact.folder";
/**
* The hudson port property.
*/
public static final String PROP_PORT = ".port";
/**
* The name of the hudson job property.
*/
public static final String PROP_JOB = ".job";
/**
* The property of the hudson diff job.
*/
public static final String PROP_DIFF_JOB = ".diffjob";
private static final String LAST_BUILD = "lastBuild";
/**
* An array containing all valid states of a hudson build. Valid means it can be used for creating diffs.
*/
public static final String[] VALID_STATES = new String[]{"SUCCESS", "UNSTABLE", "FAILURE"};
private static final String ARTIFACT = FuzzyUtil.getProperty(PROP_HUDSON + PROP_ARTIFACT_FOLDER, "/artifact/");
/**
* Standard constructor using the last build and the build before the last build for reading testruns.
*
* @throws DocumentException If it cannot read the buildnumbers correctly from hudson.
* @throws IOException If it cannot read the buildnumbers correctly from hudson.
*/
public HudsonTestRunProvider() throws DocumentException, IOException{
initProperties();
firstBuildNumber = getLastValidBuildNumber(Integer.parseInt(getFirstElementValue(jobUrl + LAST_BUILD + "/api/xml?tree=number")), jobUrl);
secondBuildNumber = getLastValidBuildNumber(firstBuildNumber - 1, jobUrl);
}
/**
* Constructor using tow special numbers for testruns.
*
* @param firstBuildNumber The number of the first build (first from the last one backwards, so it is later than the second one).
* @param secondBuildNumber The number of the second build.
*/
public HudsonTestRunProvider(int firstBuildNumber, int secondBuildNumber){
initProperties();
this.firstBuildNumber = firstBuildNumber;
this.secondBuildNumber = secondBuildNumber;
}
private void initProperties(){
hudsonUrl = getHudsonUrl();
jobUrl = hudsonUrl + JOB + FuzzyUtil.getProperty(PROP_HUDSON + PROP_JOB, "Explorer") + "/";
}
private static String getHudsonUrl(){
String port = FuzzyUtil.getProperty(PROP_HUDSON + PROP_PORT, null);
return FuzzyUtil.getProperty(PROP_HUDSON + PROP_URL, "http://localhost") + (port != null ? (":" + port) : "") + "/";
}
private static int getLastValidBuildNumber(int maxBuildNumber, String jobUrl) throws MalformedURLException, DocumentException{
if(maxBuildNumber < 0){
throw new RuntimeException("There are not enough valid builds till now!");
}
if(isValidBuild(maxBuildNumber, jobUrl)){
return maxBuildNumber;
} else {
return getLastValidBuildNumber(maxBuildNumber - 1, jobUrl);
}
}
private static boolean isValidBuild(int buildNumber, String jobUrl) throws MalformedURLException, DocumentException{
String result = getFirstElementValue(jobUrl + buildNumber + "/api/xml?tree=result");
for(String valid : VALID_STATES){
if(valid.equals(result)){
return true;
}
}
return false;
}
@SuppressWarnings("unchecked")
private static String getFirstElementValue(String url) throws MalformedURLException, DocumentException{
Document doc = saxReader.read(new URL(url));
List<Element> elements = doc.getRootElement().elements();
if(elements.size() == 0){
throw new RuntimeException("There are no elements in the result of the url: " + url);
}
return elements.get(0).getText();
}
@Override
public TestRun[] getTestRuns() throws IOException {
TestRun[] runs = new TestRun[2];
Resource resource = getTestRunResource(firstBuildNumber);
if(!FuzzyUtil.resourceExists(resource)){
throw new RuntimeException("No TestRun file for first run!");
}
resource.load(null);
runs[0] = getTestRun(resource);
resource = getTestRunResource(secondBuildNumber);
if(!FuzzyUtil.resourceExists(resource)){
throw new RuntimeException("No TestRun file for second run!");
}
resource.load(null);
runs[1] = getTestRun(resource);
return runs;
}
private Resource getTestRunResource(int buildNumber){
return FuzzyUtil.createResource(jobUrl + buildNumber + ARTIFACT +
FuzzyUtil.FUZZY_FOLDER + FuzzyUtil.RUN_FOLDER + getTestConfig().getId() + FuzzyUtil.FILE_SUFFIX);
}
/**
* @return All {@link TestConfig} which are loadable via this {@link HudsonTestRunProvider}.
*/
public List<TestConfig> getAllConfigs(){
Resource resource = FuzzyUtil.createResource(jobUrl + firstBuildNumber + ARTIFACT +
FuzzyUtil.FUZZY_FOLDER + FuzzyUtil.TEST_CONFIG_FILE);
try {
resource.load(null);
} catch (IOException e) {
throw new RuntimeException("Could not load configs file!", e);
}
List<TestConfig> configs = new ArrayList<TestConfig>();
for(EObject obj : resource.getContents()){
if (obj instanceof TestConfig) {
configs.add((TestConfig) obj);
}
}
return configs;
}
/**
* @return The diff resource created by hudson.
* @throws DocumentException
* @throws MalformedURLException
*/
public static Resource getDiffResource() throws MalformedURLException, DocumentException{
String diffJobUrl = getHudsonUrl() + JOB + FuzzyUtil.getProperty(PROP_HUDSON + PROP_DIFF_JOB, "Diff") + "/";
int lastValidNumber = getLastValidBuildNumber(Integer.parseInt(getFirstElementValue(diffJobUrl + LAST_BUILD + "/api/xml?tree=number")), diffJobUrl);
return FuzzyUtil.createResource(diffJobUrl + lastValidNumber + ARTIFACT + FuzzyUtil.FUZZY_FOLDER + "diff" + FuzzyUtil.FILE_SUFFIX);
}
}