From 794cb43ee4bf8f480f220d82b2032713d2764f7b Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 16 Jul 2007 17:17:20 +0000
Subject: [PATCH] Add a new test suite for testing server-side admin framework: this suite tests that default values are decoded properly and that components are correctly notified when changes to property values occur. Also included in this change is a fix for a bug found during testing where inherited default values were not correctly decoded during add/change notification.
---
opends/src/server/org/opends/server/admin/server/ServerManagedObject.java | 155 +++++---
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java | 858 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 952 insertions(+), 61 deletions(-)
diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index 49be1e0..b2792fe 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -109,7 +109,7 @@
* The type of the property.
*/
private static class DefaultValueFinder<T> implements
- DefaultBehaviorProviderVisitor<T, Collection<T>, ManagedObjectPath> {
+ DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
/**
* Get the default values for the specified property.
@@ -120,40 +120,40 @@
* The managed object path of the current managed object.
* @param pd
* The property definition.
+ * @param newConfigEntry
+ * Optional new configuration entry which does not yet
+ * exist in the configuration back-end.
* @return Returns the default values for the specified property.
* @throws DefaultBehaviorException
* If the default values could not be retrieved or
* decoded properly.
*/
public static <T> Collection<T> getDefaultValues(ManagedObjectPath p,
- PropertyDefinition<T> pd) throws DefaultBehaviorException {
- DefaultValueFinder<T> v = new DefaultValueFinder<T>(pd);
- Collection<T> values = pd.getDefaultBehaviorProvider().accept(v, p);
-
- if (v.exception != null) {
- throw v.exception;
- }
-
- if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
- throw new DefaultBehaviorException(pd,
- new PropertyIsSingleValuedException(pd));
- }
-
- return values;
+ PropertyDefinition<T> pd, ConfigEntry newConfigEntry)
+ throws DefaultBehaviorException {
+ DefaultValueFinder<T> v = new DefaultValueFinder<T>(newConfigEntry);
+ return v.find(p, pd);
}
// Any exception that occurred whilst retrieving inherited default
// values.
private DefaultBehaviorException exception = null;
- // The property definition whose default values are required.
- private final PropertyDefinition<T> pd;
+ // The path of the managed object containing the next property.
+ private ManagedObjectPath nextPath = null;
+
+ // The next property whose default values were required.
+ private PropertyDefinition<T> nextProperty = null;
+
+ // Optional new configuration entry which does not yet exist in
+ // the configuration back-end.
+ private ConfigEntry newConfigEntry;
// Private constructor.
- private DefaultValueFinder(PropertyDefinition<T> pd) {
- this.pd = pd;
+ private DefaultValueFinder(ConfigEntry newConfigEntry) {
+ this.newConfigEntry = newConfigEntry;
}
@@ -162,14 +162,14 @@
* {@inheritDoc}
*/
public Collection<T> visitAbsoluteInherited(
- AbsoluteInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
+ AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
try {
return getInheritedProperty(d.getManagedObjectPath(), d
.getManagedObjectDefinition(), d.getPropertyName());
} catch (DefaultBehaviorException e) {
- exception = new DefaultBehaviorException(pd, e);
+ exception = e;
+ return Collections.emptySet();
}
- return Collections.emptySet();
}
@@ -177,8 +177,7 @@
/**
* {@inheritDoc}
*/
- public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
return Collections.emptySet();
}
@@ -188,15 +187,15 @@
* {@inheritDoc}
*/
public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ Void p) {
Collection<String> stringValues = d.getDefaultValues();
List<T> values = new ArrayList<T>(stringValues.size());
for (String stringValue : stringValues) {
try {
- values.add(pd.decodeValue(stringValue));
+ values.add(nextProperty.decodeValue(stringValue));
} catch (IllegalPropertyValueStringException e) {
- exception = new DefaultBehaviorException(pd, e);
+ exception = new DefaultBehaviorException(nextProperty, e);
break;
}
}
@@ -210,14 +209,14 @@
* {@inheritDoc}
*/
public Collection<T> visitRelativeInherited(
- RelativeInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
+ RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
try {
- return getInheritedProperty(d.getManagedObjectPath(p), d
+ return getInheritedProperty(d.getManagedObjectPath(nextPath), d
.getManagedObjectDefinition(), d.getPropertyName());
} catch (DefaultBehaviorException e) {
- exception = new DefaultBehaviorException(pd, e);
+ exception = e;
+ return Collections.emptySet();
}
- return Collections.emptySet();
}
@@ -226,72 +225,104 @@
* {@inheritDoc}
*/
public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ Void p) {
return Collections.emptySet();
}
+ // Find the default values for the next path/property.
+ private Collection<T> find(ManagedObjectPath p, PropertyDefinition<T> pd)
+ throws DefaultBehaviorException {
+ nextPath = p;
+ nextProperty = pd;
+
+ Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(
+ this, null);
+
+ if (exception != null) {
+ throw exception;
+ }
+
+ if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+ throw new DefaultBehaviorException(pd,
+ new PropertyIsSingleValuedException(pd));
+ }
+
+ return values;
+ }
+
+
+
// Get an inherited property value.
+ @SuppressWarnings("unchecked")
private Collection<T> getInheritedProperty(ManagedObjectPath target,
AbstractManagedObjectDefinition<?, ?> d, String propertyName)
throws DefaultBehaviorException {
- try {
- // First check that the requested type of managed object
- // corresponds to the path.
- AbstractManagedObjectDefinition<?, ?> supr = target
- .getManagedObjectDefinition();
- if (!supr.isParentOf(d)) {
- throw new DefinitionDecodingException(Reason.WRONG_TYPE_INFORMATION);
- }
+ // First check that the requested type of managed object
+ // corresponds to the path.
+ AbstractManagedObjectDefinition<?, ?> supr = target
+ .getManagedObjectDefinition();
+ if (!supr.isParentOf(d)) {
+ throw new DefaultBehaviorException(nextProperty,
+ new DefinitionDecodingException(Reason.WRONG_TYPE_INFORMATION));
+ }
+ // Save the current property in case of recursion.
+ PropertyDefinition<T> pd1 = nextProperty;
+
+ try {
// Get the actual managed object definition.
DN dn = DNBuilder.create(target);
- ConfigEntry configEntry = getManagedObjectConfigEntry(dn);
+ ConfigEntry configEntry;
+ if (newConfigEntry != null && newConfigEntry.getDN().equals(dn)) {
+ configEntry = newConfigEntry;
+ } else {
+ configEntry = getManagedObjectConfigEntry(dn);
+ }
+
DefinitionResolver resolver = new MyDefinitionResolver(configEntry);
ManagedObjectDefinition<?, ?> mod = d
.resolveManagedObjectDefinition(resolver);
- PropertyDefinition<?> pd2;
+ PropertyDefinition<T> pd2;
try {
- pd2 = mod.getPropertyDefinition(propertyName);
+ PropertyDefinition<?> pdTmp = mod.getPropertyDefinition(propertyName);
+ pd2 = pd1.getClass().cast(pdTmp);
} catch (IllegalArgumentException e) {
throw new PropertyNotFoundException(propertyName);
+ } catch (ClassCastException e) {
+ // FIXME: would be nice to throw a better exception here.
+ throw new PropertyNotFoundException(propertyName);
}
List<String> stringValues = getAttribute(mod, pd2, configEntry);
if (stringValues.isEmpty()) {
// Recursively retrieve this property's default values.
- Collection<?> tmp = getDefaultValues(target, pd2);
+ Collection<T> tmp = find(target, pd2);
Collection<T> values = new ArrayList<T>(tmp.size());
- for (Object o : tmp) {
- T value;
- try {
- value = pd.castValue(o);
- } catch (ClassCastException e) {
- throw new IllegalPropertyValueException(pd, o);
- }
- pd.validateValue(value);
+ for (T value : tmp) {
+ pd1.validateValue(value);
values.add(value);
}
return values;
} else {
Collection<T> values = new ArrayList<T>(stringValues.size());
for (String s : stringValues) {
- values.add(pd.decodeValue(s));
+ values.add(pd1.decodeValue(s));
}
return values;
}
} catch (DefinitionDecodingException e) {
- throw new DefaultBehaviorException(pd, e);
+ throw new DefaultBehaviorException(pd1, e);
} catch (PropertyNotFoundException e) {
- throw new DefaultBehaviorException(pd, e);
+ throw new DefaultBehaviorException(pd1, e);
} catch (IllegalPropertyValueException e) {
- throw new DefaultBehaviorException(pd, e);
+ throw new DefaultBehaviorException(pd1, e);
} catch (IllegalPropertyValueStringException e) {
- throw new DefaultBehaviorException(pd, e);
+ throw new DefaultBehaviorException(pd1, e);
} catch (ConfigException e) {
- throw new DefaultBehaviorException(pd, e);
+ throw new DefaultBehaviorException(pd1, e);
}
}
}
@@ -379,7 +410,7 @@
for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
List<String> values = getAttribute(mod, pd, configEntry);
try {
- decodeProperty(properties, path, pd, values);
+ decodeProperty(properties, path, pd, values, configEntry);
} catch (PropertyException e) {
exceptions.add(e);
}
@@ -423,7 +454,8 @@
private static <T> void decodeProperty(
Map<PropertyDefinition<?>, SortedSet<?>> properties,
ManagedObjectPath path, PropertyDefinition<T> pd,
- List<String> stringValues) throws PropertyException {
+ List<String> stringValues, ConfigEntry newConfigEntry)
+ throws PropertyException {
PropertyException exception = null;
SortedSet<T> values = new TreeSet<T>(pd);
@@ -439,7 +471,8 @@
} else {
// No values defined so get the defaults.
try {
- values.addAll(DefaultValueFinder.getDefaultValues(path, pd));
+ values.addAll(DefaultValueFinder.getDefaultValues(path, pd,
+ newConfigEntry));
} catch (DefaultBehaviorException e) {
exception = e;
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java
new file mode 100644
index 0000000..5d850e4
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/server/DefaultBehaviorTest.java
@@ -0,0 +1,858 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.admin.server;
+
+
+
+import java.util.List;
+import java.util.SortedSet;
+
+import javax.naming.ldap.LdapName;
+
+import org.opends.server.TestCaseUtils;
+import org.opends.server.admin.AdminTestCase;
+import org.opends.server.admin.LDAPProfile;
+import org.opends.server.admin.MockLDAPProfile;
+import org.opends.server.admin.TestCfg;
+import org.opends.server.admin.TestChildCfg;
+import org.opends.server.admin.TestParentCfg;
+import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.std.server.RootCfg;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.ConfigChangeResult;
+import org.opends.server.types.DN;
+import org.opends.server.types.ResultCode;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+
+/**
+ * Test cases for default behavior on the server-side.
+ */
+public final class DefaultBehaviorTest extends AdminTestCase {
+
+ /**
+ * A test child add listener.
+ */
+ private static class AddListener implements
+ ConfigurationAddListener<TestChildCfg> {
+
+ // The child configuration that was added.
+ private TestChildCfg child;
+
+
+
+ /**
+ * Creates a new add listener.
+ */
+ public AddListener() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationAdd(TestChildCfg configuration) {
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+
+
+
+ /**
+ * Gets the child configuration checking that it has the expected
+ * name.
+ *
+ * @param expectedName
+ * The child's expected name.
+ * @return Returns the child configuration.
+ */
+ public TestChildCfg getChild(String expectedName) {
+ Assert.assertNotNull(child);
+ Assert.assertEquals(child.dn().getRDN().getAttributeValue(0)
+ .getStringValue(), expectedName);
+ return child;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAddAcceptable(TestChildCfg configuration,
+ List<String> unacceptableReasons) {
+ child = configuration;
+ return true;
+ }
+
+ }
+
+
+
+ /**
+ * A test child change listener.
+ */
+ private static class ChangeListener implements
+ ConfigurationChangeListener<TestChildCfg> {
+
+ // The child configuration that was changed.
+ private TestChildCfg child;
+
+
+
+ /**
+ * Creates a new change listener.
+ */
+ public ChangeListener() {
+ // No implementation required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ TestChildCfg configuration) {
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+
+
+
+ /**
+ * Gets the child configuration checking that it has the expected
+ * name.
+ *
+ * @param expectedName
+ * The child's expected name.
+ * @return Returns the child configuration.
+ */
+ public TestChildCfg getChild(String expectedName) {
+ Assert.assertNotNull(child);
+ Assert.assertEquals(child.dn().getRDN().getAttributeValue(0)
+ .getStringValue(), expectedName);
+ return child;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(TestChildCfg configuration,
+ List<String> unacceptableReasons) {
+ child = configuration;
+ return true;
+ }
+
+ }
+
+ // Test child 1 LDIF.
+ private static final String[] TEST_CHILD_1 = new String[] {
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test child 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real"
+ };
+
+ // Test child 2 LDIF.
+ private static final String[] TEST_CHILD_2 = new String[] {
+ "dn: cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test child 2",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value c2v1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value c2v2,dc=com"
+ };
+
+ // Test child 3 LDIF.
+ private static final String[] TEST_CHILD_3 = new String[] {
+ "dn: cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test child 3",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value c3v1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value c3v2,dc=com",
+ "ds-cfg-virtual-attribute-group-dn: dc=default value c3v3,dc=com",
+ "ds-cfg-virtual-attribute-group-dn: dc=default value c3v4,dc=com"
+ };
+
+ // Test child 4 LDIF.
+ private static final String[] TEST_CHILD_4 = new String[] {
+ "dn: cn=test child 4,cn=test children,cn=test parent 2,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test child 4",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real"
+ };
+
+ // Test LDIF.
+ private static final String[] TEST_LDIF = new String[] {
+ // Base entries.
+ "dn: cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test parents",
+ "",
+ // Parent 1 - uses default values for
+ // optional-multi-valued-dn-property.
+ "dn: cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test parent 1",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "",
+ // Parent 2 - overrides default values for
+ // optional-multi-valued-dn-property.
+ "dn: cn=test parent 2,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-virtual-attribute",
+ "cn: test parent 2",
+ "ds-cfg-virtual-attribute-enabled: true",
+ "ds-cfg-virtual-attribute-class: org.opends.server.extensions.UserDefinedVirtualAttributeProvider",
+ "ds-cfg-virtual-attribute-type: description",
+ "ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value p2v1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=default value p2v2,dc=com",
+ "",
+ // Child base entries.
+ "dn:cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test children",
+ "",
+ "dn:cn=test children,cn=test parent 2,cn=test parents,cn=config",
+ "objectclass: top",
+ "objectclass: ds-cfg-branch",
+ "cn: test children",
+ ""
+ };
+
+ // JNDI LDAP context.
+ private JNDIDirContextAdaptor adaptor = null;
+
+
+
+ /**
+ * Sets up tests
+ *
+ * @throws Exception
+ * If the server could not be initialized.
+ */
+ @BeforeClass
+ public void setUp() throws Exception {
+ // This test suite depends on having the schema available, so
+ // we'll start the server.
+ TestCaseUtils.startServer();
+ LDAPProfile.getInstance().pushWrapper(new MockLDAPProfile());
+
+ // Add test managed objects.
+ TestCaseUtils.addEntries(TEST_LDIF);
+ }
+
+
+
+ /**
+ * Tears down test environment.
+ *
+ * @throws Exception
+ * If the test entries could not be removed.
+ */
+ @AfterClass
+ public void tearDown() throws Exception {
+ LDAPProfile.getInstance().popWrapper();
+
+ // Remove test entries.
+ deleteSubtree("cn=test parents,cn=config");
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through an
+ * add listener.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAddListenerChildValues1() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+ AddListener listener = new AddListener();
+ parent.addTestChildAddListener(listener);
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+ try {
+ assertChild1(listener.getChild("test child 1"));
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ } finally {
+ parent.removeTestChildAddListener(listener);
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through an
+ * add listener.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAddListenerChildValues2() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+ AddListener listener = new AddListener();
+ parent.addTestChildAddListener(listener);
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_2);
+ try {
+ assertChild2(listener.getChild("test child 2"));
+ } finally {
+ deleteSubtree("cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ } finally {
+ parent.removeTestChildAddListener(listener);
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through an
+ * add listener.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAddListenerChildValues3() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+ AddListener listener = new AddListener();
+ parent.addTestChildAddListener(listener);
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_3);
+ try {
+ assertChild3(listener.getChild("test child 3"));
+ } finally {
+ deleteSubtree("cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ } finally {
+ parent.removeTestChildAddListener(listener);
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through an
+ * add listener.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testAddListenerChildValues4() throws Exception {
+ TestParentCfg parent = getParent("test parent 2");
+ AddListener listener = new AddListener();
+ parent.addTestChildAddListener(listener);
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_4);
+ try {
+ assertChild4(listener.getChild("test child 4"));
+ } finally {
+ deleteSubtree("cn=test child 4,cn=test children,cn=test parent 2,cn=test parents,cn=config");
+ }
+ } finally {
+ parent.removeTestChildAddListener(listener);
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through a
+ * change listener. This test replaces the defaulted properties with
+ * real values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChangeListenerChildValues1() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+ TestChildCfg child = parent.getTestChild("test child 1");
+ ChangeListener listener = new ChangeListener();
+ child.addChangeListener(listener);
+
+ // Now modify it.
+ String[] changes = new String[] {
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "changetype: modify",
+ "replace: ds-cfg-virtual-attribute-base-dn",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 2,dc=com",
+ "-",
+ "replace: ds-cfg-virtual-attribute-group-dn",
+ "ds-cfg-virtual-attribute-group-dn: dc=new value 3,dc=com",
+ "ds-cfg-virtual-attribute-group-dn: dc=new value 4,dc=com"
+ };
+ TestCaseUtils.applyModifications(changes);
+
+ // Make sure that the change listener was notified and the
+ // modified child contains the correct values.
+ child = listener.getChild("test child 1");
+
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=new value 3,dc=com", "dc=new value 4,dc=com");
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through a
+ * change listener. This test makes sure that default values
+ * inherited from within the modified component itself behave as
+ * expected.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChangeListenerChildValues2() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+ TestChildCfg child = parent.getTestChild("test child 1");
+ ChangeListener listener = new ChangeListener();
+ child.addChangeListener(listener);
+
+ // Now modify it.
+ String[] changes = new String[] {
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "changetype: modify",
+ "replace: ds-cfg-virtual-attribute-base-dn",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 2,dc=com"
+ };
+ TestCaseUtils.applyModifications(changes);
+
+ // Make sure that the change listener was notified and the
+ // modified child contains the correct values.
+ child = listener.getChild("test child 1");
+
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through a
+ * change listener. This test makes sure that default values
+ * inherited from outside the modified component behave as expected.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChangeListenerChildValues3() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+ TestChildCfg child = parent.getTestChild("test child 1");
+ ChangeListener listener = new ChangeListener();
+ child.addChangeListener(listener);
+
+ // Now modify it.
+ String[] changes = new String[] {
+ "dn: cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config",
+ "changetype: modify",
+ "replace: ds-cfg-virtual-attribute-group-dn",
+ "ds-cfg-virtual-attribute-group-dn: dc=new value 1,dc=com",
+ "ds-cfg-virtual-attribute-group-dn: dc=new value 2,dc=com"
+ };
+ TestCaseUtils.applyModifications(changes);
+
+ // Make sure that the change listener was notified and the
+ // modified child contains the correct values.
+ child = listener.getChild("test child 1");
+
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values when accessed through a
+ * change listener. This test makes sure that a component is
+ * notified when the default values it inherits from another
+ * component are modified.
+ * <p>
+ * FIXME: disabled - waiting for fix to issue 1793.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test(enabled = false)
+ public void testChangeListenerChildValues4() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+
+ try {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+ TestChildCfg child = parent.getTestChild("test child 1");
+ ChangeListener listener = new ChangeListener();
+ child.addChangeListener(listener);
+
+ // Now modify the parent.
+ String[] changes = new String[] {
+ "dn: cn=test parent 1,cn=test parents,cn=config",
+ "changetype: modify",
+ "replace: ds-cfg-virtual-attribute-base-dn",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 1,dc=com",
+ "ds-cfg-virtual-attribute-base-dn: dc=new value 2,dc=com"
+ };
+ TestCaseUtils.applyModifications(changes);
+
+ // Make sure that the change listener was notified and the
+ // modified child contains the correct values.
+ child = listener.getChild("test child 1");
+
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=new value 1,dc=com", "dc=new value 2,dc=com");
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+
+ // Undo the modifications.
+ String[] changes = new String[] {
+ "dn: cn=test parent 1,cn=test parents,cn=config",
+ "changetype: modify",
+ "delete: ds-cfg-virtual-attribute-base-dn"
+ };
+ TestCaseUtils.applyModifications(changes);
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChildValues1() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_1);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild1(parent.getTestChild("test child 1"));
+ } finally {
+ deleteSubtree("cn=test child 1,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChildValues2() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_2);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild2(parent.getTestChild("test child 2"));
+ } finally {
+ deleteSubtree("cn=test child 2,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChildValues3() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_3);
+
+ try {
+ TestParentCfg parent = getParent("test parent 1");
+ assertChild3(parent.getTestChild("test child 3"));
+ } finally {
+ deleteSubtree("cn=test child 3,cn=test children,cn=test parent 1,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that children have correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testChildValues4() throws Exception {
+ // Add the entry.
+ TestCaseUtils.addEntry(TEST_CHILD_4);
+
+ try {
+ TestParentCfg parent = getParent("test parent 2");
+ assertChild4(parent.getTestChild("test child 4"));
+ } finally {
+ deleteSubtree("cn=test child 4,cn=test children,cn=test parent 2,cn=test parents,cn=config");
+ }
+ }
+
+
+
+ /**
+ * Tests that parent 1 has correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testParentValues1() throws Exception {
+ TestParentCfg parent = getParent("test parent 1");
+
+ Assert.assertEquals(parent.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(parent.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(),
+ "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
+ }
+
+
+
+ /**
+ * Tests that parent 2 has correct values.
+ *
+ * @throws Exception
+ * If the test unexpectedly fails.
+ */
+ @Test
+ public void testParentValues2() throws Exception {
+ TestParentCfg parent = getParent("test parent 2");
+
+ Assert.assertEquals(parent.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(parent.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(parent.getOptionalMultiValuedDNProperty(),
+ "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
+ }
+
+
+
+ // Assert that the values of child 1 are correct.
+ private void assertChild1(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=domain1,dc=com", "dc=domain2,dc=com", "dc=domain3,dc=com");
+ }
+
+
+
+ // Assert that the values of child 2 are correct.
+ private void assertChild2(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=default value c2v1,dc=com", "dc=default value c2v2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=default value c2v1,dc=com", "dc=default value c2v2,dc=com");
+ }
+
+
+
+ // Assert that the values of child 3 are correct.
+ private void assertChild3(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=default value c3v1,dc=com", "dc=default value c3v2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=default value c3v3,dc=com", "dc=default value c3v4,dc=com");
+ }
+
+
+
+ // Assert that the values of child 4 are correct.
+ private void assertChild4(TestChildCfg child) {
+ Assert.assertEquals(child.getMandatoryClassProperty(),
+ "org.opends.server.extensions.UserDefinedVirtualAttributeProvider");
+ Assert.assertEquals(child.getMandatoryReadOnlyAttributeTypeProperty(),
+ DirectoryServer.getAttributeType("description"));
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty1(),
+ "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
+ assertDNSetEquals(child.getOptionalMultiValuedDNProperty2(),
+ "dc=default value p2v1,dc=com", "dc=default value p2v2,dc=com");
+ }
+
+
+
+ // Asserts that the actual set of DNs contains the expected values.
+ private void assertDNSetEquals(SortedSet<DN> actual, String... expected) {
+ String[] actualStrings = new String[actual.size()];
+ int i = 0;
+ for (DN dn : actual) {
+ actualStrings[i] = dn.toString();
+ i++;
+ }
+ Assert.assertEqualsNoOrder(actualStrings, expected);
+ }
+
+
+
+ // Deletes the named sub-tree.
+ private void deleteSubtree(String dn) throws Exception {
+ getAdaptor().deleteSubtree(new LdapName(dn));
+ }
+
+
+
+ // Gets the JNDI connection for the test server instance.
+ private synchronized JNDIDirContextAdaptor getAdaptor() throws Exception {
+ if (adaptor == null) {
+ adaptor = JNDIDirContextAdaptor.simpleBind("127.0.0.1", TestCaseUtils
+ .getServerLdapPort(), "cn=directory manager", "password");
+ }
+ return adaptor;
+ }
+
+
+
+ // Gets the named parent configuration.
+ private TestParentCfg getParent(String name) throws IllegalArgumentException,
+ ConfigException {
+ ServerManagementContext ctx = ServerManagementContext.getInstance();
+ ServerManagedObject<RootCfg> root = ctx.getRootConfigurationManagedObject();
+ TestParentCfg parent = root.getChild(TestCfg.RD_TEST_ONE_TO_MANY_PARENT,
+ name).getConfiguration();
+ return parent;
+ }
+}
--
Gitblit v1.10.0