From d4b8c4a45412fef75de97c9b3bafbc2b50d43f2a Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 09 Nov 2006 20:35:37 +0000
Subject: [PATCH] Add new unit tests that perform validation for message IDs.  One test verifies that there are no duplicate message ID assignments, and the other makes sure that all message IDs defined are registered with the server and have a valid default message.  This testing is conducted using reflection to examine all declared fields in the message classes.

---
 opends/src/server/org/opends/server/messages/SchemaMessages.java                                         |   70 ++++---
 opends/src/server/org/opends/server/messages/ToolMessages.java                                           |    6 
 opends/tests/unit-tests-testng/src/server/org/opends/server/messages/MessagesTestCase.java               |   46 +++++
 opends/tests/unit-tests-testng/src/server/org/opends/server/messages/UnregisteredMessageIDsTestCase.java |  145 ++++++++++++++++
 opends/src/server/org/opends/server/messages/ConfigMessages.java                                         |   63 +++---
 opends/src/server/org/opends/server/messages/BackendMessages.java                                        |    2 
 opends/tests/unit-tests-testng/src/server/org/opends/server/messages/DuplicateMessageIDsTestCase.java    |  135 +++++++++++++++
 opends/src/server/org/opends/server/messages/PluginMessages.java                                         |    2 
 opends/src/server/org/opends/server/messages/CoreMessages.java                                           |   20 +-
 opends/src/server/org/opends/server/messages/ExtensionsMessages.java                                     |    4 
 10 files changed, 418 insertions(+), 75 deletions(-)

diff --git a/opends/src/server/org/opends/server/messages/BackendMessages.java b/opends/src/server/org/opends/server/messages/BackendMessages.java
index e1ef600..4612d81 100644
--- a/opends/src/server/org/opends/server/messages/BackendMessages.java
+++ b/opends/src/server/org/opends/server/messages/BackendMessages.java
@@ -2603,7 +2603,7 @@
     registerMessage(MSGID_TASK_CANNOT_PARSE_ACTUAL_START_TIME,
                     "An error occurred while trying to parse the actual " +
                     "start time value %s from task entry %s.");
