diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyDefinitionUsageBuilder.java b/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyDefinitionUsageBuilder.java index 9ee882069e..3cade28dc5 100644 --- a/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyDefinitionUsageBuilder.java +++ b/opendj-config/src/main/java/org/forgerock/opendj/config/PropertyDefinitionUsageBuilder.java @@ -13,6 +13,7 @@ * * Copyright 2008-2009 Sun Microsystems, Inc. * Portions copyright 2014-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.config; @@ -227,8 +228,11 @@ public LocalizableMessage visitString(StringPropertyDefinition d, Void p) { if (isDetailed) { LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); builder.append(d.getPatternUsage()); - builder.append(" - "); - builder.append(d.getPatternSynopsis()); + // The pattern synopsis is optional. + if (d.getPatternSynopsis() != null) { + builder.append(" - "); + builder.append(d.getPatternSynopsis()); + } return builder.toMessage(); } else { return LocalizableMessage.raw(d.getPatternUsage()); diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/StringPropertyDefinitionTest.java b/opendj-config/src/test/java/org/forgerock/opendj/config/StringPropertyDefinitionTest.java index d9793db876..7c0c4f8e17 100644 --- a/opendj-config/src/test/java/org/forgerock/opendj/config/StringPropertyDefinitionTest.java +++ b/opendj-config/src/test/java/org/forgerock/opendj/config/StringPropertyDefinitionTest.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008 Sun Microsystems, Inc. + * Portions Copyright 2024-2026 3A Systems, LLC */ package org.forgerock.opendj.config; @@ -35,8 +36,7 @@ public void testValidateValuePatternMatches() { d.validateValue("abc"); } - // TODO : I18N problem - @Test(enabled = false, expectedExceptions = PropertyException.class) + @Test(expectedExceptions = PropertyException.class) public void testValidateValuePatternDoesNotMatch() { StringPropertyDefinition d = getDefinition(true, "^[a-z]+$"); d.validateValue("abc123"); @@ -48,8 +48,7 @@ public void testDecodeValuePatternMatches() { assertEquals(d.decodeValue("abc"), "abc"); } - // TODO : I18N problem - @Test(enabled = false, expectedExceptions = PropertyException.class) + @Test(expectedExceptions = PropertyException.class) public void testDecodeValuePatternDoesNotMatch() { StringPropertyDefinition d = getDefinition(true, "^[a-z]+$"); d.decodeValue("abc123"); diff --git a/opendj-config/src/test/java/org/forgerock/opendj/config/ValidateConfigDefinitionsTest.java b/opendj-config/src/test/java/org/forgerock/opendj/config/ValidateConfigDefinitionsTest.java index 16d46dcfa1..0573832931 100644 --- a/opendj-config/src/test/java/org/forgerock/opendj/config/ValidateConfigDefinitionsTest.java +++ b/opendj-config/src/test/java/org/forgerock/opendj/config/ValidateConfigDefinitionsTest.java @@ -13,19 +13,15 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2024-2026 3A Systems, LLC */ package org.forgerock.opendj.config; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import org.forgerock.opendj.ldap.schema.AttributeType; -import org.forgerock.opendj.ldap.schema.ObjectClass; -import org.forgerock.opendj.ldap.schema.Schema; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -64,10 +60,21 @@ Object[][] enumerateManageObjectDefns() throws Exception { /** Exceptions to config objects having a different objectclass. */ private static final List CLASS_OBJECT_CLASS_EXCEPTIONS = Arrays.asList(new String[] { - "org.forgerock.opendj.config.std.meta.RootCfgDefn", "org.forgerock.opendj.config.std.meta.GlobalCfgDefn", }); - - /** TODO : does not work because can't retrieve object class objects */ - @Test(enabled = false, dataProvider = "enumerateManageObjectDefns") + "org.forgerock.opendj.server.config.meta.RootCfgDefn", + "org.forgerock.opendj.server.config.meta.GlobalCfgDefn", }); + + /** + * Validates the naming conventions of every configuration definition and its properties. + *

+ * This checks the parts of a definition that can be verified from the definitions and their + * LDAP profiles alone: object class and attribute names follow the {@code ds-cfg-} convention, + * {@code -class}/{@code -enabled} properties use the canonical names, and properties are not + * redundantly prefixed with their object name. It intentionally does not validate a definition + * against the live {@code ds-cfg-*} LDAP schema (required/optional attributes, single- vs + * multi-valued, mandatory), because that schema is generated in the server module and is not on + * this module's test class path. + */ + @Test(dataProvider = "enumerateManageObjectDefns") public void validateConfigObjectDefinitions(AbstractManagedObjectDefinition objectDef) { String objName = objectDef.getName(); StringBuilder errors = new StringBuilder(); @@ -86,14 +93,12 @@ public void validateConfigObjectDefinitions(AbstractManagedObjectDefinition propDef : allPropertyDefs) { - validatePropertyDefinition(objectDef, configObjectClass, propDef, errors); + validatePropertyDefinition(objectDef, propDef, errors); } - assertTrue(errors.length() != 0, "The configuration definition for " + objectDef.getName() + assertTrue(errors.length() == 0, "The configuration definition for " + objectDef.getName() + " has the following problems: " + EOL + errors); } @@ -115,8 +120,15 @@ public void validateConfigObjectDefinitions(AbstractManagedObjectDefinition LDAP_ATTRIBUTE_NAME_EXCEPTIONS = Arrays.asList(new String[] { + // http-endpoint's authorization-mechanism property intentionally maps to this attribute. + "ds-cfg-http-authorization-mechanism" + // e.g. "ds-cfg-non-standard-attribute-name" + }); + private void validatePropertyDefinition(AbstractManagedObjectDefinition objectDef, - ObjectClass configObjectClass, PropertyDefinition propDef, StringBuilder errors) { + PropertyDefinition propDef, StringBuilder errors) { String objName = objectDef.getName(); String propName = propDef.getName(); @@ -153,51 +165,12 @@ private void validatePropertyDefinition(AbstractManagedObjectDefinition ob // LDAP attribute name is consistent with the property name String expectedLdapAttr = "ds-cfg-" + propName; - if (!ldapAttrName.equals(expectedLdapAttr)) { + if (!ldapAttrName.equals(expectedLdapAttr) && !LDAP_ATTRIBUTE_NAME_EXCEPTIONS.contains(ldapAttrName)) { errors.append( "For the " + propName + " property on config object " + objName + ", the LDAP attribute must be " - + expectedLdapAttr + " instead of " + ldapAttrName).append(EOL + EOL); - } - - Schema schema = Schema.getDefaultSchema(); - AttributeType attrType = schema.getAttributeType(ldapAttrName); - - // LDAP attribute exists - if (attrType == null) { - errors.append( - propName + " property on config object " + objName + " is declared" + " to use ldap attribute " - + ldapAttrName + ", but this attribute is not in the schema ").append(EOL + EOL); - } else { - - // LDAP attribute is multivalued if the property is multivalued - if (propDef.hasOption(PropertyOption.MULTI_VALUED) && attrType.isSingleValue()) { - errors.append( - propName + " property on config object " + objName + " is declared" - + " as multi-valued, but the corresponding ldap attribute " + ldapAttrName - + " is declared as single-valued.").append(EOL + EOL); - } - - if (configObjectClass != null) { - // If it's mandatory in the schema, it must be mandatory on the - // config property - Set mandatoryAttributes = configObjectClass.getRequiredAttributes(); - if (mandatoryAttributes.contains(attrType) && !propDef.hasOption(PropertyOption.MANDATORY)) { - errors.append( - propName + " property on config object " + objName + " is not declared" - + " as mandatory even though the corresponding ldap attribute " + ldapAttrName - + " is declared as mandatory in the schema.").append(EOL + EOL); - } - - Set allowedAttributes = new HashSet<>(mandatoryAttributes); - allowedAttributes.addAll(configObjectClass.getOptionalAttributes()); - if (!allowedAttributes.contains(attrType)) { - errors.append( - propName + " property on config object " + objName + " has" - + " the corresponding ldap attribute " + ldapAttrName - + ", but this attribute is not an allowed attribute on the configuration " - + " object's objectclass " + configObjectClass.getNameOrOID()).append(EOL + EOL); - } - } + + expectedLdapAttr + " instead of " + ldapAttrName + ". If this deviation is intentional," + + " then add " + ldapAttrName + " to the LDAP_ATTRIBUTE_NAME_EXCEPTIONS array in " + + ValidateConfigDefinitionsTest.class.getName() + " to suppress this warning.").append(EOL + EOL); } } diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java index 06fccc6016..0e1fa60c9c 100644 --- a/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java +++ b/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFChangeRecordWriterTestCase.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2026 3A Systems, LLC */ package org.forgerock.opendj.ldif; @@ -452,7 +453,7 @@ public void testSetIncludeBranchDoesntAllowNull() throws Exception { * @throws Exception * If the test failed unexpectedly. */ - @Test(enabled = false) + @Test public void testSetAddUserFriendlyComments() throws Exception { final List actual = new ArrayList<>(); final LDIFChangeRecordWriter writer = new LDIFChangeRecordWriter(actual); diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java index 894bb465bf..c251c4753a 100644 --- a/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java +++ b/opendj-core/src/test/java/org/forgerock/opendj/ldif/LDIFEntryWriterTestCase.java @@ -685,7 +685,7 @@ public void testWriteComment() throws Exception { * @throws Exception * If the test failed unexpectedly. */ - @Test(enabled = false) + @Test public void testSetAddUserFriendlyComments() throws Exception { final List actual = new ArrayList<>(); final LDIFEntryWriter writer = new LDIFEntryWriter(actual); diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestcase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestCase.java similarity index 99% rename from opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestcase.java rename to opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestCase.java index a475dfc7a0..1c26e86c45 100644 --- a/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestcase.java +++ b/opendj-core/src/test/java/org/forgerock/opendj/ldif/TemplateTagTestCase.java @@ -12,6 +12,7 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2013-2015 ForgeRock AS. + * Portions Copyright 2024-2026 3A Systems, LLC */ package org.forgerock.opendj.ldif; @@ -39,7 +40,7 @@ import org.testng.annotations.Test; @SuppressWarnings("javadoc") -public class TemplateTagTestcase extends SdkTestCase { +public class TemplateTagTestCase extends SdkTestCase { private static final int LINE_NUMBER = 10; private static final TemplateFile NULL_TEMPLATE_FILE = null; diff --git a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java index bf7c0db246..87a652c48a 100644 --- a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java +++ b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java @@ -13,7 +13,7 @@ * * Copyright 2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. - * Portions Copyright 2019-2024 3A Systems, LLC. + * Portions Copyright 2019-2026 3A Systems, LLC. */ package org.forgerock.opendj.grizzly; @@ -308,7 +308,7 @@ public void testSynchronousConnection(ConnectionFactory factory) throws Exceptio * @throws Exception * If an unexpected error occurred. */ - @Test(enabled = false) + @Test public void testSchemaUsage() throws Exception { // Create a connection factory: this should always use the default // schema, even if it is updated. diff --git a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java index cccece5113..41a9a74b8e 100644 --- a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java +++ b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/DefaultTCPNIOTransportTestCase.java @@ -13,6 +13,7 @@ * * Copyright 2010 Sun Microsystems, Inc. * Portions copyright 2012-2016 ForgeRock AS. + * Portions Copyright 2023-2026 3A Systems, LLC. */ package org.forgerock.opendj.grizzly; @@ -43,7 +44,7 @@ public class DefaultTCPNIOTransportTestCase extends SdkTestCase { * @throws Exception * If an unexpected error occurred. */ - @Test(enabled = false) + @Test public void testGetInstance() throws Exception { // Create a transport. final ReferenceCountedObject.Reference transport = DEFAULT_TRANSPORT.acquire(); diff --git a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java index 2e19fdd551..29dd804f4d 100644 --- a/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java +++ b/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java @@ -13,6 +13,7 @@ * * Copyright 2010 Sun Microsystems, Inc. * Portions Copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2017-2026 3A Systems, LLC */ package org.forgerock.opendj.grizzly; @@ -273,7 +274,7 @@ public void testLDAPListenerBasic() throws Exception { * @throws Exception * If an unexpected exception occurred. */ - @Test(enabled = false) + @Test public void testLDAPListenerLoadBalanceDuringHandleAccept() throws Exception { // Online server listener. final MockServerConnection onlineServerConnection = new MockServerConnection(); @@ -453,7 +454,7 @@ public void handleBind(final Integer requestContext, final int version, * @throws Exception * If an unexpected exception occurred. */ - @Test(enabled = false) + @Test public void testLDAPListenerProxyDuringHandleAccept() throws Exception { final MockServerConnection onlineServerConnection = new MockServerConnection(); final MockServerConnectionFactory onlineServerConnectionFactory = @@ -513,10 +514,13 @@ public ServerConnection handleAccept( new ServerConnectionFactoryAdapter(Options.defaultOptions().get(LDAP_DECODE_OPTIONS), proxyServerConnectionFactory)); try { - // Connect and close. + // Connect to the proxy listener (not to the online server + // directly, otherwise the proxy handleAccept is never invoked) + // and close. + final InetSocketAddress proxyAddr = proxyListener.firstSocketAddress(); final Connection connection = - new LDAPConnectionFactory(onlineServerAddr.getHostName(), - onlineServerAddr.getPort()).getConnection(); + new LDAPConnectionFactory(proxyAddr.getHostName(), + proxyAddr.getPort()).getConnection(); assertThat(proxyServerConnection.context.get(10, TimeUnit.SECONDS)).isNotNull(); assertThat(onlineServerConnection.context.get(10, TimeUnit.SECONDS)).isNotNull();