84dcd65e48ce25f66a8a4fe5070f4b8fa78f6a09
[controller.git] / opendaylight / config / config-it-base / src / main / java / org / opendaylight / controller / config / it / base / AbstractConfigTestBase.java
1 /*
2  * Copyright (c) 2015 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.controller.config.it.base;
10
11 import static org.ops4j.pax.exam.CoreOptions.maven;
12 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
13 import static org.ops4j.pax.exam.CoreOptions.when;
14 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
15 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
18 import com.google.common.base.Stopwatch;
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.lang.management.ManagementFactory;
23 import java.util.Properties;
24 import java.util.concurrent.TimeUnit;
25 import javax.management.ObjectName;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.internal.AssumptionViolatedException;
29 import org.junit.rules.TestRule;
30 import org.junit.rules.TestWatcher;
31 import org.junit.runner.Description;
32 import org.opendaylight.controller.config.api.ConfigRegistry;
33 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
34 import org.ops4j.pax.exam.Configuration;
35 import org.ops4j.pax.exam.Option;
36 import org.ops4j.pax.exam.OptionUtils;
37 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
38 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
39 import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
40 import org.ops4j.pax.exam.options.MavenUrlReference;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public abstract class AbstractConfigTestBase {
45     private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
46     private static final String ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY = "org.ops4j.pax.url.mvn.localRepository";
47     private static final String ETC_ORG_OPS4J_PAX_URL_MVN_CFG = "etc/org.ops4j.pax.url.mvn.cfg";
48     private static final String ETC_ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
49
50     private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
51     private static final String KARAF_DEBUG_PORT = "5005";
52     private static final String KARAF_DEBUG_PROP = "karaf.debug";
53     private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
54     private static final Logger LOG = LoggerFactory.getLogger(AbstractConfigTestBase.class);
55     public static final String ORG_OPS4J_PAX_LOGGING_CFG = "etc/org.ops4j.pax.logging.cfg";
56
57     /*
58      * Default values for karaf distro type, groupId, and artifactId
59      */
60     private static final String KARAF_DISTRO_TYPE = "zip";
61     private static final String KARAF_DISTRO_ARTIFACTID = "opendaylight-karaf-empty";
62     private static final String KARAF_DISTRO_GROUPID = "org.opendaylight.odlparent";
63
64     /*
65      * Property names to override defaults for karaf distro artifactId, groupId, version, and type
66      */
67     private static final String KARAF_DISTRO_VERSION_PROP = "karaf.distro.version";
68     private static final String KARAF_DISTRO_TYPE_PROP = "karaf.distro.type";
69     private static final String KARAF_DISTRO_ARTIFACTID_PROP = "karaf.distro.artifactId";
70     private static final String KARAF_DISTRO_GROUPID_PROP = "karaf.distro.groupId";
71
72     /**
73      * Property file used to store the Karaf distribution version
74      */
75     private static final String PROPERTIES_FILENAME = "abstractconfigtestbase.properties";
76
77     /*
78      * Wait up to 10s for our configured module to come up
79      */
80     private static final int MODULE_TIMEOUT_MILLIS = 60000;
81
82     /**
83      * This method need only be overridden if using the config system.
84      *
85      * @return the config module name
86      */
87     @Deprecated
88     public String getModuleName() {
89         return null;
90     }
91
92     /**
93      * This method need only be overridden if using the config system.
94      *
95      * @return the config module instance name
96      */
97     @Deprecated
98     public String getInstanceName() {
99         return null;
100     }
101
102     public abstract MavenUrlReference getFeatureRepo();
103
104     public abstract String getFeatureName();
105
106     public Option getLoggingOption() {
107         Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
108                         logConfiguration(AbstractConfigTestBase.class),
109                         LogLevel.INFO.name());
110         return option;
111     }
112
113     /**
114      * Override this method to provide more options to config
115      *
116      * @return An array of additional config options
117      */
118     protected Option[] getAdditionalOptions() {
119         return null;
120     }
121
122     public String logConfiguration(final Class<?> klazz) {
123         return "log4j.logger." + klazz.getPackage().getName();
124     }
125
126     public String getKarafDistro() {
127         String groupId = System.getProperty(KARAF_DISTRO_GROUPID_PROP,KARAF_DISTRO_GROUPID);
128         String artifactId = System.getProperty(KARAF_DISTRO_ARTIFACTID_PROP,KARAF_DISTRO_ARTIFACTID);
129         String version = System.getProperty(KARAF_DISTRO_VERSION_PROP);
130         String type = System.getProperty(KARAF_DISTRO_TYPE_PROP,KARAF_DISTRO_TYPE);
131         if (version == null) {
132             // We use a properties file to retrieve ${karaf.version}, instead of .versionAsInProject()
133             // This avoids forcing all users to depend on Karaf in their POMs
134             Properties abstractConfigTestBaseProps = new Properties();
135             try (InputStream abstractConfigTestBaseInputStream = Thread.currentThread().getContextClassLoader()
136                     .getResourceAsStream(PROPERTIES_FILENAME)) {
137                 abstractConfigTestBaseProps.load(abstractConfigTestBaseInputStream);
138             } catch (final IOException e) {
139                 LOG.error("Unable to load {} to determine the Karaf version", PROPERTIES_FILENAME, e);
140             }
141             version = abstractConfigTestBaseProps.getProperty(KARAF_DISTRO_VERSION_PROP);
142         }
143         MavenArtifactUrlReference karafUrl = maven()
144                 .groupId(groupId)
145                 .artifactId(artifactId)
146                 .version(version)
147                 .type(type);
148         return karafUrl.getURL();
149     }
150
151     protected Option mvnLocalRepoOption() {
152         String mvnRepoLocal = System.getProperty(MAVEN_REPO_LOCAL, "");
153         LOG.info("mvnLocalRepo \"{}\"", mvnRepoLocal);
154         return editConfigurationFilePut(ETC_ORG_OPS4J_PAX_URL_MVN_CFG, ORG_OPS4J_PAX_URL_MVN_LOCAL_REPOSITORY,
155                 mvnRepoLocal);
156     }
157
158     @Configuration
159     public Option[] config() {
160         Option[] options = new Option[] {
161                 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
162                         .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
163                 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
164                         .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
165                         .useDeployFolder(false),
166                 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
167                 features(getFeatureRepo(), getFeatureName()),
168                 mavenBundle("org.apache.aries.quiesce", "org.apache.aries.quiesce.api", "1.0.0"),
169                 getLoggingOption(),
170                 mvnLocalRepoOption(),
171                 editConfigurationFilePut(ETC_ORG_OPS4J_PAX_LOGGING_CFG, "log4j.rootLogger", "INFO, stdout, osgi:*")};
172         return OptionUtils.combine(options, getAdditionalOptions());
173     }
174
175     @Before
176     public void setup() throws Exception {
177         String moduleName = getModuleName();
178         String instanceName = getInstanceName();
179         if(moduleName == null || instanceName == null) {
180             return;
181         }
182
183         LOG.info("Module: {} Instance: {} attempting to configure.",
184                 moduleName, instanceName);
185         Stopwatch stopWatch = Stopwatch.createStarted();
186         ObjectName objectName = null;
187         for(int i = 0;i<MODULE_TIMEOUT_MILLIS;i++) {
188             try {
189                 ConfigRegistry configRegistryClient = new ConfigRegistryJMXClient(ManagementFactory
190                         .getPlatformMBeanServer());
191                 objectName = configRegistryClient.lookupConfigBean(moduleName, instanceName);
192                 LOG.info("Module: {} Instance: {} ObjectName: {}.",
193                         moduleName,instanceName,objectName);
194                 break;
195             } catch (final Exception e) {
196                 if(i<MODULE_TIMEOUT_MILLIS) {
197                     Thread.sleep(1);
198                     continue;
199                 } else {
200                     throw e;
201                 }
202             }
203         }
204         if(objectName != null) {
205             LOG.info("Module: {} Instance: {} configured after {} ms",
206                 moduleName,instanceName,
207                 stopWatch.elapsed(TimeUnit.MILLISECONDS));
208         } else {
209             throw new RuntimeException("NOT FOUND Module: " +moduleName + " Instance: " + instanceName +
210                     " configured after " + stopWatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
211         }
212     }
213
214     @Rule
215     public TestRule watcher = new TestWatcher() {
216
217         @Override
218         protected void starting(final Description description) {
219             LOG.info("TestWatcher: Starting test: {}", description.getDisplayName());
220         }
221
222         @Override
223         protected void finished(final Description description) {
224             LOG.info("TestWatcher: Finished test: {}", description.getDisplayName());
225         }
226
227         @Override
228         protected void succeeded(final Description description) {
229             LOG.info("TestWatcher: Test succeeded: {}", description.getDisplayName());
230         }
231
232         @Override
233         protected void failed(final Throwable ex, final Description description) {
234             LOG.info("TestWatcher: Test failed: {}", description.getDisplayName(), ex);
235         }
236
237         @Override
238         protected void skipped(final AssumptionViolatedException ex, final Description description) {
239             LOG.info("TestWatcher: Test skipped: {} ", description.getDisplayName(), ex);
240         }
241     };
242
243 }