2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.odlparent.featuretest;
11 import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP;
12 import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP;
13 import static org.opendaylight.odlparent.featuretest.Constants.ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP;
14 import static org.ops4j.pax.exam.CoreOptions.maven;
15 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
19 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
22 import java.io.InputStream;
23 import java.io.IOException;
25 import java.net.URISyntaxException;
26 import java.util.Properties;
27 import javax.inject.Inject;
28 import org.apache.karaf.features.Feature;
29 import org.apache.karaf.features.FeaturesService;
30 import org.apache.karaf.features.Repository;
31 import org.junit.Assert;
32 import org.junit.Before;
33 import org.junit.runner.RunWith;
34 import org.junit.Test;
35 import org.ops4j.pax.exam.Configuration;
36 import org.ops4j.pax.exam.CoreOptions;
37 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
38 import org.ops4j.pax.exam.Option;
39 import org.ops4j.pax.exam.options.extra.VMOption;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 @RunWith(PerRepoTestRunner.class)
45 public class SingleFeatureTest {
46 private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
47 private static final String ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY = "org.ops4j.pax.url.mvn.localRepository";
48 private static final String ORG_OPS4J_PAX_URL_MVN_REPOSITORIES = "org.ops4j.pax.url.mvn.repositories";
49 private static final String ETC_ORG_OPS4J_PAX_URL_MVN_CFG = "etc/org.ops4j.pax.url.mvn.cfg";
50 private static final String LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST =
51 "log4j.logger.org.opendaylight.odlparent.featuretest";
52 private static final Logger LOG = LoggerFactory.getLogger(SingleFeatureTest.class);
55 * File name to add our logging config property too.
57 private static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
60 * Default values for karaf distro type, groupId, and artifactId
62 private static final String KARAF_DISTRO_TYPE = "zip";
63 private static final String KARAF_DISTRO_ARTIFACTID = "apache-karaf";
64 private static final String KARAF_DISTRO_GROUPID = "org.apache.karaf";
67 * Property names to override defaults for karaf distro artifactId, groupId, version, and type
69 private static final String KARAF_DISTRO_VERSION_PROP = "karaf.distro.version";
70 private static final String KARAF_DISTRO_TYPE_PROP = "karaf.distro.type";
71 private static final String KARAF_DISTRO_ARTIFACTID_PROP = "karaf.distro.artifactId";
72 private static final String KARAF_DISTRO_GROUPID_PROP = "karaf.distro.groupId";
75 * Property file used to store the Karaf distribution version
77 private static final String PROPERTIES_FILENAME = "singlefeaturetest.properties";
80 * <p>List of Karaf 3.0.4 default maven repositories with snapshot repositories excluded.</p>
81 * <p>Unfortunately this must be hard-coded since declarative model which uses Options,
82 * does not allow us to read value, parse it (properties has allways
83 * problems with lists) and construct replacement string which does
84 * not contains snapshots.</p>
85 * <p>When updating Karaf, check this against org.ops4j.pax.url.mvn.cfg in the Karaf distribution.</p>
87 private static final String EXTERNAL_DEFAULT_REPOSITORIES = "http://repo1.maven.org/maven2@id=central, "
88 + "http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, "
89 + "http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, "
90 + "http://zodiac.springsource.com/maven/bundles/release@id=gemini ";
94 private FeaturesService featuresService;
97 * Returns the required configuration.
99 * @return The Pax Exam configuration.
100 * @throws IOException if an error occurs.
103 public Option[] config() throws IOException {
104 return new Option[] {
105 // TODO: Find a way to inherit memory limits from Maven options.
106 new VMOption("-Xmx2g"),
107 new VMOption("-XX:MaxPermSize=512m"),
108 getKarafDistroOption(),
110 configureConsole().ignoreLocalConsole(),
111 logLevel(LogLevel.WARN),
112 mvnLocalRepoOption(),
113 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG, LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,
114 LogLevel.INFO.name()),
117 * Disables external snapshot repositories.
119 * Pax URL and Karaf by default always search for new version of snapshots
120 * in all snapshots repository, even if that snapshots does not belong to that
121 * repository and maven is invoked even with -nsu (no snapshot update)
124 * This is also true for OpenDaylight snapshot artefacts - pax url tries
125 * to resolve them from third-party repositories, even if they are not present
126 * there - this increases time which takes for features to install.
128 * For more complex projects this actually means several HTTP GETs for each
129 * snapshot bundle referenced, even if the bundle is already present
130 * in local maven repository.
132 * In order to speed-up installation and remove unnecessary network traffic,
133 * which fails for obvious reasons, external snapshot repositories are
138 disableExternalSnapshotRepositories(),
139 CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP).value(
140 System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP)),
141 CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP).value(
142 System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP)),
143 CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP).value(
144 System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP)),
149 * Disables snapshot repositories, which are enabled by default in karaf distribution.
151 * @return Edit Configuration option which removes external snapshot repositories.
153 private static Option disableExternalSnapshotRepositories() {
154 return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_REPOSITORIES,
155 EXTERNAL_DEFAULT_REPOSITORIES);
158 protected Option mvnLocalRepoOption() {
159 String mvnRepoLocal = System.getProperty(MAVEN_REPO_LOCAL, "");
160 LOG.info("mvnLocalRepo \"{}\"", mvnRepoLocal);
161 return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,
165 protected Option getKarafDistroOption() {
166 String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP, KARAF_DISTRO_GROUPID);
167 String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP, KARAF_DISTRO_ARTIFACTID);
168 String version = System.getProperty(KARAF_DISTRO_VERSION_PROP);
169 String type = System.getProperty(KARAF_DISTRO_TYPE_PROP, KARAF_DISTRO_TYPE);
170 if (version == null) {
171 // We use a properties file to retrieve ${karaf.version}, instead of .versionAsInProject()
172 // This avoids forcing all users to depend on Karaf in their POMs
173 Properties singleFeatureTestProps = new Properties();
174 try (InputStream singleFeatureTestInputStream = Thread.currentThread().getContextClassLoader()
175 .getResourceAsStream(PROPERTIES_FILENAME)) {
176 singleFeatureTestProps.load(singleFeatureTestInputStream);
177 } catch (IOException e) {
178 LOG.error("Unable to load {} to determine the Karaf version", PROPERTIES_FILENAME, e);
180 version = singleFeatureTestProps.getProperty(KARAF_DISTRO_VERSION_PROP);
182 LOG.info("Using karaf distro {} {} {} {}", groupId, artifactId, version, type);
183 return karafDistributionConfiguration()
187 .artifactId(artifactId)
190 .name("OpenDaylight")
191 .unpackDirectory(new File("target/pax"))
192 .useDeployFolder(false);
195 private static URI getRepoUri() throws URISyntaxException {
196 return new URI(getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP));
199 private static String getFeatureName() {
200 return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP);
203 public String getFeatureVersion() {
204 return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP);
207 private static String getProperty(final String propName) {
208 String prop = System.getProperty(propName);
209 Assert.assertTrue("Missing property :" + propName, prop != null);
213 private void checkRepository(final URI repoUri) {
214 Repository repo = null;
215 for (Repository r : featuresService.listRepositories()) {
216 if (r.getURI().equals(repoUri)) {
221 Assert.assertNotNull("Repository not found: " + repoUri, repo);
225 * Sets the repository up.
227 * @throws Exception if an error occurs.
230 public void installRepo() throws Exception {
231 final URI repoUri = getRepoUri();
232 LOG.info("Attempting to add repository {}", repoUri);
233 featuresService.addRepository(repoUri);
234 checkRepository(repoUri);
235 LOG.info("Successfully loaded repository {}", repoUri);
238 // Give it 5 minutes max as we've seen feature install hang on jenkins.
239 @Test(timeout = 300000)
240 public void installFeature() throws Exception {
241 LOG.info("Attempting to install feature {} {}", getFeatureName(), getFeatureVersion());
242 featuresService.installFeature(getFeatureName(), getFeatureVersion());
243 Feature feature = featuresService.getFeature(getFeatureName(), getFeatureVersion());
244 Assert.assertNotNull(
245 "Attempt to get feature " + getFeatureName() + " " + getFeatureVersion() + "resulted in null", feature);
246 Assert.assertTrue("Failed to install Feature: " + getFeatureName() + " " + getFeatureVersion(),
247 featuresService.isInstalled(feature));
248 LOG.info("Successfull installed feature {} {}", getFeatureName(), getFeatureVersion());