From 832a7aedbb459b6973d4f4fd1926c7894e06f8c0 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sun, 5 Jul 2026 11:08:26 +0300 Subject: [PATCH 1/3] Enable four disabled tests in opendj-core and opendj-grizzly An audit of the enabled=false test methods across the sibling modules found four disabled without any stated reason (the remaining ones all document why they are off). All four pass once enabled: - LDIFEntryWriterTestCase.testSetAddUserFriendlyComments and LDIFChangeRecordWriterTestCase.testSetAddUserFriendlyComments pass as-is; - GrizzlyLDAPListenerTestCase.testLDAPListenerLoadBalanceDuringHandleAccept passes as-is; - GrizzlyLDAPListenerTestCase.testLDAPListenerProxyDuringHandleAccept contained a copy-paste error: the client connected to the online server directly instead of to the proxy listener, so the proxy handleAccept was never invoked and the test timed out waiting for the proxied connection. Connect to the proxy listener instead. --- .../ldif/LDIFChangeRecordWriterTestCase.java | 3 ++- .../opendj/ldif/LDIFEntryWriterTestCase.java | 2 +- .../grizzly/GrizzlyLDAPListenerTestCase.java | 14 +++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) 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-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(); From c501c81f077d502897658e2a51ae126916fca354 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sun, 5 Jul 2026 19:35:38 +0300 Subject: [PATCH 2/3] Enable five more rotted-reason tests and fix a usage builder NPE - Rename TemplateTagTestcase to TemplateTagTestCase: the lowercase "c" never matched the *TestCase include pattern, so its 21 tests never ran (all pass). - PropertyDefinitionUsageBuilder.visitString threw a NullPointerException for string properties which define a pattern but no pattern synopsis, breaking error message generation for pattern validation failures - the "I18N problem" that kept two StringPropertyDefinitionTest methods disabled. Append the synopsis only when present and enable the tests. - ValidateConfigDefinitionsTest.validateConfigObjectDefinitions, DefaultTCPNIOTransportTestCase.testGetInstance and ConnectionFactoryTestCase.testSchemaUsage carry stale disable reasons (a TODO about unavailable object classes, an unclean-environment FIXME and OPENDJ-159): all pass now, twice in a row, together with their neighbouring classes. Still disabled with valid reasons: the entry generator debug printer, the GSSAPI bind test (needs a KDC), the rest2ldap case-insensitive field selection (CREST-86, confirmed still failing) and the Windows-only FileManagerTest case. --- .../opendj/config/PropertyDefinitionUsageBuilder.java | 8 ++++++-- .../opendj/config/StringPropertyDefinitionTest.java | 7 +++---- .../opendj/config/ValidateConfigDefinitionsTest.java | 3 ++- ...{TemplateTagTestcase.java => TemplateTagTestCase.java} | 3 ++- .../opendj/grizzly/ConnectionFactoryTestCase.java | 4 ++-- .../opendj/grizzly/DefaultTCPNIOTransportTestCase.java | 3 ++- 6 files changed, 17 insertions(+), 11 deletions(-) rename opendj-core/src/test/java/org/forgerock/opendj/ldif/{TemplateTagTestcase.java => TemplateTagTestCase.java} (99%) 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..030a0e1aa3 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,6 +13,7 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions copyright 2011-2016 ForgeRock AS. + * Portions Copyright 2024-2026 3A Systems, LLC */ package org.forgerock.opendj.config; @@ -67,7 +68,7 @@ Object[][] enumerateManageObjectDefns() throws Exception { "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") + @Test(dataProvider = "enumerateManageObjectDefns") public void validateConfigObjectDefinitions(AbstractManagedObjectDefinition objectDef) { String objName = objectDef.getName(); StringBuilder errors = new StringBuilder(); 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(); From e1c6fe8ee043cb541b9df9b46de3a795c8d38dfe Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Tue, 7 Jul 2026 10:04:30 +0300 Subject: [PATCH 3/3] Enable ValidateConfigDefinitionsTest as a config naming-convention validator The test was re-enabled in #707 but only stayed green because its assertion was inverted (errors.length() != 0), so it passed precisely when a definition had problems. Its schema-consistency checks also cannot run in opendj-config, where the ds-cfg-* LDAP schema is not on the test class path (object classes/attributes resolve as placeholders) - the reason behind the original "TODO: can't retrieve object class objects". Fix the assertion to == 0, drop the schema-dependent checks, and keep the naming-convention checks verifiable from the definitions and their LDAP profiles alone. Fixing the assertion surfaced three real issues, now fixed: - CLASS_OBJECT_CLASS_EXCEPTIONS referenced the obsolete org.forgerock.opendj.config.std.meta package; updated to org.forgerock.opendj.server.config.meta (root/global). - http-endpoint's authorization-mechanism intentionally maps to ds-cfg-http-authorization-mechanism; added LDAP_ATTRIBUTE_NAME_EXCEPTIONS. --- .../config/ValidateConfigDefinitionsTest.java | 84 +++++++------------ 1 file changed, 28 insertions(+), 56 deletions(-) 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 030a0e1aa3..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 @@ -20,13 +20,8 @@ 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; @@ -65,9 +60,20 @@ 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 */ + "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(); @@ -87,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); } @@ -116,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(); @@ -154,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); } }