/******************************************************************************* * Copyright (c) 2011, 2013 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.List; import org.eclipse.core.runtime.Assert; import org.eclipse.osgi.util.NLS; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import junit.framework.AssertionFailedError; /** * @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 static TestConfiguration defaultConfiguration; public static TestConfiguration getDefault() { if (defaultConfiguration == null) { defaultConfiguration = new TestConfiguration(); defaultConfiguration.setDefaultOnly(CommonTestUtil.runHeartbeatTestsOnly()); } return defaultConfiguration; } public static void setDefault(TestConfiguration defaultConfiguration) { TestConfiguration.defaultConfiguration = defaultConfiguration; } private boolean localOnly; private boolean defaultOnly; private boolean headless; 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(); Exception[] exception = new Exception[1]; if (!CommonTestUtil.ignoreLocalTestServices()) { try { File file = CommonTestUtil.getFile(clazz, "local.json"); fixtures = discover(file.toURI().toASCIIString(), "", clazz, fixtureType, defaultOnly, exception); } 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, exception); } } if (fixtures.isEmpty()) { fixtures = discover(URL_SERVICES_DEFAULT + "/cgi-bin/services", URL_SERVICES_DEFAULT, clazz, fixtureType, defaultOnly, exception); } 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 }), exception[0]); } return fixtures; } private static <T> List<T> discover(String location, String baseUrl, Class<T> clazz, String fixtureType, boolean defaultOnly, Exception[] result) { Assert.isNotNull(fixtureType); List<FixtureConfiguration> configurations = getConfigurations(location, result); 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, Exception[] result) { 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) { result[0] = new IOException("IOException accessing " + url, e); return null; } } }