co.cask.cdap.test.TestConfiguration Maven / Gradle / Ivy
/*
* Copyright © 2015 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package co.cask.cdap.test;
import com.google.common.base.Preconditions;
import org.junit.rules.ExternalResource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* This class can be used to setup CDAP configuration for unit-test.
*
* Usage:
*
*
{@code
* class MyUnitTest extends TestBase {
*
* @ClassRule
* public static final TestConfiguration CONFIG = new TestConfiguration("explore.enabled", "false");
*
* ....
* }
* }
*
*
*/
public class TestConfiguration extends ExternalResource {
public static final String PROPERTY_PREFIX = "cdap.unit.test.";
private final Map configs;
/**
* Creates a new instance with the give list of configurations.
*
* @param configs list of configuration pairs.
* The list must be in the form of {@code (key1, value1, key2, value2, ...)},
* hence the length of configs must be even.
* The {@link Object#toString()} method will be called to obtain the keys and values that go into
* the configuration.
*/
public TestConfiguration(Object... configs) {
Preconditions.checkArgument(configs.length % 2 == 0,
"Arguments must be in pair form like (k1, v1, k2, v2): %s", Arrays.toString(configs));
this.configs = new HashMap<>();
for (int i = 0; i < configs.length; i += 2) {
this.configs.put(PROPERTY_PREFIX + configs[i].toString(), configs[i + 1].toString());
}
}
/**
* Creates a new instance with the given configurations.
*
* @param configs a Map of configurations
*/
public TestConfiguration(Map configs) {
this.configs = new HashMap<>(configs);
}
@Override
protected void before() throws Throwable {
// Use the system properties map as a mean to communicate unit-test specific CDAP configurations to the
// TestBase class, which it will use to setup the CConfiguration.
// All keys set into the properties are prefixed with PROPERTY_PREFIX.
// It is done using @ClassRule instead of inheritance/method override is because TestBase starts
// CDAP services in a @BeforeClass method, which is a static method.
//
// In JUnit, @BeforeClass methods in super-class are called before the one in the sub-class.
// This means the sub-class cannot use @BeforeClass method to provide configurations before CDAP initialize.
//
// Since @BeforeClass method must be static, there is no way to guarantee that the sub-class implements
// a particular method such that TestBase can calls to get configurations before initializing CDAP.
// One can rely on naming convention and static method shadowing, however, that is an anti-pattern.
// Using @ClassRule gives a much cleaner solution.
for (Map.Entry entry : configs.entrySet()) {
System.setProperty(entry.getKey(), entry.getValue());
}
}
@Override
protected void after() {
for (String key : configs.keySet()) {
System.clearProperty(key);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy