blob: 8edfa01cf1073671ad542e27e18c53e4b6886eaa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Tasktop Technologies and others.
* 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:
* Tasktop Technologies - initial API and implementation
* Guy Perron - add Windows support
*******************************************************************************/
package org.eclipse.mylyn.commons.sdk.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import junit.framework.AssertionFailedError;
import org.eclipse.core.runtime.Assert;
import org.eclipse.osgi.util.NLS;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/**
* @author Steffen Pingel
*/
public class TestConfiguration {
private static final String URL_SERVICES_LOCALHOST = System.getProperty("localhost.test.server",
"http://localhost:2080");
private static final String URL_SERVICES_DEFAULT = System.getProperty("mylyn.test.server", "http://mylyn.org");
public enum TestKind {
UNIT, COMPONENT, INTEGRATION, SYSTEM
};
public static TestConfiguration defaultConfiguration;
public static TestConfiguration getDefault() {
if (defaultConfiguration == null) {
defaultConfiguration = new TestConfiguration(TestKind.UNIT);
defaultConfiguration.setDefaultOnly(CommonTestUtil.runHeartbeatTestsOnly());
}
return defaultConfiguration;
}
public static void setDefault(TestConfiguration defaultConfiguration) {
TestConfiguration.defaultConfiguration = defaultConfiguration;
}
private final EnumSet<TestKind> kinds;
private boolean localOnly;
private boolean defaultOnly;
private boolean headless;
public TestConfiguration(TestKind firstKind, TestKind... moreKinds) {
Assert.isNotNull(firstKind);
this.kinds = EnumSet.of(firstKind, moreKinds);
}
public boolean hasKind(TestKind kind) {
return kinds.contains(kind);
}
public boolean isDefaultOnly() {
return defaultOnly;
}
public boolean isHeadless() {
return headless;
}
public boolean isLocalOnly() {
return localOnly;
}
public void setDefaultOnly(boolean heartbeat) {
this.defaultOnly = heartbeat;
}
public void setHeadless(boolean headless) {
this.headless = headless;
}
public void setLocalOnly(boolean localOnly) {
this.localOnly = localOnly;
}
public <T> List<T> discover(Class<T> clazz, String fixtureType) {
return discover(clazz, fixtureType, isDefaultOnly());
}
public <T> T discoverDefault(Class<T> clazz, String fixtureType) {
List<T> fixtures = discover(clazz, fixtureType, true);
if (fixtures.isEmpty()) {
throw new RuntimeException(NLS.bind("No default fixture available for {0}", fixtureType));
}
return fixtures.get(0);
}
public <T> List<T> discover(Class<T> clazz, String fixtureType, boolean defaultOnly) {
List<T> fixtures = Collections.emptyList();
if (!CommonTestUtil.ignoreLocalTestServices()) {
try {
File file = CommonTestUtil.getFile(clazz, "local.json");
fixtures = discover(file.toURI().toASCIIString(), "", clazz, fixtureType, defaultOnly);
} catch (AssertionFailedError e) {
// ignore
} catch (IOException e) {
// ignore
}
if (fixtures.isEmpty()) {
fixtures = discover(URL_SERVICES_LOCALHOST + "/cgi-bin/services", URL_SERVICES_LOCALHOST, clazz,
fixtureType, defaultOnly);
}
}
if (fixtures.isEmpty()) {
fixtures = discover(URL_SERVICES_DEFAULT + "/cgi-bin/services", URL_SERVICES_DEFAULT, clazz, fixtureType,
defaultOnly);
}
if (fixtures.isEmpty()) {
throw new RuntimeException(NLS.bind(
"Failed to discover any fixtures for kind {0} with defaultOnly={1} ({2} and {3})", new Object[] {
fixtureType, Boolean.toString(defaultOnly), URL_SERVICES_LOCALHOST, URL_SERVICES_DEFAULT }));
}
return fixtures;
}
private static <T> List<T> discover(String location, String baseUrl, Class<T> clazz, String fixtureType,
boolean defaultOnly) {
Assert.isNotNull(fixtureType);
List<FixtureConfiguration> configurations = getConfigurations(location);
if (configurations != null) {
for (FixtureConfiguration configuration : configurations) {
if (configuration != null) {
configuration.setUrl(baseUrl + configuration.getUrl());
}
}
return loadFixtures(configurations, clazz, fixtureType, defaultOnly);
}
return Collections.emptyList();
}
private static <T> List<T> loadFixtures(List<FixtureConfiguration> configurations, Class<T> clazz,
String fixtureType, boolean defaultOnly) {
List<T> result = new ArrayList<T>();
String defaultOverwriteUrl = System.getProperty("mylyn.tests.configuration.url", "");
for (FixtureConfiguration configuration : configurations) {
if (configuration != null
&& fixtureType.equals(configuration.getType())
&& (!defaultOnly || (defaultOverwriteUrl.equals("") && configuration.isDefault()) || (configuration.url.equals(defaultOverwriteUrl)))) {
try {
Constructor<T> constructor = clazz.getConstructor(FixtureConfiguration.class);
result.add(constructor.newInstance(configuration));
} catch (Exception e) {
throw new RuntimeException("Unexpected error creating test fixture", e);
}
}
}
return result;
}
private static List<FixtureConfiguration> getConfigurations(String url) {
try {
URLConnection connection = new URL(url).openConnection();
InputStreamReader in = new InputStreamReader(connection.getInputStream());
try {
TypeToken<List<FixtureConfiguration>> type = new TypeToken<List<FixtureConfiguration>>() {
};
return new Gson().fromJson(in, type.getType());
} finally {
in.close();
}
} catch (IOException e) {
return null;
}
}
}