/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.core.domain.configuration;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotSame;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import java.util.Set;
import org.testng.annotations.Test;
import org.rhq.core.util.MessageDigestGenerator;
/**
* This class has tests for Configuration just like org.rhq.core.domain.configuration.test.ConfigurationTest. These
* tests however are just plain, vanilla unit tests whereas the tests in org.rhq.core.domain.configuration.test.ConfigurationTest
* are slower, longer running integration tests; hence, the separation.
*/
public class ConfigurationTest {
@Test
public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenKeepingIds() {
Configuration original = createConfiguration();
Configuration copy = original.deepCopy(true);
assertNotSame(copy, original,
"Expected a reference to a new Configuration object, not the original object being copied");
}
@Test
public void deepCopyShouldNotReturnReferenceToOriginalObjectWhenNotKeepingIds() {
Configuration original = createConfiguration();
Configuration copy = original.deepCopy(false);
assertNotSame(copy, original,
"Expected a reference to a new Configuration object, not the original object being copied");
}
@Test
public void deepCopyShouldCopyAllSimpleFieldsWhenKeepingIds() {
Configuration original = createConfiguration();
Configuration copy = original.deepCopy(true);
assertEquals(copy.getId(), original.getId(), "Failed to copy the id property");
assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property");
assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property");
}
@Test
public void deepCopyShouldNotCopyIdWhenNotKeepingIds() {
Configuration original = createConfiguration();
Configuration copy = original.deepCopy(false);
assertFalse(copy.getId() == original.getId(), "The original id property should not be copied");
assertEquals(copy.getNotes(), original.getNotes(), "Failed to copy the notes property");
assertEquals(copy.getVersion(), original.getVersion(), "Failed to copy version property");
}
@Test
public void deepCopyShouldCopyPropertiesWhenKeepingIds() {
Configuration original = createConfiguration();
original.put(new PropertySimple("simpleProperty", "Simple Property"));
Configuration copy = original.deepCopy(true);
assertNotSame(copy.getProperties(), original.getProperties(),
"The properties property should not refer to the properties in the original object");
assertEquals(copy.getProperties(), original.getProperties(),
"Failed to copy the contents of the properties collection");
}
@Test
public void deepCopyShouldCopyPropertiesWhenNotKeepingIds() {
Configuration original = createConfiguration();
original.put(new PropertySimple("simpleProperty", "Simple Property"));
Configuration copy = original.deepCopy(false);
assertNotSame(copy.getProperties(), original.getProperties(),
"The properties property should not refer to the properties in the original object");
assertEquals(copy.getProperties(), original.getProperties(),
"Failed to copy the contents of the properties collection");
}
@Test
public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenKeepingIds() {
Configuration original = createConfiguration();
String propertyName = "simpleProperty";
original.put(new PropertySimple(propertyName, "Simple Property"));
Configuration copy = original.deepCopy(true);
assertNotSame(copy.get(propertyName), original.get(propertyName),
"Expected a refernce to a new property, not the original property being copied");
}
@Test
public void deepCopyShouldNotReturnCopyReferenceOfOriginalPropertyWhenNotKeepingIds() {
Configuration original = createConfiguration();
String propertyName = "simpleProperty";
original.put(new PropertySimple(propertyName, "Simple Property"));
Configuration copy = original.deepCopy(false);
assertNotSame(copy.get(propertyName), original.get(propertyName),
"Expected a refernce to a new property, not the original property being copied");
}
@Test
public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenKeepingIds() {
Configuration original = createConfiguration();
String propertyName = "simpleProperty";
original.put(new PropertySimple(propertyName, "Simple Property"));
Configuration copy = original.deepCopy(true);
assertSame(
copy.get(propertyName).getConfiguration(),
copy,
"The reference to the parent configuration should point to the newly copied configuration, not the original configuration");
}
@Test
public void deepCopyShouldSetParentReferenceOfCopiedPropertiesWhenNotKeepingIds() {
Configuration original = createConfiguration();
String propertyName = "simpleProperty";
original.put(new PropertySimple(propertyName, "Simple Property"));
Configuration copy = original.deepCopy(false);
assertSame(
copy.get(propertyName).getConfiguration(),
copy,
"The reference to the parent configuration should point to the newly copied configuration, not the original configuration");
}
@Test
public void deepCopyShouldCopyRawConfigurationsWhenKeepingIds() {
Configuration original = createConfiguration();
original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
Configuration copy = original.deepCopy(true);
assertNotSame(copy.getRawConfigurations(), original.getRawConfigurations(),
"The rawConfigurations property should not refer to the original rawConfigurations of the copied object.");
assertRawConfigurationsEquals(copy.getRawConfigurations(), original.getRawConfigurations(),
"Failed to copy rawConfigurations property.");
}
@Test
public void deepCopyShouldCopyRawConfigurationsWhenNotKeepingIds() {
Configuration original = createConfiguration();
original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
Configuration copy = original.deepCopy(false);
assertNotSame(copy.getRawConfigurations(), original.getRawConfigurations(),
"The rawConfigurations property should not refer to the original rawConfigurations of the copied object.");
assertRawConfigurationsEquals(copy.getRawConfigurations(), original.getRawConfigurations(),
"Failed to copy rawConfigurations property.");
}
void assertRawConfigurationsEquals(Set<RawConfiguration> actual, Set<RawConfiguration> expected, String msg) {
assertEquals(actual.size(), expected.size(), msg
+ " -- The rawConfigurations set has the wrong number of elements.");
for (RawConfiguration rawConfig : expected) {
assertTrue(actual.contains(rawConfig), msg + " -- Failed to find " + rawConfig);
}
}
@Test
public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenKeepingIds() {
Configuration original = createConfiguration();
original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
Configuration copy = original.deepCopy(true);
RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy);
assertSame(
copiedRawConfig.getConfiguration(),
copy,
"The reference to the parent configuration should point to the newly copied configuration, not the original configuration.");
}
@Test
public void deepCopyShouldSetParentReferenceOfCopiedRawConfigurationsWhenNotKeepingIds() {
Configuration original = createConfiguration();
original.addRawConfiguration(createRawConfiguration("/tmp/foo"));
Configuration copy = original.deepCopy(false);
RawConfiguration copiedRawConfig = getCopiedRawConfiguration(copy);
assertSame(
copiedRawConfig.getConfiguration(),
copy,
"The reference to the parent configuration should point to the newly copied configuration, not the original configuration.");
}
private RawConfiguration getCopiedRawConfiguration(Configuration config) {
for (RawConfiguration rawConfig : config.getRawConfigurations()) {
return rawConfig;
}
return null;
}
@Test
public void equalsShouldBeFalseWhenArgumentIsNull() {
Configuration config = new Configuration();
assertFalse(config.equals(null), "equals() should be false for null argument.");
}
@Test
public void equalsShouldBeFalseWhenArgumentIsNotAConfiguration() {
Configuration config = new Configuration();
assertFalse(config.equals(new Object()), "equals should return false when argument is not a "
+ Configuration.class.getSimpleName());
}
@Test
public void equalsShouldBeReflexive() {
Configuration config = new Configuration();
assertTrue(config.equals(config), "equals() should be reflexive.");
}
@Test
public void equalsAndHashCodeShouldBeSymmetricWhenBothConfigurationsAreEmpty() {
Configuration c1 = new Configuration();
Configuration c2 = new Configuration();
assertTrue(c1.equals(c2) && c2.equals(c1), "equals() should be true and symmetric when both configs are empty.");
assertEquals(c1.hashCode(), c2.hashCode(), "hashCodes should be the same when equals() returns true.");
}
@Test
public void equalsAndHashCodeShouldBeSymmetricWhenConfigsHaveEqualStructuredAndNoRaw() {
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
Configuration c2 = new Configuration();
c2.put(new PropertySimple("foo", "bar"));
assertTrue(c1.equals(c2) && c2.equals(c1),
"equals() should be true and symmetric when structured configs are equal and there are no raw configs.");
assertEquals(c1.hashCode(), c2.hashCode());
}
@Test
public void equalsAndHashCodeShouldBeSymmetricWhenConfigsHaveEqualRawAndNoStructured() {
RawConfiguration rawConfig = createRawConfiguration("/tmp/foo");
Configuration c1 = new Configuration();
c1.addRawConfiguration(rawConfig);
Configuration c2 = new Configuration();
c2.addRawConfiguration(createCopyOfRawConfiguration(rawConfig));
assertTrue(c1.equals(c2) && c2.equals(c1),
"equals() should be true and symmetric when raw configs are equal and there are no structured configs.");
assertEquals(c1.hashCode(), c2.hashCode());
}
@Test
public void equalsAndHashCodeShouldBeTransitiveWhenConfigurationsAreEmpty() {
Configuration c1 = new Configuration();
Configuration c2 = new Configuration();
Configuration c3 = new Configuration();
assertTrue(c1.equals(c2) && c2.equals(c3), "equals() should be true when configs are empty.");
assertTrue(c1.equals(c3), "equals should be transitive.");
assertEquals(c1.hashCode(), c3.hashCode(), "hashCodes should be the same when equals returns true.");
}
@Test
public void equalsAndHashCodeShouldBeTransitiveWhenConfigsHaveEqualStructuredAndNoRaw() {
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
Configuration c2 = new Configuration();
c2.put(new PropertySimple("foo", "bar"));
Configuration c3 = new Configuration();
c3.put(new PropertySimple("foo", "bar"));
assertTrue(c1.equals(c2) && c2.equals(c3),
"equals() should be true when structured configs are equal and there are no raw configs.");
assertTrue(c1.equals(c3), "equals should be transitive.");
assertEquals(c1.hashCode(), c3.hashCode(), "hashCodes should be the same when equals() returns true.");
}
@Test
public void equalsAndHashCodeShouldBeTransitiveWhenConfigsHaveEqualRawAndNoStructured() {
RawConfiguration rawConfig = createRawConfiguration("/tmp/foo");
Configuration c1 = new Configuration();
c1.addRawConfiguration(rawConfig);
Configuration c2 = new Configuration();
c2.addRawConfiguration(createCopyOfRawConfiguration(rawConfig));
Configuration c3 = new Configuration();
c3.addRawConfiguration(createCopyOfRawConfiguration(rawConfig));
assertTrue(c1.equals(c2) && c2.equals(c3),
"equals() should be true when raw configs are equal and there are no structured configs.");
assertTrue(c1.equals(c3), "equals should be transitive.");
assertEquals(c1.hashCode(), c3.hashCode(), "hashCodes should be the same when equals() returns true.");
}
@Test
public void equalsShouldBeFalseWhenOneConfigHasStructuredAndTheOtherDoesNot() {
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
Configuration c2 = new Configuration();
assertFalse(c1.equals(c2), "equals() should be false when one config has structured and the other does not");
}
@Test
public void equalsShouldBeFalseWhenBothHaveStructuredButNotRaw() {
RawConfiguration rawConfig = createRawConfiguration("/tmp/foo");
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
c1.addRawConfiguration(rawConfig);
Configuration c2 = new Configuration();
c2.put(new PropertySimple("foo", "bar"));
assertFalse(c1.equals(c2), "equals() should be false when one config has raw and the other does not.");
}
@Test
public void equalsShouldBeFalseWhenBothHaveRawButNotStructured() {
RawConfiguration r1 = createRawConfiguration("/tmp/foo");
Configuration c1 = new Configuration();
c1.addRawConfiguration(r1);
c1.put(new PropertySimple("foo", "bar"));
RawConfiguration r2 = createCopyOfRawConfiguration(r1);
Configuration c2 = new Configuration();
c2.addRawConfiguration(r2);
assertFalse(c1.equals(c2), "equals() should be false when one config has structured and the other does not.");
}
@Test
public void equalsShouldBeFalseWhenStructuredAreUnequalAndRawsAreEqual() {
RawConfiguration rawConfig = createRawConfiguration("/tmp/foo");
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
c1.addRawConfiguration(rawConfig);
Configuration c2 = new Configuration();
c2.put(new PropertySimple("bar", "foo"));
c2.addRawConfiguration(createCopyOfRawConfiguration(rawConfig));
assertFalse(c1.equals(c2), "equals() should be false when structured configs are not equal.");
}
@Test
public void equalsShouldBeFalseWhenStructuredAreEqualAndRawAreUnequal() {
Configuration c1 = new Configuration();
c1.put(new PropertySimple("foo", "bar"));
c1.addRawConfiguration(createRawConfiguration("/tmp/foo"));
Configuration c2 = new Configuration();
c2.put(new PropertySimple("foo", "bar"));
c2.addRawConfiguration(createRawConfiguration("/tmp/bar"));
assertFalse(c1.equals(c2), "equals() should be false when raw configs are not equal.");
}
@Test
public void configurationCanBeUpdatedUsingTheCollectionObtainedFromGetProperties() {
Configuration configuration = new Configuration();
Collection<Property> props = configuration.getProperties();
PropertySimple prop = new PropertySimple("a", "a");
props.add(prop);
assertEquals(configuration.getAllProperties().size(), 1, "The configuration's properties should have been updated using the proxy.");
assertEquals(configuration.get("a"), prop, "Proxy should transparently update the property map.");
}
@Test
public void setPropertiesCanAcceptPropertiesProxyObtainedFromGetProperties() {
Configuration configuration = new Configuration();
Collection<Property> props = new ArrayList<Property>();
PropertySimple prop = new PropertySimple("a", "a");
props.add(prop);
//set the properties using a "normal" collection
configuration.setProperties(props);
assertEquals(configuration.getAllProperties().size(), 1, "The configuration's properties should have been updated.");
assertEquals(configuration.get("a"), prop, "Setting the properties using a collection should transparently update the property map.");
//now get the proxy object from the configuration
props = configuration.getProperties();
//and try to assign it back... as simple as it seems, special care must be taken, which we are testing for here
configuration.setProperties(props);
assertEquals(configuration.getAllProperties().size(), 1, "Setting the proxy as the set of properties should not modify the properties");
assertEquals(configuration.get("a"), prop, "The property map should be untouched when setting the properties using the previously obtained proxy");
}
private Configuration createConfiguration() {
Configuration config = new Configuration();
config.setId(1);
config.setNotes("notes");
config.setVersion(1L);
// make sure properties property is initialized
config.getMap();
return config;
}
private RawConfiguration createRawConfiguration(String path) {
byte[] bytes = new byte[10];
Random random = new Random();
random.nextBytes(bytes);
RawConfiguration rawConfig = new RawConfiguration();
rawConfig.setPath(path);
String contents = new String(bytes);
String sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(contents);
rawConfig.setContents(contents, sha256);
return rawConfig;
}
private RawConfiguration createCopyOfRawConfiguration(RawConfiguration rawConfig) {
RawConfiguration copy = new RawConfiguration();
copy.setPath(rawConfig.getPath());
String contents = rawConfig.getContents();
String sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(contents);
copy.setContents(contents, sha256);
copy.setConfiguration(rawConfig.getConfiguration());
return copy;
}
}