* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+
package org.opendaylight.odlparent.featuretest;
import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP;
import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP;
import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP;
import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.when;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
-//import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
import javax.inject.Inject;
+
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
+import org.ops4j.pax.exam.options.extra.VMOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
@RunWith(PerRepoTestRunner.class)
public class SingleFeatureTest {
+
private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
private static final String ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY = "org.ops4j.pax.url.mvn.localRepository";
private static final String ORG_OPS4J_PAX_URL_MVN_REPOSITORIES = "org.ops4j.pax.url.mvn.repositories";
private static final String ETC_ORG_OPS4J_PAX_URL_MVN_CFG = "etc/org.ops4j.pax.url.mvn.cfg";
- private static final String LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST = "log4j.logger.org.opendaylight.odlparent.featuretest";
+ private static final String ETC_ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
+ private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
+ private static final String PROFILE_PROP = "karaf.featureTest.profile";
+
+ private static final String LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST =
+ "log4j.logger.org.opendaylight.odlparent.featuretest";
private static final Logger LOG = LoggerFactory.getLogger(SingleFeatureTest.class);
/*
private static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
/*
- * Default values for karaf distro version, type, groupId, and artifactId
+ * Default values for karaf distro type, groupId, and artifactId
*/
- private static final String KARAF_DISTRO_VERSION = "3.0.2";
private static final String KARAF_DISTRO_TYPE = "zip";
private static final String KARAF_DISTRO_ARTIFACTID = "apache-karaf";
private static final String KARAF_DISTRO_GROUPID = "org.apache.karaf";
private static final String KARAF_DISTRO_ARTIFACTID_PROP = "karaf.distro.artifactId";
private static final String KARAF_DISTRO_GROUPID_PROP = "karaf.distro.groupId";
+ /**
+ * Property file used to store the Karaf distribution version.
+ */
+ private static final String PROPERTIES_FILENAME = "singlefeaturetest.properties";
/**
- * List of karaf 3.0.2 default maven repositories with snapshot repositories excluded.
- *
- * Unfortunately this must be hard-coded since declarative model which uses Options,
+ * <p>List of Karaf 3.0.4 default maven repositories with snapshot repositories excluded.</p>
+ * <p>Unfortunately this must be hard-coded since declarative model which uses Options,
* does not allow us to read value, parse it (properties has allways
* problems with lists) and construct replacement string which does
- * not contains snapshots.
- *
+ * not contains snapshots.</p>
+ * <p>When updating Karaf, check this against org.ops4j.pax.url.mvn.cfg in the Karaf distribution.</p>
*/
- private static final String EXTERNAL_DEFAULT_REPOSITORIES = "http://repo1.maven.org/maven2@id=central, " +
- "http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, " +
- "http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, " +
- "http://zodiac.springsource.com/maven/bundles/release@id=gemini ";
+ private static final String EXTERNAL_DEFAULT_REPOSITORIES = "http://repo1.maven.org/maven2@id=central, "
+ + "http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, "
+ + "http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, "
+ + "http://zodiac.springsource.com/maven/bundles/release@id=gemini ";
- @Inject
- private FeaturesService featuresService;
+ @Inject
+ private FeaturesService featuresService;
+ private String karafVersion;
+ private String karafDistroVersion;
+
+ /**
+ * Returns the required configuration.
+ *
+ * @return The Pax Exam configuration.
+ * @throws IOException if an error occurs.
+ */
@Configuration
public Option[] config() throws IOException {
- return new Option[] {
- getKarafDistroOption(),
- keepRuntimeFolder(),
- configureConsole().ignoreLocalConsole(),
- logLevel(LogLevel.WARN),
- mvnLocalRepoOption(),
- editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,LogLevel.INFO.name()),
+ return new Option[] {
+ // TODO: Find a way to inherit memory limits from Maven options.
+ new VMOption("-Xmx2g"),
+ new VMOption("-XX:MaxPermSize=512m"),
+ when(Boolean.getBoolean(PROFILE_PROP)).useOptions(
+ new VMOption("-XX:+UnlockCommercialFeatures"),
+ new VMOption("-XX:+FlightRecorder"),
+ new VMOption("-XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath="
+ + getNewJFRFile())
+ ),
+ getKarafDistroOption(),
+ when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
+ configureConsole().ignoreLocalConsole(),
+ logLevel(LogLevel.WARN),
+ mvnLocalRepoOption(),
+ standardKarafFeatures(),
+ editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG, LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,
+ LogLevel.INFO.name()),
+ editConfigurationFilePut(ETC_ORG_OPS4J_PAX_LOGGING_CFG, "log4j.rootLogger", "INFO, stdout, osgi:*"),
/*
*
* Disables external snapshot repositories.
*
*
*/
- disableExternalSnapshotRepositories(),
- CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP).value(System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP)),
- CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP).value(System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP)),
- CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP).value(System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP)),
- };
+ disableExternalSnapshotRepositories(),
+ CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP).value(
+ System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP)),
+ CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP).value(
+ System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP)),
+ CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP).value(
+ System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP)),
+ };
+ }
+
+ private String getNewJFRFile() throws IOException {
+ return File.createTempFile("SingleFeatureTest-Karaf-JavaFlightRecorder", ".jfr").getAbsolutePath();
+ }
+
+ private Option standardKarafFeatures() throws IOException {
+ String url = maven().groupId("org.apache.karaf.features").artifactId("standard").classifier("features").type(
+ "xml").version(getKarafVersion()).getURL();
+ try {
+ Features features = JaxbUtil.unmarshal(new URL(url).openStream(), false);
+ List<String> featureNames = new ArrayList<>();
+ for (Feature f : features.getFeature()) {
+ featureNames.add(f.getName());
+ }
+
+ return features(url, featureNames.toArray(new String[featureNames.size()]));
+ } catch (IOException e) {
+ throw new IOException("Could not obtain features from URL: " + url, e);
+ }
+ }
+
+ private String getKarafVersion() {
+ if (karafVersion == null) {
+ // We use a properties file to retrieve ${karaf.version}, instead of .versionAsInProject()
+ // This avoids forcing all users to depend on Karaf in their POMs
+ Properties singleFeatureTestProps = new Properties();
+ try (InputStream singleFeatureTestInputStream = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(PROPERTIES_FILENAME)) {
+ singleFeatureTestProps.load(singleFeatureTestInputStream);
+ } catch (IOException e) {
+ LOG.error("Unable to load {} to determine the Karaf version", PROPERTIES_FILENAME, e);
+ }
+ karafVersion = singleFeatureTestProps.getProperty(KARAF_DISTRO_VERSION_PROP);
+
+ LOG.info("Retrieved karafVersion {} from properties file {}", karafVersion, PROPERTIES_FILENAME);
+ } else {
+ LOG.info("Retrieved karafVersion {} from system property {}", karafVersion, KARAF_DISTRO_VERSION_PROP);
+ }
+
+ return karafVersion;
+ }
+
+ private String getKarafDistroVersion() {
+ if (karafDistroVersion == null) {
+ karafDistroVersion = System.getProperty(KARAF_DISTRO_VERSION_PROP);
+ if (karafDistroVersion == null) {
+ karafDistroVersion = getKarafVersion();
+ } else {
+ LOG.info("Retrieved karafDistroVersion {} from system property {}", karafVersion,
+ KARAF_DISTRO_VERSION_PROP);
+ }
+ }
+
+ return karafDistroVersion;
}
/**
- *
* Disables snapshot repositories, which are enabled by default in karaf distribution.
*
- *
- *
* @return Edit Configuration option which removes external snapshot repositories.
*/
private static Option disableExternalSnapshotRepositories() {
- return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_REPOSITORIES,EXTERNAL_DEFAULT_REPOSITORIES);
+ return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_REPOSITORIES,
+ EXTERNAL_DEFAULT_REPOSITORIES);
}
protected Option mvnLocalRepoOption() {
String mvnRepoLocal = System.getProperty(MAVEN_REPO_LOCAL, "");
- LOG.info("mvnLocalRepo \"{}\"",mvnRepoLocal);
- Option option =
- editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG,ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,mvnRepoLocal);
- return option;
+ LOG.info("mvnLocalRepo \"{}\"", mvnRepoLocal);
+ return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,
+ mvnRepoLocal);
}
protected Option getKarafDistroOption() {
- String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP,KARAF_DISTRO_GROUPID);
- String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP,KARAF_DISTRO_ARTIFACTID);
- String version = System.getProperty(KARAF_DISTRO_VERSION_PROP,KARAF_DISTRO_VERSION);
- String type = System.getProperty(KARAF_DISTRO_TYPE_PROP,KARAF_DISTRO_TYPE);
- LOG.info("Using karaf distro {} {} {} {}",groupId,artifactId,version,type);
+ String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP, KARAF_DISTRO_GROUPID);
+ String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP, KARAF_DISTRO_ARTIFACTID);
+ String type = System.getProperty(KARAF_DISTRO_TYPE_PROP, KARAF_DISTRO_TYPE);
+ LOG.info("Using karaf distro {} {} {} {}", groupId, artifactId, getKarafDistroVersion(), type);
return karafDistributionConfiguration()
.frameworkUrl(
maven()
.groupId(groupId)
.artifactId(artifactId)
.type(type)
- .version(version))
- .name("OpenDaylight")
- .unpackDirectory(new File("target/pax"))
- .useDeployFolder(false);
+ .version(getKarafDistroVersion()))
+ .name("OpenDaylight")
+ .unpackDirectory(new File("target/pax"))
+ .useDeployFolder(false);
}
- private URI getRepoURI() throws URISyntaxException {
+ private static URI getRepoUri() throws URISyntaxException {
return new URI(getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP));
}
- private String getFeatureName() {
+ private static String getFeatureName() {
return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP);
}
return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP);
}
- private String getProperty(final String propName) {
+ private static String getProperty(final String propName) {
String prop = System.getProperty(propName);
- Assert.assertTrue("Missing property :" +propName, prop!=null);
+ Assert.assertTrue("Missing property :" + propName, prop != null);
return prop;
}
- private void checkRepository(final URI repoURI) {
+ private void checkRepository(final URI repoUri) {
Repository repo = null;
- for(Repository r: featuresService.listRepositories()) {
- if(r.getURI().equals(repoURI)){
+ for (Repository r : featuresService.listRepositories()) {
+ if (r.getURI().equals(repoUri)) {
repo = r;
break;
}
}
- Assert.assertNotNull("Repository not found: " + repoURI,repo);
+ Assert.assertNotNull("Repository not found: " + repoUri, repo);
}
+ /**
+ * Sets the repository up.
+ *
+ * @throws Exception if an error occurs.
+ */
@Before
public void installRepo() throws Exception {
- LOG.info("Attempting to add repository {}", getRepoURI());
- featuresService.addRepository(getRepoURI());
- checkRepository(getRepoURI());
- LOG.info("Successfully loaded repository {}", getRepoURI());
+ final URI repoUri = getRepoUri();
+ LOG.info("Attempting to add repository {}", repoUri);
+ featuresService.addRepository(repoUri);
+ checkRepository(repoUri);
+ LOG.info("Successfully loaded repository {}", repoUri);
}
- @Test
+ // Give it 10 minutes max as we've seen feature install hang on jenkins.
+ @Test(timeout = 600000)
public void installFeature() throws Exception {
- LOG.info("Attempting to install feature {} {}", getFeatureName(),getFeatureVersion());
- featuresService.installFeature(getFeatureName(), getFeatureVersion());
- Feature f = featuresService.getFeature(getFeatureName(), getFeatureVersion());
- Assert.assertNotNull("Attempt to get feature "+ getFeatureName() + " " + getFeatureVersion() + "resulted in null" , f);
- Assert.assertTrue("Failed to install Feature: " + getFeatureName() + " " + getFeatureVersion(),featuresService.isInstalled(f));
- LOG.info("Successfull installed feature {} {}", getFeatureName(),getFeatureVersion());
+ LOG.info("Attempting to install feature {} {}", getFeatureName(), getFeatureVersion());
+ featuresService.installFeature(getFeatureName(), getFeatureVersion());
+ Feature feature = featuresService.getFeature(getFeatureName(), getFeatureVersion());
+ Assert.assertNotNull(
+ "Attempt to get feature " + getFeatureName() + " " + getFeatureVersion() + "resulted in null", feature);
+ Assert.assertTrue("Failed to install Feature: " + getFeatureName() + " " + getFeatureVersion(),
+ featuresService.isInstalled(feature));
+ LOG.info("Successfull installed feature {} {}", getFeatureName(), getFeatureVersion());
}
}