/* * Copyright 2013 Rackspace * * 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 com.rackspacecloud.blueflood.service; import org.junit.*; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; public class ConfigurationTest { @Before public void setup() throws IOException { Configuration.getInstance().init(); } @After public void tearDown() throws IOException { // this resets the configuration after each test method invocation Configuration.getInstance().init(); } @Test public void testConfiguration() { try { Configuration config = Configuration.getInstance(); Map<Object, Object> properties = config.getProperties(); Assert.assertNotNull(properties); Assert.assertEquals("127.0.0.1:19180", config.getStringProperty(CoreConfig.CASSANDRA_HOSTS)); System.setProperty("CASSANDRA_HOSTS", "127.0.0.2"); Assert.assertEquals("127.0.0.2", config.getStringProperty(CoreConfig.CASSANDRA_HOSTS)); Assert.assertEquals(60000, config.getIntegerProperty(CoreConfig.SCHEDULE_POLL_PERIOD)); } finally { System.clearProperty("CASSANDRA_HOSTS"); } } @Test public void testInitWithBluefloodConfig() throws IOException { try { Configuration config = Configuration.getInstance(); Assert.assertNull(config.getStringProperty("TEST_PROPERTY")); Assert.assertEquals("ALL", config.getStringProperty(CoreConfig.SHARDS)); String configPath = new File("src/test/resources/bf-override-config.properties").getAbsolutePath(); System.setProperty("blueflood.config", "file://" + configPath); config.init(); Assert.assertEquals("foo", config.getStringProperty("TEST_PROPERTY")); Assert.assertEquals("NONE", config.getStringProperty(CoreConfig.SHARDS)); } finally { System.clearProperty("blueflood.config"); } } // list of strings @Test public void testMultipleCommaSeparatedItemsShouldYieldTheSameNumberOfElements() { String[] expected = { "a", "b", "c" }; List<String> actual = Configuration.stringListFromString("a,b,c"); Assert.assertArrayEquals(expected, actual.toArray()); } @Test public void testWhitespaceBetweenElementsIsNotSignificant() { String[] expected = { "a", "b", "c" }; List<String> actual = Configuration.stringListFromString("a, b,c"); Assert.assertArrayEquals(expected, actual.toArray()); } @Test public void testLeadingWhitespaceIsKept() { String[] expected = { " a", "b", "c" }; List<String> actual = Configuration.stringListFromString(" a,b,c"); Assert.assertArrayEquals(expected, actual.toArray()); } @Test public void testTrailingWhitespaceIsKept() { String[] expected = { "a", "b", "c " }; List<String> actual = Configuration.stringListFromString("a,b,c "); Assert.assertArrayEquals(expected, actual.toArray()); } @Test public void testConsecutiveCommasDontProduceEmptyElements() { String[] expected = { "a", "b", "c" }; List<String> actual = Configuration.stringListFromString("a,,,b,c"); Assert.assertArrayEquals(expected, actual.toArray()); } // boolean values @Test public void testNullShouldBeInterpretedAsBooleanFalse() { Assert.assertFalse(Configuration.booleanFromString(null)); } @Test public void test_TRUE_ShouldBeInterpretedAsBooleanTrue() { Assert.assertTrue(Configuration.booleanFromString("TRUE")); } // integer values @Test public void testIntegerOneShouldBeInterpretedAsOne() { Assert.assertEquals(1, Configuration.intFromString("1")); } @Test(expected=NumberFormatException.class) public void testIntegerLeadingWhitespaceShouldBeIgnored() { int value = Configuration.intFromString(" 1"); } @Test(expected=NumberFormatException.class) public void testIntegerTrailingWhitespaceShouldBeIgnored() { int value = Configuration.intFromString("1 "); } // long values @Test public void testLongOneShouldBeInterpretedAsOne() { Assert.assertEquals(1L, Configuration.longFromString("1")); } @Test(expected=NumberFormatException.class) public void testLongLeadingWhitespaceShouldBeRejected() { long value = Configuration.longFromString(" 1"); } @Test(expected=NumberFormatException.class) public void testLongTrailingWhitespaceShouldBeRejected() { long value = Configuration.longFromString("1 "); } // float values @Test public void testFloatOneShouldBeInterpretedAsOne() { Assert.assertEquals(1.0f, Configuration.floatFromString("1"), 0.00001f); } @Test public void testFloatExtendedFormat() { Assert.assertEquals(-1100.0f, Configuration.floatFromString("-1.1e3"), 0.00001f); } @Test(expected=NumberFormatException.class) public void testFloatExtendedFormatSpaceBeforeDotIsInvalid() { Assert.assertEquals(-1100.0f, Configuration.floatFromString("-1 .1e3"), 0.00001f); } @Test(expected=NumberFormatException.class) public void testFloatExtendedFormatSpaceAfterDotIsInvalid() { Assert.assertEquals(-1100.0f, Configuration.floatFromString("-1. 1e3"), 0.00001f); } @Test(expected=NumberFormatException.class) public void testFloatExtendedFormatSpaceBeforeExponentMarkerIsInvalid() { Assert.assertEquals(-1100.0f, Configuration.floatFromString("-1.1 e3"), 0.00001f); } @Test(expected=NumberFormatException.class) public void testFloatExtendedFormatSpaceAfterExponentMarkerIsInvalid() { Assert.assertEquals(-1100.0f, Configuration.floatFromString("-1.1e 3"), 0.00001f); } @Test public void testFloatLeadingWhitespaceShouldBeIgnored() { Assert.assertEquals(1.0f, Configuration.floatFromString(" 1"), 0.00001f); } @Test public void testFloatTrailingWhitespaceShouldBeIgnored() { Assert.assertEquals(1.0f, Configuration.floatFromString("1 "), 0.00001f); } // override behavior @Test public void testSystemPropertiesOverrideConfigurationValues() { final String keyName = CoreConfig.MAX_CASSANDRA_CONNECTIONS.toString(); Configuration config = Configuration.getInstance(); try { Assert.assertEquals("75", config.getStringProperty(CoreConfig.MAX_CASSANDRA_CONNECTIONS)); System.setProperty(keyName, "something else"); Assert.assertEquals("something else", config.getStringProperty(CoreConfig.MAX_CASSANDRA_CONNECTIONS)); } finally { System.clearProperty(keyName); config.clearProperty(keyName); } } // originals, a.k.a. backup keys @Test public void testGettingValuesCreatesOriginals() { final String keyName = CoreConfig.ROLLUP_KEYSPACE.toString(); // The behavior of getStringProperty() when it creates new 'original.*' // entries is very convoluted. It requires: // 1. A system property named $NAME exists // 2. A property named "original.$NAME" does NOT exist in the props object // 3. A property named $NAME does exist in the props object // Hence the calls to System.setProperty and config.setProperty below // with different values. That way, we create the 'original.*' entry // from the intended source and can test it. try { // arrange Configuration config = Configuration.getInstance(); Map<Object, Object> props = config.getAllProperties(); // preconditions Assert.assertTrue( "props should already have 'ROLLUP_KEYSPACE', because that's a default", props.containsKey(keyName)); Assert.assertFalse( "props should not contain 'original.ROLLUP_KEYSPACE' yet", props.containsKey("original." + keyName)); // act System.setProperty(keyName, "some value"); config.setProperty(keyName, "some other value"); String value = config.getStringProperty(CoreConfig.ROLLUP_KEYSPACE); Assert.assertEquals("some value", value); // assert Map<Object, Object> props2 = config.getAllProperties(); Assert.assertTrue( "props2 should already have 'ROLLUP_KEYSPACE', because that's a default", props2.containsKey(keyName)); Assert.assertTrue( "props2 should now contain 'original.ROLLUP_KEYSPACE'", props2.containsKey("original." + keyName)); Assert.assertEquals("some value", config.getStringProperty(CoreConfig.ROLLUP_KEYSPACE)); Assert.assertEquals("some other value", config.getStringProperty("original." + keyName)); } finally { System.clearProperty(keyName); } } @Test public void testWhenNoSyspropExistsAndTheKeyIsntPresentInConfigAndTheBackupKeyIsntPresentThenReturnValueShouldBeNullAndNoBackupCreated() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act String value = config.getStringProperty(keyName); // assert // return value is null Assert.assertNull(value); // the key is not present Assert.assertFalse(config.containsKey(keyName)); // the backup key is not present Assert.assertFalse(config.containsKey(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenNoSyspropExistsAndTheKeyIsPresentInConfigAndTheBackupKeyIsntPresentThenReturnValueShouldBeThePreviouslySetValueAndNoBackupCreated() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act config.setProperty(keyName, "some value"); String value = config.getStringProperty(keyName); // assert // return value is previously-set value Assert.assertEquals("some value", value); // key is present and its value is equal to what we set it to Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); //backup key is not present Assert.assertFalse(config.containsKey(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropExistsAndTheKeyIsntPresentInConfigAndTheBackupKeyIsntPresentThenReturnValueShouldBeSyspropValueAndNoBackupCreated() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); String value = config.getStringProperty(keyName); // assert // return value is system property value Assert.assertEquals("some value", value); // the key has been added and its value is that of the sysprop Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); // the backup key has not been added Assert.assertFalse(config.containsKey(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropExistsAndTheKeyIsPresentInConfigAndTheBackupKeyIsntPresentThenReturnValueShouldBeSyspropValueAndNoBackupCreated() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); config.setProperty(keyName, "some other value"); String value = config.getStringProperty(keyName); // assert // return value is the sysprop Assert.assertEquals("some value", value); // the key is present and its value has been changed to that of the sysprop Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); // the backup key has been added and its value is the previously-set value of the (non-backup) key Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testAfterAnOriginalIsCreatedSystemPropertyNoLongerOverrides() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); // A config.setProperty(keyName, "some other value"); // B String value = config.getStringProperty(keyName); // assert Assert.assertEquals("some value", value); // equal to the sysprop A Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName2)); // act System.setProperty(keyName, "another value"); // C config.setProperty(keyName, "another another value"); // D String value2 = config.getStringProperty(keyName); // assert Assert.assertEquals("another another value", value2); // _not_ equal to the sysprop C Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("another another value", config.getRawStringProperty(keyName)); Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testAfterAnOriginalIsCreatedItIsNeverUpdated() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); // A config.setProperty(keyName, "some other value"); // B String value = config.getStringProperty(keyName); // assert Assert.assertEquals("some value", value); Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName2)); // equal to config value B // act System.setProperty(keyName, "another value"); // C config.setProperty(keyName, "another another value"); // D String value2 = config.getStringProperty(keyName); // assert Assert.assertEquals("another another value", value2); Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("another another value", config.getRawStringProperty(keyName)); Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName2)); // _still_ equal to config value B } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropDoesntExistAndTheKeyIsntPresentInConfigAndTheBackupKeyIsPresentThenReturnValueShouldBeNullAndBackupRemainsAsIs() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act config.setProperty(keyName2, "more value"); String value = config.getStringProperty(keyName); // assert // return value is null Assert.assertNull(value); // the key is not added Assert.assertFalse(config.containsKey(keyName)); // the backup key is still present and has the same value Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("more value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropDoesntExistAndTheKeyIsPresentInConfigAndTheBackupKeyIsPresentThenReturnValueShouldBeKeysValueAndBackupRemainsAsIs() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act config.setProperty(keyName, "some value"); config.setProperty(keyName2, "more value"); String value = config.getStringProperty(keyName); // assert // return value is previously-set value Assert.assertEquals("some value", value); // key is present and its value is equal to what we set it to Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some value", config.getRawStringProperty(keyName)); // the backup key is still present and has the same value Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("more value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropExistsAndTheKeyIsntPresentInConfigAndTheBackupKeyIsPresentThenReturnValueShouldBeNullAndBackupRemainsAsIs() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); config.setProperty(keyName2, "more value"); String value = config.getStringProperty(keyName); // assert // return value is null (not sysprop as we might expect) Assert.assertNull(value); // key is not present Assert.assertFalse(config.containsKey(keyName)); // the backup key is still present and has the same value Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("more value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } @Test public void testWhenSyspropExistsAndTheKeyIsPresentInConfigAndTheBackupKeyIsPresentThenReturnValueShouldBeKeysValueAndBackupRemainsAsIs() { // arrange final String keyName = "some-key-name"; final String keyName2 = "original." + keyName; Configuration config = Configuration.getInstance(); try { // precondition Assert.assertFalse(config.containsKey(keyName)); Assert.assertFalse(config.containsKey(keyName2)); // act System.setProperty(keyName, "some value"); config.setProperty(keyName, "some other value"); config.setProperty(keyName2, "more value"); String value = config.getStringProperty(keyName); // assert // return value is null (not sysprop as we might expect) Assert.assertEquals("some other value", value); // key is present and its value is equal to what we set it to Assert.assertTrue(config.containsKey(keyName)); Assert.assertEquals("some other value", config.getRawStringProperty(keyName)); // the backup key is still present and has the same value Assert.assertTrue(config.containsKey(keyName2)); Assert.assertEquals("more value", config.getRawStringProperty(keyName2)); } finally { config.clearProperty(keyName); config.clearProperty(keyName2); System.clearProperty(keyName); } } // getProperties @Test public void testGetPropertiesDoesntWorkForDefaults() { Configuration config = Configuration.getInstance(); Assert.assertEquals( "19180", config.getStringProperty(CoreConfig.DEFAULT_CASSANDRA_PORT)); Map props = config.getProperties(); Assert.assertFalse(props.containsKey(CoreConfig.DEFAULT_CASSANDRA_PORT.toString())); } @Test public void testGetPropertiesWorksForNonDefaults() { final String keyName = "abcdef"; // arrange Configuration config = Configuration.getInstance(); // preconditions Map props = config.getProperties(); Assert.assertFalse(props.containsKey(keyName)); // act config.setProperty(keyName, "123456"); // assert Map props2 = config.getProperties(); Assert.assertTrue(props2.containsKey(keyName)); } }