-    registerMessage(MSGID_TASK_CANNOT_PARSE_SCHEDULED_START_TIME,
+    registerMessage(MSGID_TASK_CANNOT_PARSE_COMPLETION_TIME,
                     "An error occurred while trying to parse the completion " +
                     "time value %s from task entry %s.");
     registerMessage(MSGID_TASK_MISSING_ATTR,
diff --git a/opends/src/server/org/opends/server/messages/ConfigMessages.java b/opends/src/server/org/opends/server/messages/ConfigMessages.java
index 615f2a8..237e237 100644
--- a/opends/src/server/org/opends/server/messages/ConfigMessages.java
+++ b/opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -4889,26 +4889,6 @@
 
 
   /**
-   * The message ID for the description of the server time limit configuration
-   * attribute.  This does not take any arguments.
-   */
-  public static final int MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT =
-       CATEGORY_MASK_CONFIG | SEVERITY_MASK_INFORMATIONAL | 450;
-
-
-
-  /**
-   * The message ID for the message that will be used if an error occurs while
-   * trying to process the server time limit.  This takes two arguments, which
-   * are the DN of the configuration entry and a string representation of the
-   * exception that was caught.
-   */
-  public static final int MSGID_CONFIG_CORE_INVALID_TIME_LIMIT =
-       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 451;
-
-
-
-  /**
    * The message ID for the message that will be used if an error occurs while
    * attempting to retrieve the configuration base entry for the Directory
    * Server synchronization providers.  This takes a single argument, which is
@@ -5575,15 +5555,6 @@
 
 
   /**
-   * The message ID for the message that will be used if no default password
-   * policy has been defined.  This does not take any arguments.
-   */
-  public static final int MSGID_CONFIG_PWPOLICY_NO_DEFAULT_POLICY =
-       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 514;
-
-
-
-  /**
    * The message ID for the message that will be used if a password policy
    * configuration entry is invalid.  This takes two arguments, which are the DN
    * of the invalid password policy configuration entry and a message that
@@ -6153,6 +6124,35 @@
 
 
   /**
+   * The message ID for the description of the server time limit configuration
+   * attribute.  This does not take any arguments.
+   */
+  public static final int MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT =
+       CATEGORY_MASK_CONFIG | SEVERITY_MASK_INFORMATIONAL | 569;
+
+
+
+  /**
+   * The message ID for the message that will be used if an error occurs while
+   * trying to process the server time limit.  This takes two arguments, which
+   * are the DN of the configuration entry and a string representation of the
+   * exception that was caught.
+   */
+  public static final int MSGID_CONFIG_CORE_INVALID_TIME_LIMIT =
+       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 570;
+
+
+
+  /**
+   * The message ID for the message that will be used if no default password
+   * policy has been defined.  This does not take any arguments.
+   */
+  public static final int MSGID_CONFIG_PWPOLICY_NO_DEFAULT_POLICY =
+       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 571;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -7607,7 +7607,7 @@
                     "determine whether the plugin associated with " +
                     "configuration entry %s should be enabled or disabled:  " +
                     "%s.  It will be disabled.");
-    registerMessage(MSGID_CONFIG_PLUGIN_ATTR_DESCRIPTION_CLASS,
+    registerMessage(MSGID_CONFIG_PLUGIN_ATTR_DESCRIPTION_PLUGIN_TYPE,
                     "Specifies the plugin type(s) for this plugin, which "+
                     "control the times when this plugin will be invoked " +
                     "during processing.  This value is only read when " +
@@ -7814,6 +7814,9 @@
     registerMessage(MSGID_CONFIG_LOGGER_INVALID_SUPPRESS_INT_OPERATION_VALUE,
         "Invalid value specified for attribute %s. " +
         "Allowed values are true or false.");
+    registerMessage(MSGID_CONFIG_LOGGER_SUPPRESS_INTERNAL_OPERATIONS,
+                    "Indicates whether messages for internal operations " +
+                    "should be excluded from the access log file.");
 
 
     registerMessage(MSGID_CONFIG_KEYMANAGER_CANNOT_INSTALL_NULL_PROVIDER,
diff --git a/opends/src/server/org/opends/server/messages/CoreMessages.java b/opends/src/server/org/opends/server/messages/CoreMessages.java
index a7357e7..98e59fe 100644
--- a/opends/src/server/org/opends/server/messages/CoreMessages.java
+++ b/opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -5887,16 +5887,6 @@
 
   /**
    * The message ID for the message that will be used if an attempt is made to
-   * increment an attribute that does not exist.  This takes a single argument,
-   * which is the name of the attribute.
-   */
-  public static final int MSGID_ENTRY_INCREMENT_NO_SUCH_ATTRIBUTE =
-       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 562;
-
-
-
-  /**
-   * The message ID for the message that will be used if an attempt is made to
    * increment an attribute that has multiple values.  This takes a single
    * argument, which is the name of the attribute.
    */
@@ -5947,6 +5937,16 @@
 
 
   /**
+   * The message ID for the message that will be used if an attempt is made to
+   * increment an attribute that does not exist.  This takes a single argument,
+   * which is the name of the attribute.
+   */
+  public static final int MSGID_ENTRY_INCREMENT_NO_SUCH_ATTRIBUTE =
+       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 568;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined
    * in this class.
    */
diff --git a/opends/src/server/org/opends/server/messages/ExtensionsMessages.java b/opends/src/server/org/opends/server/messages/ExtensionsMessages.java
index 1cc7df3..ad5a893 100644
--- a/opends/src/server/org/opends/server/messages/ExtensionsMessages.java
+++ b/opends/src/server/org/opends/server/messages/ExtensionsMessages.java
@@ -4192,7 +4192,7 @@
     registerMessage(MSGID_FIFOCACHE_UPDATED_INCLUDE_FILTERS,
                     "The set of search filters that will control which " +
                     "entries may be included in the cache has been updated.");
-    registerMessage(MSGID_FIFOCACHE_UPDATED_INCLUDE_FILTERS,
+    registerMessage(MSGID_FIFOCACHE_UPDATED_EXCLUDE_FILTERS,
                     "The set of search filters that will control which " +
                     "entries should be be excluded from the cache has been " +
                     "updated.");
@@ -5675,7 +5675,7 @@
     registerMessage(MSGID_SOFTREFCACHE_UPDATED_INCLUDE_FILTERS,
                     "The set of search filters that will control which " +
                     "entries may be included in the cache has been updated.");
-    registerMessage(MSGID_SOFTREFCACHE_UPDATED_INCLUDE_FILTERS,
+    registerMessage(MSGID_SOFTREFCACHE_UPDATED_EXCLUDE_FILTERS,
                     "The set of search filters that will control which " +
                     "entries should be be excluded from the cache has been " +
                     "updated.");
diff --git a/opends/src/server/org/opends/server/messages/PluginMessages.java b/opends/src/server/org/opends/server/messages/PluginMessages.java
index 07f38b6..b043752 100644
--- a/opends/src/server/org/opends/server/messages/PluginMessages.java
+++ b/opends/src/server/org/opends/server/messages/PluginMessages.java
@@ -879,7 +879,7 @@
                     ATTR_PROFILE_DIR + " of configuration entry %s is " +
                     "invalid because the specified path does not exist or " +
                     "is not a directory.");
-    registerMessage(MSGID_PLUGIN_PROFILER_CANNOT_DETERMINE_INTERVAL,
+    registerMessage(MSGID_PLUGIN_PROFILER_CANNOT_DETERMINE_ACTION,
                     "An unexpected error occurred while attempting to " +
                     "determine the value of the " + ATTR_PROFILE_ACTION +
                     " attribute in the %s entry:  %s.  No action will be " +
diff --git a/opends/src/server/org/opends/server/messages/SchemaMessages.java b/opends/src/server/org/opends/server/messages/SchemaMessages.java
index a95c8e7..4d55bd4 100644
--- a/opends/src/server/org/opends/server/messages/SchemaMessages.java
+++ b/opends/src/server/org/opends/server/messages/SchemaMessages.java
@@ -2797,35 +2797,6 @@
 
 
   /**
-   * The message ID for the message that will be used if an authPassword value
-   * has an invalid character in the authValue element.  This takes a single
-   * argument, which is the position of the invalid character.
-   */
-  public static final int MSGID_ATTR_SYNTAX_AUTHPW_INVALID_AUTH_VALUE_CHAR =
-       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 246;
-
-
-
-  /**
-   * The message ID for the message that will be used if an authPassword value
-   * has an empty authValue element.  This does not take any arguments.
-   */
-  public static final int MSGID_ATTR_SYNTAX_AUTHPW_NO_AUTH_VALUE =
-       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 247;
-
-
-
-  /**
-   * The message ID for the message that will be used if an authPassword value
-   * has an invalid character after the authValue element.  This takes a single
-   * argument, which is the position of the invalid character.
-   */
-  public static final int MSGID_ATTR_SYNTAX_AUTHPW_INVALID_TRAILING_CHAR =
-       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 248;
-
-
-
-  /**
    * The message ID for the message that will be used if a value does not start
    * with an opening parenthesis.  This takes a single argument, which is the
    * provided value string.
@@ -2948,6 +2919,35 @@
 
 
   /**
+   * The message ID for the message that will be used if an authPassword value
+   * has an invalid character in the authValue element.  This takes a single
+   * argument, which is the position of the invalid character.
+   */
+  public static final int MSGID_ATTR_SYNTAX_AUTHPW_INVALID_AUTH_VALUE_CHAR =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 261;
+
+
+
+  /**
+   * The message ID for the message that will be used if an authPassword value
+   * has an empty authValue element.  This does not take any arguments.
+   */
+  public static final int MSGID_ATTR_SYNTAX_AUTHPW_NO_AUTH_VALUE =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 262;
+
+
+
+  /**
+   * The message ID for the message that will be used if an authPassword value
+   * has an invalid character after the authValue element.  This takes a single
+   * argument, which is the position of the invalid character.
+   */
+  public static final int MSGID_ATTR_SYNTAX_AUTHPW_INVALID_TRAILING_CHAR =
+       CATEGORY_MASK_SCHEMA | SEVERITY_MASK_SEVERE_ERROR | 263;
+
+
+
+  /**
    * Associates a set of generic messages with the message IDs defined in this
    * class.
    */
@@ -3631,6 +3631,18 @@
                     "objectclass with OID %s (%s).  This objectclass exists " +
                     "in the server schema but is defined as %s rather than " +
                     "structural.");
+    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR,
+                    "The definition for the name form with OID %s declared " +
+                    "that it should include required attribute \"%s\".  No " +
+                    "attribute type matching this name or OID exists in the " +
+                    "server schema, so a default attribute type with the " +
+                    "directory string syntax will be used.");
+    registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR,
+                    "The definition for the name form with OID %s declared " +
+                    "that it should include optional attribute \"%s\".  No " +
+                    "attribute type matching this name or OID exists in the " +
+                    "server schema, so a default attribute type with the " +
+                    "directory string syntax will be used.");
     registerMessage(MSGID_ATTR_SYNTAX_NAME_FORM_NO_STRUCTURAL_CLASS,
                     "The provided value \"%s\" could not be parsed as a name " +
                     "form description because it does not specify the " +
diff --git a/opends/src/server/org/opends/server/messages/ToolMessages.java b/opends/src/server/org/opends/server/messages/ToolMessages.java
index 70eb891..50d7990 100644
--- a/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -7093,7 +7093,7 @@
     registerMessage(MSGID_LDIFIMPORT_CANNOT_INITIALIZE_PWPOLICY,
                     "An error occurred while attempting to initialize the " +
                     "password policy components:  %s.");
-    registerMessage(MSGID_LDIFEXPORT_CANNOT_INITIALIZE_PLUGINS,
+    registerMessage(MSGID_LDIFIMPORT_CANNOT_INITIALIZE_PLUGINS,
                     "An error occurred while attempting to initialize the " +
                     "LDIF import plugins:  %s.");
     registerMessage(MSGID_LDIFIMPORT_CANNOT_PARSE_EXCLUDE_FILTER,
@@ -7213,6 +7213,8 @@
                     "# Your password has expired.");
     registerMessage(MSGID_BIND_PASSWORD_EXPIRING,
                     "# Your password will expire in %s.");
+    registerMessage(MSGID_BIND_ACCOUNT_LOCKED,
+                    "# Your account has been locked.");
     registerMessage(MSGID_BIND_MUST_CHANGE_PASSWORD,
                     "# You must change your password before any other " +
                     "operations will be allowed.");
@@ -8585,7 +8587,7 @@
                     "Line %d of the template file contains an incomplete " +
                     "tag that starts with either '<' or '{' but does get " +
                     "closed.");
-    registerMessage(MSGID_MAKELDIF_NO_COLON_IN_BRANCH_EXTRA_LINE,
+    registerMessage(MSGID_MAKELDIF_NO_COLON_IN_TEMPLATE_LINE,
                     "There is no colon to separate the attribute name from " +
                     "the value pattern on line %s of the template file in " +
                     "the definition for template %s.");
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/DuplicateMessageIDsTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/DuplicateMessageIDsTestCase.java
new file mode 100644
index 0000000..fb6afc0
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/DuplicateMessageIDsTestCase.java
@@ -0,0 +1,135 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.messages;
+
+
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+
+import static org.testng.Assert.*;
+
+
+
+/**
+ * This class provides a mechanism for determining whether any of the messages
+ * files have duplicate message IDs.
+ */
+public class DuplicateMessageIDsTestCase
+       extends MessagesTestCase
+{
+  /**
+   * Look in the build filesystem for files in the org.opends.server.messages
+   * package.  Dynamically load all of those classes and use reflection to look
+   * at all fields in those classes.  Make sure that there are no duplicate
+   * values between any of those constant fields.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void TestDuplicateMessageIDs()
+         throws Exception
+  {
+    String s = File.separator;
+    String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT);
+    String messageClassesDir = buildRoot + s + "build" + s + "classes" + s +
+                               "org" + s + "opends" + s + "server" + s +
+                               "messages";
+    File f = new File(messageClassesDir);
+    LinkedList<String> classNames = new LinkedList<String>();
+    for (String filename : f.list())
+    {
+      if (! filename.endsWith(".class"))
+      {
+        continue;
+      }
+
+      classNames.add("org.opends.server.messages." +
+                     filename.substring(0, filename.length()-6));
+    }
+
+    assertFalse(classNames.isEmpty());
+
+    HashMap<Integer,String> messageIDs = new HashMap<Integer,String>();
+    LinkedList<String> conflictingMessageIDs = new LinkedList<String>();
+    for (String className : classNames)
+    {
+      Class c = Class.forName(className);
+      for (Field field : c.getDeclaredFields())
+      {
+        if (field.getType().getName().equals("int"))
+        {
+          if (Modifier.isStatic(field.getModifiers()) &&
+              Modifier.isFinal(field.getModifiers()) &&
+              field.getName().startsWith("MSGID_"))
+          {
+            String fieldName  = className + "." + field.getName();
+            int    fieldValue = field.getInt(null);
+
+            String conflictingField = messageIDs.get(fieldValue);
+            if (conflictingField == null)
+            {
+              messageIDs.put(fieldValue, fieldName);
+            }
+            else
+            {
+              conflictingMessageIDs.add(conflictingField + "==" +
+                                        fieldName + "==" + fieldValue);
+            }
+          }
+        }
+      }
+    }
+
+    assertFalse(messageIDs.isEmpty());
+    if (! conflictingMessageIDs.isEmpty())
+    {
+      StringBuilder buffer = new StringBuilder();
+
+      Iterator<String> iterator = conflictingMessageIDs.iterator();
+      buffer.append("Conflicting message IDs detected:  ");
+      buffer.append(iterator.next());
+
+      while (iterator.hasNext())
+      {
+        buffer.append(", ");
+        buffer.append(iterator.next());
+      }
+
+      assertTrue(conflictingMessageIDs.isEmpty(), buffer.toString());
+    }
+  }
+}
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/MessagesTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/MessagesTestCase.java
new file mode 100644
index 0000000..9513ff7
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/MessagesTestCase.java
@@ -0,0 +1,46 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.messages;
+
+
+
+import org.testng.annotations.Test;
+
+import org.opends.server.DirectoryServerTestCase;
+
+
+
+/**
+ * An abstract base class for all messages test cases.
+ */
+@Test(groups = { "precommit", "messages" })
+public abstract class MessagesTestCase
+       extends DirectoryServerTestCase
+{
+  // No implementation required.
+}
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/UnregisteredMessageIDsTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/UnregisteredMessageIDsTestCase.java
new file mode 100644
index 0000000..da93fbf
--- /dev/null
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/messages/UnregisteredMessageIDsTestCase.java
@@ -0,0 +1,145 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.messages;
+
+
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.opends.server.TestCaseUtils;
+
+import static org.testng.Assert.*;
+
+
+
+/**
+ * This class provides a mechanism for determining whether any of the message
+ * IDs defined have not been registered with the server (and therefore may not
+ * have a default message).
+ */
+public class UnregisteredMessageIDsTestCase
+       extends MessagesTestCase
+{
+  /**
+   * Make sure that the Directory Server is running.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @BeforeClass()
+  public void startServer()
+         throws Exception
+  {
+    TestCaseUtils.startServer();
+  }
+
+
+
+  /**
+   * Look in the build filesystem for files in the org.opends.server.messages
+   * package.  Dynamically load all of those classes and use reflection to look
+   * at all fields in those classes.  For each field, make sure that it has a
+   * corresponding message registered with the server.
+   *
+   * @throws  Exception  If an unexpected problem occurs.
+   */
+  @Test()
+  public void TestUnregisteredMessageIDs()
+         throws Exception
+  {
+    ConcurrentHashMap<Integer,String> messages = MessageHandler.getMessages();
+
+    String s = File.separator;
+    String buildRoot = System.getProperty(TestCaseUtils.PROPERTY_BUILD_ROOT);
+    String messageClassesDir = buildRoot + s + "build" + s + "classes" + s +
+                               "org" + s + "opends" + s + "server" + s +
+                               "messages";
+    File f = new File(messageClassesDir);
+    LinkedList<String> classNames = new LinkedList<String>();
+    for (String filename : f.list())
+    {
+      if (! filename.endsWith(".class"))
+      {
+        continue;
+      }
+
+      classNames.add("org.opends.server.messages." +
+                     filename.substring(0, filename.length()-6));
+    }
+
+    assertFalse(classNames.isEmpty());
+
+    LinkedList<String> unregisteredMessageIDs = new LinkedList<String>();
+    for (String className : classNames)
+    {
+      Class c = Class.forName(className);
+      for (Field field : c.getDeclaredFields())
+      {
+        if (field.getType().getName().equals("int"))
+        {
+          if (Modifier.isStatic(field.getModifiers()) &&
+              Modifier.isFinal(field.getModifiers()) &&
+              field.getName().startsWith("MSGID_"))
+          {
+            String fieldName  = className + "." + field.getName();
+            int    fieldValue = field.getInt(null);
+
+            if (! messages.containsKey(fieldValue))
+            {
+              unregisteredMessageIDs.add(fieldName);
+            }
+          }
+        }
+      }
+    }
+
+    if (! unregisteredMessageIDs.isEmpty())
+    {
+      StringBuilder buffer = new StringBuilder();
+
+      Iterator<String> iterator = unregisteredMessageIDs.iterator();
+      buffer.append("Unregistered message IDs detected:  ");
+      buffer.append(iterator.next());
+
+      while (iterator.hasNext())
+      {
+        buffer.append(", ");
+        buffer.append(iterator.next());
+      }
+
+      assertTrue(unregisteredMessageIDs.isEmpty(), buffer.toString());
+    }
+  }
+}
+

--
Gitblit v1.10.0