Checkstyle clean-up
[odlparent.git] / features-test / src / main / java / org / opendaylight / odlparent / featuretest / SingleFeatureTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.odlparent.featuretest;
10
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.CoreOptions.when;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
19 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
20 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
21 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
22
23 import java.io.File;
24 import java.io.InputStream;
25 import java.io.IOException;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28 import java.net.URL;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Properties;
32
33 import javax.inject.Inject;
34
35 import org.apache.karaf.features.Feature;
36 import org.apache.karaf.features.FeaturesService;
37 import org.apache.karaf.features.Repository;
38 import org.apache.karaf.features.internal.model.Features;
39 import org.apache.karaf.features.internal.model.JaxbUtil;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.ops4j.pax.exam.Configuration;
45 import org.ops4j.pax.exam.CoreOptions;
46 import org.ops4j.pax.exam.Option;
47 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
48 import org.ops4j.pax.exam.options.extra.VMOption;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 @RunWith(PerRepoTestRunner.class)
53 public class SingleFeatureTest {
54     private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
55     private static final String ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY = "org.ops4j.pax.url.mvn.localRepository";
56     private static final String ORG_OPS4J_PAX_URL_MVN_REPOSITORIES = "org.ops4j.pax.url.mvn.repositories";
57     private static final String ETC_ORG_OPS4J_PAX_URL_MVN_CFG = "etc/org.ops4j.pax.url.mvn.cfg";
58     private static final String ETC_ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
59     private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
60     private static final String LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST =
61             "log4j.logger.org.opendaylight.odlparent.featuretest";
62     private static final Logger LOG = LoggerFactory.getLogger(SingleFeatureTest.class);
63
64     /*
65      * File name to add our logging config property too.
66      */
67     private static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
68
69     /*
70      * Default values for karaf distro type, groupId, and artifactId
71      */
72     private static final String KARAF_DISTRO_TYPE = "zip";
73     private static final String KARAF_DISTRO_ARTIFACTID = "apache-karaf";
74     private static final String KARAF_DISTRO_GROUPID = "org.apache.karaf";
75
76     /*
77      * Property names to override defaults for karaf distro artifactId, groupId, version, and type
78      */
79     private static final String KARAF_DISTRO_VERSION_PROP = "karaf.distro.version";
80     private static final String KARAF_DISTRO_TYPE_PROP = "karaf.distro.type";
81     private static final String KARAF_DISTRO_ARTIFACTID_PROP = "karaf.distro.artifactId";
82     private static final String KARAF_DISTRO_GROUPID_PROP = "karaf.distro.groupId";
83
84     /**
85      * Property file used to store the Karaf distribution version.
86      */
87     private static final String PROPERTIES_FILENAME = "singlefeaturetest.properties";
88
89     /**
90      * <p>List of Karaf 3.0.4 default maven repositories with snapshot repositories excluded.</p>
91      * <p>Unfortunately this must be hard-coded since declarative model which uses Options,
92      * does not allow us to read value, parse it (properties has allways
93      * problems with lists) and construct replacement string which does
94      * not contains snapshots.</p>
95      * <p>When updating Karaf, check this against org.ops4j.pax.url.mvn.cfg in the Karaf distribution.</p>
96      */
97     private static final String EXTERNAL_DEFAULT_REPOSITORIES = "http://repo1.maven.org/maven2@id=central, "
98             + "http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, "
99             + "http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external, "
100             + "http://zodiac.springsource.com/maven/bundles/release@id=gemini ";
101
102
103     @Inject
104     private FeaturesService featuresService;
105
106     private String karafVersion;
107     private String karafDistroVersion;
108
109     /**
110      * Returns the required configuration.
111      *
112      * @return The Pax Exam configuration.
113      * @throws IOException if an error occurs.
114      */
115     @Configuration
116     public Option[] config() throws IOException {
117         return new Option[] {
118             // TODO: Find a way to inherit memory limits from Maven options.
119             new VMOption("-Xmx2g"),
120             new VMOption("-XX:MaxPermSize=512m"),
121             getKarafDistroOption(),
122             when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
123             configureConsole().ignoreLocalConsole(),
124             logLevel(LogLevel.WARN),
125             mvnLocalRepoOption(),
126             standardKarafFeatures(),
127             editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG, LOG4J_LOGGER_ORG_OPENDAYLIGHT_YANGTOOLS_FEATURETEST,
128                     LogLevel.INFO.name()),
129             editConfigurationFilePut(ETC_ORG_OPS4J_PAX_LOGGING_CFG, "log4j.rootLogger", "INFO, stdout, osgi:*"),
130              /*
131               *
132               * Disables external snapshot repositories.
133               *
134               * Pax URL and Karaf by default always search for new version of snapshots
135               * in all snapshots repository, even if that snapshots does not belong to that
136               * repository and maven is invoked even with -nsu (no snapshot update)
137               * or offline mode.
138               *
139               * This is also true for OpenDaylight snapshot artefacts - pax url tries
140               * to resolve them from third-party repositories, even if they are not present
141               * there - this increases time which takes for features to install.
142               *
143               * For more complex projects this actually means several HTTP GETs for each
144               * snapshot bundle referenced, even if the bundle is already present
145               * in local maven repository.
146               *
147               * In order to speed-up installation and remove unnecessary network traffic,
148               * which fails for obvious reasons, external snapshot repositories are
149               * removed.
150               *
151               *
152               */
153             disableExternalSnapshotRepositories(),
154             CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP).value(
155                     System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP)),
156             CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP).value(
157                     System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP)),
158             CoreOptions.systemProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP).value(
159                     System.getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP)),
160         };
161     }
162
163     private Option standardKarafFeatures() {
164         String url = maven().groupId("org.apache.karaf.features").artifactId("standard").classifier("features").type(
165                 "xml").version(getKarafVersion()).getURL();
166         try {
167             Features features = JaxbUtil.unmarshal(new URL(url).openStream(), false);
168             List<String> featureNames = new ArrayList<>();
169             for (Feature f : features.getFeature()) {
170                 featureNames.add(f.getName());
171             }
172
173             return features(url, featureNames.toArray(new String[featureNames.size()]));
174         } catch (Exception e) {
175             throw new RuntimeException("Could not obtain features from URL " + url, e);
176         }
177     }
178
179     private String getKarafVersion() {
180         if (karafVersion == null) {
181             // We use a properties file to retrieve ${karaf.version}, instead of .versionAsInProject()
182             // This avoids forcing all users to depend on Karaf in their POMs
183             Properties singleFeatureTestProps = new Properties();
184             try (InputStream singleFeatureTestInputStream = Thread.currentThread().getContextClassLoader()
185                     .getResourceAsStream(PROPERTIES_FILENAME)) {
186                 singleFeatureTestProps.load(singleFeatureTestInputStream);
187             } catch (IOException e) {
188                 LOG.error("Unable to load {} to determine the Karaf version", PROPERTIES_FILENAME, e);
189             }
190             karafVersion = singleFeatureTestProps.getProperty(KARAF_DISTRO_VERSION_PROP);
191
192             LOG.info("Retrieved karafVersion {} from properties file {}", karafVersion, PROPERTIES_FILENAME);
193         } else {
194             LOG.info("Retrieved karafVersion {} from system property {}", karafVersion, KARAF_DISTRO_VERSION_PROP);
195         }
196
197         return karafVersion;
198     }
199
200     private String getKarafDistroVersion() {
201         if (karafDistroVersion == null) {
202             karafDistroVersion = System.getProperty(KARAF_DISTRO_VERSION_PROP);
203             if (karafDistroVersion == null) {
204                 karafDistroVersion = getKarafVersion();
205             } else {
206                 LOG.info("Retrieved karafDistroVersion {} from system property {}", karafVersion,
207                         KARAF_DISTRO_VERSION_PROP);
208             }
209         }
210
211         return karafDistroVersion;
212     }
213
214     /**
215      * Disables snapshot repositories, which are enabled by default in karaf distribution.
216      *
217      * @return Edit Configuration option which removes external snapshot repositories.
218      */
219     private static Option disableExternalSnapshotRepositories() {
220         return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_REPOSITORIES,
221                 EXTERNAL_DEFAULT_REPOSITORIES);
222     }
223
224     protected Option mvnLocalRepoOption() {
225         String mvnRepoLocal = System.getProperty(MAVEN_REPO_LOCAL, "");
226         LOG.info("mvnLocalRepo \"{}\"", mvnRepoLocal);
227         return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,
228                 mvnRepoLocal);
229     }
230
231     protected Option getKarafDistroOption() {
232         String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP, KARAF_DISTRO_GROUPID);
233         String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP, KARAF_DISTRO_ARTIFACTID);
234         String type = System.getProperty(KARAF_DISTRO_TYPE_PROP, KARAF_DISTRO_TYPE);
235         LOG.info("Using karaf distro {} {} {} {}", groupId, artifactId, getKarafDistroVersion(), type);
236         return karafDistributionConfiguration()
237                 .frameworkUrl(
238                         maven()
239                                 .groupId(groupId)
240                                 .artifactId(artifactId)
241                                 .type(type)
242                                 .version(getKarafDistroVersion()))
243                 .name("OpenDaylight")
244                 .unpackDirectory(new File("target/pax"))
245                 .useDeployFolder(false);
246     }
247
248     private static URI getRepoUri() throws URISyntaxException {
249         return new URI(getProperty(ORG_OPENDAYLIGHT_FEATURETEST_URI_PROP));
250     }
251
252     private static String getFeatureName() {
253         return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATURENAME_PROP);
254     }
255
256     public String getFeatureVersion() {
257         return getProperty(ORG_OPENDAYLIGHT_FEATURETEST_FEATUREVERSION_PROP);
258     }
259
260     private static String getProperty(final String propName) {
261         String prop = System.getProperty(propName);
262         Assert.assertTrue("Missing property :" + propName, prop != null);
263         return prop;
264     }
265
266     private void checkRepository(final URI repoUri) {
267         Repository repo = null;
268         for (Repository r : featuresService.listRepositories()) {
269             if (r.getURI().equals(repoUri)) {
270                 repo = r;
271                 break;
272             }
273         }
274         Assert.assertNotNull("Repository not found: " + repoUri, repo);
275     }
276
277     /**
278      * Sets the repository up.
279      *
280      * @throws Exception if an error occurs.
281      */
282     @Before
283     public void installRepo() throws Exception {
284         final URI repoUri = getRepoUri();
285         LOG.info("Attempting to add repository {}", repoUri);
286         featuresService.addRepository(repoUri);
287         checkRepository(repoUri);
288         LOG.info("Successfully loaded repository {}", repoUri);
289     }
290
291     // Give it 5 minutes max as we've seen feature install hang on jenkins.
292     @Test(timeout = 300000)
293     public void installFeature() throws Exception {
294         LOG.info("Attempting to install feature {} {}", getFeatureName(), getFeatureVersion());
295         featuresService.installFeature(getFeatureName(), getFeatureVersion());
296         Feature feature = featuresService.getFeature(getFeatureName(), getFeatureVersion());
297         Assert.assertNotNull(
298                 "Attempt to get feature " + getFeatureName() + " " + getFeatureVersion() + "resulted in null", feature);
299         Assert.assertTrue("Failed to install Feature: " + getFeatureName() + " " + getFeatureVersion(),
300                 featuresService.isInstalled(feature));
301         LOG.info("Successfull installed feature {} {}", getFeatureName(), getFeatureVersion());
302     }
303 }