mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
01.15.2007 d5a18a324ec87740429780265702686837b09a6a
Modify the DurationPropertyDefinition and DurationUnit classes so that they have more user-friendly encode/decode methods:

* the DurationPropertyDefinition encoder is unchanged: it uses the base property's base unit
* the DurationPropertyDefinition decoder now supports a mixed format in addition to the old format: now users can specify durations using a mixture of units such as 1h30m instead of 90m (both are permitted)
* the DurationUnit class has a toString(long) method which applications can use to get the above mixed unit representation (e.g. CLI)

The unit tests are updated. During the precommit the password policy test cases failed because they were testing some invalid durations which were not being checked in the DurationPropertyDefinition test suite. I've put these missing test cases in the DurationPropertyDefinition test suite. In addition, I've numbered the PWP test data entries so that they are easier to debug in future.
5 files modified
423 ■■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java 43 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/DurationUnit.java 195 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java 10 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationUnitTest.java 39 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java 136 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java
@@ -29,11 +29,9 @@
import static org.opends.server.util.Validator.ensureNotNull;
import static org.opends.server.util.Validator.*;
import java.util.EnumSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -526,48 +524,21 @@
      }
    }
    // Value must be a floating point number followed by a unit.
    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)\\s*$");
    Matcher m = p.matcher(value);
    if (!m.matches()) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    // Group 1 is the float.
    double d;
    // Parse the string representation.
    long ms;
    try {
      d = Double.valueOf(m.group(1));
      ms = DurationUnit.parseValue(value);
    } catch (NumberFormatException e) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    // Group 3 is the unit.
    String unitString = m.group(3);
    DurationUnit unit;
    if (unitString == null) {
      unit = baseUnit;
    } else {
      try {
        unit = DurationUnit.getUnit(unitString);
      } catch (IllegalArgumentException e) {
    // Check the unit is in range - values must not be more granular
    // than the base unit.
    if ((ms % baseUnit.getDuration()) != 0) {
        throw new IllegalPropertyValueStringException(this, value);
      }
    }
    // Check the unit is in range.
    if (unit.getDuration() < baseUnit.getDuration()) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    if (maximumUnit != null) {
      if (unit.getDuration() > maximumUnit.getDuration()) {
        throw new IllegalPropertyValueStringException(this, value);
      }
    }
    // Convert the value a long in the property's required unit.
    long ms = unit.toMilliSeconds(d);
    Long i = (long) baseUnit.fromMilliSeconds(ms);
    try {
      validateValue(i);
opendj-sdk/opends/src/server/org/opends/server/admin/DurationUnit.java
@@ -41,19 +41,9 @@
public enum DurationUnit {
  /**
   * A millisecond unit.
   * A day unit.
   */
  MILLI_SECONDS(1L, "ms", "milliseconds"),
  /**
   * A second unit.
   */
  SECONDS(1000L, "s", "seconds"),
  /**
   * A minute unit.
   */
  MINUTES((long) 60 * 1000, "m", "minutes"),
  DAYS((long) 24 * 60 * 60 * 1000, "d", "days"),
  /**
   * An hour unit.
@@ -61,9 +51,19 @@
  HOURS((long) 60 * 60 * 1000, "h", "hours"),
  /**
   * A day unit.
   * A millisecond unit.
   */
  DAYS((long) 24 * 60 * 60 * 1000, "d", "days"),
  MILLI_SECONDS(1L, "ms", "milliseconds"),
  /**
   * A minute unit.
   */
  MINUTES((long) 60 * 1000, "m", "minutes"),
  /**
   * A second unit.
   */
  SECONDS(1000L, "s", "seconds"),
  /**
   * A week unit.
@@ -108,13 +108,17 @@
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milli-seconds. The duration string must specify the
   * unit e.g. "10s".
   * unit e.g. "10s". This method will parse duration string
   * representations produced from the {@link #toString(long)} method.
   * Therefore, a duration can comprise of multiple duration
   * specifiers, for example <code>1d15m25s</code>.
   *
   * @param s
   *          The duration string to be parsed.
   * @return Returns the parsed duration in milli-seconds.
   * @throws NumberFormatException
   *           If the provided duration string could not be parsed.
   * @see #toString(long)
   */
  public static long parseValue(String s) throws NumberFormatException {
    return parseValue(s, null);
@@ -124,7 +128,10 @@
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milli-seconds.
   * duration in milli-seconds. This method will parse duration string
   * representations produced from the {@link #toString(long)} method.
   * Therefore, a duration can comprise of multiple duration
   * specifiers, for example <code>1d15m25s</code>.
   *
   * @param s
   *          The duration string to be parsed.
@@ -135,31 +142,83 @@
   * @return Returns the parsed duration in milli-seconds.
   * @throws NumberFormatException
   *           If the provided duration string could not be parsed.
   * @see #toString(long)
   */
  public static long parseValue(String s, DurationUnit defaultUnit)
      throws NumberFormatException {
    // Value must be a floating point number followed by a unit.
    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$");
    Matcher m = p.matcher(s);
    String ns = s.trim();
    if (ns.length() == 0) {
      throw new NumberFormatException("Empty duration value \"" + s + "\"");
    }
    if (!m.matches()) {
    Pattern p1 = Pattern.compile("^((\\d+)w)?" + "((\\d+)d)?"
        + "((\\d+)h)?" + "((\\d+)m)?" + "((\\d+)s)?" + "((\\d+)ms)?$",
        Pattern.CASE_INSENSITIVE);
    Matcher m1 = p1.matcher(ns);
    if (m1.matches()) {
      // Value must be of the form produced by toString(long).
      String weeks = m1.group(2);
      String days = m1.group(4);
      String hours = m1.group(6);
      String minutes = m1.group(8);
      String seconds = m1.group(10);
      String ms = m1.group(12);
      long duration = 0;
      try {
        if (weeks != null) {
          duration += Long.valueOf(weeks) * WEEKS.getDuration();
        }
        if (days != null) {
          duration += Long.valueOf(days) * DAYS.getDuration();
        }
        if (hours != null) {
          duration += Long.valueOf(hours) * HOURS.getDuration();
        }
        if (minutes != null) {
          duration += Long.valueOf(minutes) * MINUTES.getDuration();
        }
        if (seconds != null) {
          duration += Long.valueOf(seconds) * SECONDS.getDuration();
        }
        if (ms != null) {
          duration += Long.valueOf(ms) * MILLI_SECONDS.getDuration();
        }
      } catch (NumberFormatException e) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      }
      return duration;
    } else {
      // Value must be a floating point number followed by a unit.
      Pattern p2 = Pattern.compile("^(\\d+(\\.\\d+)?)\\s*(\\w+)?$");
      Matcher m2 = p2.matcher(ns);
      if (!m2.matches()) {
      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
    }
    // Group 1 is the float.
    double d;
    try {
      d = Double.valueOf(m.group(1));
        d = Double.valueOf(m2.group(1));
    } catch (NumberFormatException e) {
      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
    }
    // Group 3 is the unit.
    String unitString = m.group(3);
      String unitString = m2.group(3);
    DurationUnit unit;
    if (unitString == null) {
      if (defaultUnit == null) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
          throw new NumberFormatException("Invalid duration value \"" + s
              + "\"");
      } else {
        unit = defaultUnit;
      }
@@ -167,21 +226,73 @@
      try {
        unit = getUnit(unitString);
      } catch (IllegalArgumentException e) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
          throw new NumberFormatException("Invalid duration value \"" + s
              + "\"");
      }
    }
    return unit.toMilliSeconds(d);
  }
  }
  // The size of the unit in milli-seconds.
  private final long sz;
  /**
   * Returns a string representation of the provided duration. The
   * string representation can be parsed using the
   * {@link #parseValue(String)} method. The string representation is
   * comprised of one or more of the number of weeks, days, hours,
   * minutes, seconds, and milli-seconds. Here are some examples:
   *
   * <pre>
   * toString(0)       // 0ms
   * toString(999)     // 999ms
   * toString(1000)    // 1s
   * toString(1500)    // 1s500ms
   * toString(3650000) // 1h50s
   * toString(3700000) // 1h1m40s
   * </pre>
   *
   * @param duration
   *          The duration in milli-seconds.
   * @return Returns a string representation of the provided duration.
   * @throws IllegalArgumentException
   *           If the provided duration is negative.
   * @see #parseValue(String)
   * @see #parseValue(String, DurationUnit)
   */
  public static String toString(long duration) throws IllegalArgumentException {
    if (duration < 0) {
      throw new IllegalArgumentException("Negative duration " + duration);
    }
    if (duration == 0) {
      return "0ms";
    }
    DurationUnit[] units = new DurationUnit[] { WEEKS, DAYS, HOURS, MINUTES,
        SECONDS, MILLI_SECONDS };
    long remainder = duration;
    StringBuilder builder = new StringBuilder();
    for (DurationUnit unit : units) {
      long count = remainder / unit.getDuration();
      if (count > 0) {
        builder.append(count);
        builder.append(unit.getShortName());
        remainder = remainder - (count * unit.getDuration());
      }
    }
    return builder.toString();
  }
  // The long name of the unit.
  private final String longName;
  // The abbreviation of the unit.
  private final String shortName;
  // The long name of the unit.
  private final String longName;
  // The size of the unit in milli-seconds.
  private final long sz;
@@ -208,34 +319,6 @@
  /**
   * Get the best-fit unit for the specified duration in this unit.
   * For example, if this unit is minutes and the duration 120 is
   * provided, then the best fit unit is hours: 2h. Similarly, if the
   * duration is 0.5, then the best fit unit will by seconds: 30s.
   *
   * @param duration
   *          The duration.
   * @return Returns the best-fit unit for the specified duration in
   *         this unit.
   */
  public DurationUnit getBestFitUnit(double duration) {
    long ms = toMilliSeconds(duration);
    if (ms == 0) {
      return this;
    } else if (ms > 0) {
      for (DurationUnit unit : new DurationUnit[] { WEEKS, DAYS, HOURS,
          MINUTES, SECONDS }) {
        if ((ms % unit.sz) == 0) {
          return unit;
        }
      }
    }
    return MILLI_SECONDS;
  }
  /**
   * Get the number of milli-seconds that this unit represents.
   *
   * @return Returns the number of milli-seconds that this unit
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
@@ -405,9 +405,11 @@
            {"0 h", 0L},
            {"0.00 h", 0L},
            {"1h", 1L},
            {"1.1h", 1L},
            {"1 h", 1L},
            {"1.1 h", 1L},
            { "0ms", 0L },
            { "1h60m", 2L },
            { "1d10h", 34L },
            { "4d600m", 106L },
            // conversion tests
            {"1 d", 24L},
@@ -441,12 +443,16 @@
  @DataProvider(name = "decodeValueData2")
  public Object[][] createDecodeValueData2() {
    return new Object[][]{
            {""},
            {"0"}, // no unit
            {"123"}, // no unit
            {"a s"},
            {"1 x"},
            {"0.h"},
            {"0. h"},
            {"1.h"},
            {"1. h"},
            {"1.1 h"}, // too granular
            {"30 m"}, // unit too small violation
            {"60 m"}, // unit too small violation
            {"1 w"},  // unit too big violation
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationUnitTest.java
@@ -79,28 +79,37 @@
    /**
     * @return test data for testing getUnit
     */
    @DataProvider(name = "testGetBestFitUnit")
    public Object[][] createGetBestFitData() {
    @DataProvider(name = "testToString")
    public Object[][] createToStringData() {
      return new Object[][]{
              { SECONDS, 0, SECONDS },
              { MINUTES, 0, MINUTES },
              { HOURS, 0, HOURS },
              { MINUTES, .5D, SECONDS },
              { MINUTES, 119D, MINUTES },
              { MINUTES, 120D, HOURS },
              { MINUTES, 121D, MINUTES },
              { MINUTES, Double.MIN_VALUE, MINUTES }
              { 0L, "0ms" },
              { 1L, "1ms" },
              { 999L, "999ms" },
              { 1000L, "1s" },
              { 1001L, "1s1ms" },
              { 59999L, "59s999ms" },
              { 60000L, "1m" },
              { 3599999L, "59m59s999ms" },
              { 3600000L, "1h" }
      };
    }
    /**
     * @param unit of best fit value
     * @param value ordinal value
     * @param expectedValue for comparison
     * @param expected for comparison
     */
    @Test(dataProvider = "testGetBestFitUnit")
    public void testGetBestFitUnit(DurationUnit unit, double value, DurationUnit expectedValue) {
        assertEquals(unit.getBestFitUnit(value), expectedValue);
    @Test(dataProvider = "testToString")
    public void testToString(long value, String expected) {
        assertEquals(DurationUnit.toString(value), expected);
    }
    /**
     * @param expected for comparison
     * @param value for parsing
     */
    @Test(dataProvider = "testToString")
    public void testParseValue(long expected, String value) {
        assertEquals(DurationUnit.parseValue(value), expected);
    }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
@@ -92,7 +92,7 @@
         throws Exception
  {
    List<Entry> entries = TestCaseUtils.makeEntries(
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 1,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -120,7 +120,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 2,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -149,7 +149,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 3,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -178,7 +178,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 4,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -208,7 +208,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 5,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -237,7 +237,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 6,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -266,7 +266,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 7,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -295,7 +295,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 8,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -324,7 +324,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 9,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -353,7 +353,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 10,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -382,7 +382,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 11,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -411,7 +411,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 12,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -440,7 +440,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 13,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -469,7 +469,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 14,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -498,7 +498,7 @@
         "ds-cfg-require-secure-password-changes: invalid",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 15,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -527,7 +527,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: invalid",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 16,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -556,7 +556,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 17,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -585,7 +585,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 18,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -614,7 +614,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 19,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -643,7 +643,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 20,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -672,7 +672,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 21,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -701,7 +701,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 22,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -730,7 +730,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 23,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -759,7 +759,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 24,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -788,7 +788,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 25,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -817,7 +817,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 26,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -846,7 +846,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 27,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -875,7 +875,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 28,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -904,7 +904,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 29,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -933,7 +933,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 30,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -962,7 +962,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 31,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -991,7 +991,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 32,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1020,7 +1020,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 33,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1049,7 +1049,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 34,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1078,7 +1078,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 35,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1107,7 +1107,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 36,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1136,7 +1136,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 37,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1165,7 +1165,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 38,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1194,7 +1194,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 39,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1223,7 +1223,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 40,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1252,7 +1252,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 41,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1281,7 +1281,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 42,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1310,7 +1310,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 43,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1339,7 +1339,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 44,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1368,7 +1368,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 45,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1397,7 +1397,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 46,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1426,7 +1426,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 47,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1455,7 +1455,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 48,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1484,7 +1484,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 49,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1513,7 +1513,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 50,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1542,7 +1542,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 51,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1571,7 +1571,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 52,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1600,7 +1600,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 53,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1629,7 +1629,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 54,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1658,7 +1658,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 55,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1687,7 +1687,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 56,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1717,7 +1717,7 @@
         "ds-cfg-skip-validation-for-administrators: false",
         "ds-cfg-require-change-by-time: invalid",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 57,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1747,7 +1747,7 @@
         "ds-cfg-skip-validation-for-administrators: false",
         "ds-cfg-last-login-time-format: invalid",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 58,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1775,7 +1775,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 59,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1804,7 +1804,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 60,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1834,7 +1834,7 @@
         "ds-cfg-skip-validation-for-administrators: false",
         "ds-cfg-account-status-notification-handler-dn: invalid",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 61,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1865,7 +1865,7 @@
         "ds-cfg-account-status-notification-handler-dn: cn=nonexistent," +
              "cn=Account Status Notification Handlers,cn=config",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 62,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1893,7 +1893,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 63,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1922,7 +1922,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 64,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1952,7 +1952,7 @@
         "ds-cfg-require-secure-password-changes: false",
         "ds-cfg-skip-validation-for-administrators: false",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 65,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -1982,7 +1982,7 @@
         "ds-cfg-skip-validation-for-administrators: false",
         "ds-cfg-password-validator-dn: invalid",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 66,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -2013,7 +2013,7 @@
         "ds-cfg-password-validator-dn: cn=nonexistent," +
              "cn=Password Validators,cn=config",
         "",
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 67,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",
@@ -2047,7 +2047,7 @@
      // normally included in the default scheme.  It is based on the internal
      // knowledge that the idle lockout interval is the last attribute checked
      // during validation.
         "dn: cn=Default Password Policy,cn=Password Policies,cn=config",
         "dn: cn=Default Password Policy 68,cn=Password Policies,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-policy",
         "cn: Default Password Policy",