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

matthew_swift
24.21.2007 82f7055c3e823a58e0d747cc782f8cf9eed913aa
This change (no associated issue no.) addresses some counter-intuitive behavior discovered when specifying some duration based properties:

* duration and size units had to be specified in default behaviors

* upper/lower limit had to be specified without a unit and with
values in the property's base unit (bytes for size properties)

This change enables us to specify duration and size property constraints and defaults with or without units (when no unit is specified we default to the property's base unit).

The Duration{Unit|PropertyDefinition} APIs have also been re-aligned with the Size{Unit|PropertyDefinition} APIs where possible and the unit tests updated (incl. replacing many bad uses of the assert keyword with the assertEquals TestNG method).
9 files modified
563 ■■■■ changed files
opendj-sdk/opends/resource/admin/property-types/duration.xsl 8 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java 141 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/DurationUnit.java 210 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/SizePropertyDefinition.java 6 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/SizeUnit.java 43 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java 78 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationUnitTest.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizeUnitTest.java 72 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/property-types/duration.xsl
@@ -56,13 +56,13 @@
    </xsl:if>
    <xsl:if test="boolean(@upper-limit)">
      <xsl:value-of
        select="concat('      builder.setUpperLimit(',
                       @upper-limit, 'L);&#xa;')" />
        select="concat('      builder.setUpperLimit(&quot;',
                       @upper-limit, '&quot;);&#xa;')" />
    </xsl:if>
    <xsl:if test="boolean(@lower-limit)">
      <xsl:value-of
        select="concat('      builder.setLowerLimit(',
                       @lower-limit, 'L);&#xa;')" />
        select="concat('      builder.setLowerLimit(&quot;',
                       @lower-limit, '&quot;);&#xa;')" />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>
opendj-sdk/opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java
@@ -76,17 +76,16 @@
  // String used to represent unlimited durations.
  private static final String UNLIMITED = "unlimited";
  // The base unit for this property definition (values including
  // limits are specified in this unit).
  // The base unit for this property definition.
  private final DurationUnit baseUnit;
  // The optional maximum unit for this property definition.
  private final DurationUnit maximumUnit;
  // The lower limit of the property value.
  // The lower limit of the property value in milli-seconds.
  private final long lowerLimit;
  // The optional upper limit of the property value.
  // The optional upper limit of the property value in milli-seconds.
  private final Long upperLimit;
  // Indicates whether this property allows the use of the "unlimited"
@@ -103,17 +102,17 @@
  public static class Builder extends
      AbstractBuilder<Long, DurationPropertyDefinition> {
    // The base unit for this property definition (values including
    // limits are specified in this unit).
    // The base unit for this property definition.
    private DurationUnit baseUnit = DurationUnit.SECONDS;
    // The optional maximum unit for this property definition.
    private DurationUnit maximumUnit = null;
    // The lower limit of the property value.
    // The lower limit of the property value in milli-seconds.
    private long lowerLimit = 0L;
    // The optional upper limit of the property value.
    // The optional upper limit of the property value in
    // milli-seconds.
    private Long upperLimit = null;
    // Indicates whether this property allows the use of the
@@ -124,8 +123,8 @@
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    private Builder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      super(d, propertyName);
    }
@@ -144,8 +143,7 @@
     *           known duration unit, or if the base unit is bigger
     *           than the maximum unit.
     */
    public final void setBaseUnit(String unit)
        throws IllegalArgumentException {
    public final void setBaseUnit(String unit) throws IllegalArgumentException {
      ensureNotNull(unit);
      setBaseUnit(DurationUnit.getUnit(unit));
@@ -234,10 +232,10 @@
    /**
     * Set the lower limit.
     * Set the lower limit in milli-seconds.
     *
     * @param lowerLimit
     *          The new lower limit (must be >= 0).
     *          The new lower limit (must be >= 0) in milli-seconds.
     * @throws IllegalArgumentException
     *           If a negative lower limit was specified, or the lower
     *           limit is greater than the upper limit.
@@ -259,11 +257,30 @@
    /**
     * Set the upper limit.
     * Set the lower limit using a string representation of the limit.
     * If the string does not specify a unit, the current base unit
     * will be used.
     *
     * @param lowerLimit
     *          The string representation of the new lower limit.
     * @throws IllegalArgumentException
     *           If the lower limit could not be parsed, or if a
     *           negative lower limit was specified, or the lower
     *           limit is greater than the upper limit.
     */
    public final void setLowerLimit(String lowerLimit)
        throws IllegalArgumentException {
      setLowerLimit(DurationUnit.parseValue(lowerLimit, baseUnit));
    }
    /**
     * Set the upper limit in milli-seconds.
     *
     * @param upperLimit
     *          The new upper limit or <code>null</code> if there is
     *          no upper limit.
     *          The new upper limit in milli-seconds, or
     *          <code>null</code> if there is no upper limit.
     * @throws IllegalArgumentException
     *           If a negative upper limit was specified, or the lower
     *           limit is greater than the upper limit or unlimited
@@ -293,6 +310,29 @@
    /**
     * Set the upper limit using a string representation of the limit.
     * If the string does not specify a unit, the current base unit
     * will be used.
     *
     * @param upperLimit
     *          The string representation of the new upper limit, or
     *          <code>null</code> if there is no upper limit.
     * @throws IllegalArgumentException
     *           If the upper limit could not be parsed, or if the
     *           lower limit is greater than the upper limit.
     */
    public final void setUpperLimit(String upperLimit)
        throws IllegalArgumentException {
      if (upperLimit == null) {
        setUpperLimit((Long) null);
      } else {
        setUpperLimit(DurationUnit.parseValue(upperLimit, baseUnit));
      }
    }
    /**
     * Specify whether or not this property definition will allow
     * unlimited values (default is false).
     *
@@ -320,12 +360,12 @@
     */
    @Override
    protected DurationPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d,
        String propertyName, EnumSet<PropertyOption> options,
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        DefaultBehaviorProvider<Long> defaultBehavior) {
      return new DurationPropertyDefinition(d, propertyName, options,
          defaultBehavior, baseUnit, maximumUnit, lowerLimit,
          upperLimit, allowUnlimited);
          defaultBehavior, baseUnit, maximumUnit, lowerLimit, upperLimit,
          allowUnlimited);
    }
  }
@@ -341,20 +381,19 @@
   *          The property name.
   * @return Returns the new integer property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
  public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private DurationPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      DefaultBehaviorProvider<Long> defaultBehavior,
      DurationUnit baseUnit, DurationUnit maximumUnit,
      Long lowerLimit, Long upperLimit, boolean allowUnlimited) {
  private DurationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName, EnumSet<PropertyOption> options,
      DefaultBehaviorProvider<Long> defaultBehavior, DurationUnit baseUnit,
      DurationUnit maximumUnit, Long lowerLimit, Long upperLimit,
      boolean allowUnlimited) {
    super(d, Long.class, propertyName, options, defaultBehavior);
    this.baseUnit = baseUnit;
    this.maximumUnit = maximumUnit;
@@ -391,9 +430,9 @@
  /**
   * Get the lower limit.
   * Get the lower limit in milli-seconds.
   *
   * @return Returns the lower limit.
   * @return Returns the lower limit in milli-seconds.
   */
  public long getLowerLimit() {
    return lowerLimit;
@@ -402,10 +441,10 @@
  /**
   * Get the upper limit.
   * Get the upper limit in milli-seconds.
   *
   * @return Returns the upper limit or <code>null</code> if there
   *         is no upper limit.
   * @return Returns the upper limit in milli-seconds, or
   *         <code>null</code> if there is no upper limit.
   */
  public Long getUpperLimit() {
    return upperLimit;
@@ -429,19 +468,19 @@
   * {@inheritDoc}
   */
  @Override
  public void validateValue(Long value)
      throws IllegalPropertyValueException {
  public void validateValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (!allowUnlimited && value < lowerLimit) {
    long nvalue = baseUnit.toMilliSeconds(value);
    if (!allowUnlimited && nvalue < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
      // unlimited allowed
    } else if (value >= 0 && value < lowerLimit) {
    } else if (nvalue >= 0 && nvalue < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
    }
    if ((upperLimit != null) && (value > upperLimit)) {
    if ((upperLimit != null) && (nvalue > upperLimit)) {
      throw new IllegalPropertyValueException(this, value);
    }
  }
@@ -452,8 +491,7 @@
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(Long value)
      throws IllegalPropertyValueException {
  public String encodeValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    // Make sure that we correctly encode negative values as
@@ -489,8 +527,7 @@
    }
    // Value must be a floating point number followed by a unit.
    Pattern p = Pattern
        .compile("^\\s*(\\d+(\\.\\d*)?)\\s*(\\w+)\\s*$");
    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)\\s*$");
    Matcher m = p.matcher(value);
    if (!m.matches()) {
@@ -506,26 +543,32 @@
    }
    // Group 3 is the unit.
    DurationUnit u;
    String unitString = m.group(3);
    DurationUnit unit;
    if (unitString == null) {
      unit = baseUnit;
    } else {
    try {
      u = DurationUnit.getUnit(m.group(3));
        unit = DurationUnit.getUnit(unitString);
    } catch (IllegalArgumentException e) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    }
    // Check the unit is in range.
    if (u.getDuration() < baseUnit.getDuration()) {
    if (unit.getDuration() < baseUnit.getDuration()) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    if (maximumUnit != null) {
      if (u.getDuration() > maximumUnit.getDuration()) {
      if (unit.getDuration() > maximumUnit.getDuration()) {
        throw new IllegalPropertyValueStringException(this, value);
      }
    }
    // Convert the value a long in the property's required unit.
    Long i = (long) u.getDuration(d, baseUnit);
    long ms = unit.toMilliSeconds(d);
    Long i = (long) baseUnit.fromMilliSeconds(ms);
    try {
      validateValue(i);
    } catch (IllegalPropertyValueException e) {
@@ -563,10 +606,12 @@
    builder.append(" lowerLimit=");
    builder.append(lowerLimit);
    builder.append("ms");
    if (upperLimit != null) {
      builder.append(" upperLimit=");
      builder.append(upperLimit);
      builder.append("ms");
    }
    builder.append(" allowUnlimited=");
opendj-sdk/opends/src/server/org/opends/server/admin/DurationUnit.java
@@ -30,6 +30,8 @@
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -79,6 +81,99 @@
    }
  }
  /**
   * Get the unit corresponding to the provided unit name.
   *
   * @param s
   *          The name of the unit. Can be the abbreviated or long
   *          name and can contain white space and mixed case
   *          characters.
   * @return Returns the unit corresponding to the provided unit name.
   * @throws IllegalArgumentException
   *           If the provided name did not correspond to a known
   *           duration unit.
   */
  public static DurationUnit getUnit(String s) throws IllegalArgumentException {
    DurationUnit unit = nameToUnit.get(s.trim().toLowerCase());
    if (unit == null) {
      throw new IllegalArgumentException("Illegal duration unit \"" + s + "\"");
    }
    return unit;
  }
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milli-seconds. The duration string must specify the
   * unit e.g. "10s".
   *
   * @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.
   */
  public static long parseValue(String s) throws NumberFormatException {
    return parseValue(s, null);
  }
  /**
   * Parse the provided duration string and return its equivalent
   * duration in milli-seconds.
   *
   * @param s
   *          The duration string to be parsed.
   * @param defaultUnit
   *          The default unit to use if there is no unit specified in
   *          the duration string, or <code>null</code> if the
   *          string must always contain a unit.
   * @return Returns the parsed duration in milli-seconds.
   * @throws NumberFormatException
   *           If the provided duration string could not be parsed.
   */
  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);
    if (!m.matches()) {
      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
    }
    // Group 1 is the float.
    double d;
    try {
      d = Double.valueOf(m.group(1));
    } catch (NumberFormatException e) {
      throw new NumberFormatException("Invalid duration value \"" + s + "\"");
    }
    // Group 3 is the unit.
    String unitString = m.group(3);
    DurationUnit unit;
    if (unitString == null) {
      if (defaultUnit == null) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      } else {
        unit = defaultUnit;
      }
    } else {
      try {
        unit = getUnit(unitString);
      } catch (IllegalArgumentException e) {
        throw new NumberFormatException("Invalid duration value \"" + s + "\"");
      }
    }
    return unit.toMilliSeconds(d);
  }
  // The size of the unit in milli-seconds.
  private final long sz;
@@ -100,32 +195,54 @@
  /**
   * Get the unit corresponding to the provided unit name.
   * Converts the specified duration in milli-seconds to this unit.
   *
   * @param s
   *          The name of the unit. Can be the abbreviated or long name and can
   *          contain white space and mixed case characters.
   * @return Returns the unit corresponding to the provided unit name.
   * @throws IllegalArgumentException
   *           If the provided name did not correspond to a known duration unit.
   * @param duration
   *          The duration in milli-seconds.
   * @return Returns milli-seconds in this unit.
   */
  public static DurationUnit getUnit(String s) throws IllegalArgumentException {
    DurationUnit unit = nameToUnit.get(s.trim().toLowerCase());
    if (unit == null) {
      throw new IllegalArgumentException("Illegal duration unit \"" + s + "\"");
    }
    return unit;
  public double fromMilliSeconds(long duration) {
    return ((double) duration / sz);
  }
  /**
   * Get the abbreviated name of this unit.
   * 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.
   *
   * @return Returns the abbreviated name of this unit.
   * @param duration
   *          The duration.
   * @return Returns the best-fit unit for the specified duration in
   *         this unit.
   */
  public String getShortName() {
    return shortName;
  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
   *         represents.
   */
  public long getDuration() {
    return sz;
  }
@@ -142,12 +259,12 @@
  /**
   * Get the number of milli-seconds that this unit represents.
   * Get the abbreviated name of this unit.
   *
   * @return Returns the number of milli-seconds that this unit represents.
   * @return Returns the abbreviated name of this unit.
   */
  public long getDuration() {
    return sz;
  public String getShortName() {
    return shortName;
  }
@@ -156,60 +273,21 @@
   * Converts the specified duration in this unit to milli-seconds.
   *
   * @param duration
   *          The duration.
   * @return Returns the number of milli-seconds that the duration represents.
   *          The duration as a quantity of this unit.
   * @return Returns the number of milli-seconds that the duration
   *         represents.
   */
  public long getDuration(double duration) {
  public long toMilliSeconds(double duration) {
    return (long) (sz * duration);
  }
  /**
   * Converts a duration in this unit to the specified unit.
   *
   * @param duration
   *          The duration.
   * @param unit
   *          The required unit.
   * @return Returns a value representing the duration in the specified unit.
   */
  public double getDuration(double duration, DurationUnit unit) {
    return (sz * duration) / unit.sz;
  }
  /**
   * 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) {
    for (DurationUnit unit :
            new DurationUnit[]{WEEKS, DAYS, HOURS, MINUTES, SECONDS}) {
      double v = getDuration(duration, unit);
      if (Double.isInfinite(v) || Double.isNaN(v) || v == 0) {
        return this;
      }
      if (v >= 1 && Math.floor(v) == Math.ceil(v)) {
        return unit;
      }
    }
    return MILLI_SECONDS;
  }
  /**
   * {@inheritDoc}
   * <p>
   * This implementation returns the abbreviated name of this duration unit.
   * This implementation returns the abbreviated name of this duration
   * unit.
   */
  @Override
  public String toString() {
opendj-sdk/opends/src/server/org/opends/server/admin/SizePropertyDefinition.java
@@ -130,7 +130,7 @@
     */
    public final void setLowerLimit(String lowerLimit)
        throws IllegalArgumentException {
      setLowerLimit(SizeUnit.parseValue(lowerLimit));
      setLowerLimit(SizeUnit.parseValue(lowerLimit, SizeUnit.BYTES));
    }
@@ -175,7 +175,7 @@
      if (upperLimit == null) {
        setUpperLimit((Long) null);
      } else {
        setUpperLimit(SizeUnit.parseValue(upperLimit));
        setUpperLimit(SizeUnit.parseValue(upperLimit, SizeUnit.BYTES));
      }
    }
@@ -344,7 +344,7 @@
    // Decode the value.
    Long i;
    try {
      i = SizeUnit.parseValue(value);
      i = SizeUnit.parseValue(value, SizeUnit.BYTES);
    } catch (NumberFormatException e) {
      throw new IllegalPropertyValueStringException(this, value);
    }
opendj-sdk/opends/src/server/org/opends/server/admin/SizeUnit.java
@@ -121,17 +121,39 @@
  /**
   * Parse the provided size string and return its equivalent size in bytes.
   * Parse the provided size string and return its equivalent size in
   * bytes. The size string must specify the unit e.g. "10kb".
   *
   * @param s
   *          The size string to be parsed.
   * @return Returns the parsed size in bytes.
   * @return Returns the parsed duration in bytes.
   * @throws NumberFormatException
   *           If the provided size string could not be parsed.
   */
  public static long parseValue(String s) throws NumberFormatException {
    return parseValue(s, null);
  }
  /**
   * Parse the provided size string and return its equivalent size in
   * bytes.
   *
   * @param s
   *          The size string to be parsed.
   * @param defaultUnit
   *          The default unit to use if there is no unit specified in
   *          the size string, or <code>null</code> if the string
   *          must always contain a unit.
   * @return Returns the parsed size in bytes.
   * @throws NumberFormatException
   *           If the provided size string could not be parsed.
   */
  public static long parseValue(String s, SizeUnit defaultUnit)
      throws NumberFormatException {
    // Value must be a floating point number followed by a unit.
    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)\\s*$");
    Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$");
    Matcher m = p.matcher(s);
    if (!m.matches()) {
@@ -147,14 +169,25 @@
    }
    // Group 3 is the unit.
    String unitString = m.group(3);
    SizeUnit unit;
    if (unitString == null) {
      if (defaultUnit == null) {
        throw new NumberFormatException("Invalid size value \"" + s + "\"");
      } else {
        unit = defaultUnit;
      }
    } else {
    try {
      SizeUnit u = getUnit(m.group(3));
      return u.toBytes(d);
        unit = getUnit(unitString);
    } catch (IllegalArgumentException e) {
      throw new NumberFormatException("Invalid size value \"" + s + "\"");
    }
  }
    return unit.toBytes(d);
  }
  // The size of the unit in bytes.
  private final long sz;
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/ConfigurableEnvironment.java
@@ -276,7 +276,7 @@
        // JE durations are in microseconds so we must convert.
        DurationPropertyDefinition durationPropDefn =
             (DurationPropertyDefinition)propDefn;
        value = 1000*durationPropDefn.getBaseUnit().getDuration(value);
        value = 1000*durationPropDefn.getBaseUnit().toMilliSeconds(value);
        return String.valueOf(value);
      }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/DurationPropertyDefinitionTest.java
@@ -56,7 +56,7 @@
    DurationPropertyDefinition.Builder builder = createTestBuilder();
    builder.setLowerLimit((long) 1);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    assert spd.getLowerLimit() == 1;
    assertEquals(spd.getLowerLimit(), 1);
  }
  /**
@@ -64,7 +64,7 @@
   * @return data
   */
  @DataProvider(name = "longLimitData")
  public Object[][] createlongLimitData() {
  public Object[][] createLongLimitData() {
    return new Object[][]{
            {1L, 1L},
            // { null, 0 }
@@ -92,11 +92,47 @@
   * @param expectedValue to compare
   */
  @Test(dataProvider = "longLimitData")
  public void testLowerLimit2(long limit, Long expectedValue) {
  public void testLowerLimit2(long limit, long expectedValue) {
    DurationPropertyDefinition.Builder builder = createTestBuilder();
    builder.setLowerLimit(limit);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    assert spd.getLowerLimit() == expectedValue;
    assertEquals(spd.getLowerLimit(), expectedValue);
  }
  /**
   * Creates data for testing string-based limit values
   *
   * @return data
   */
  @DataProvider(name = "stringLimitData")
  public Object[][] createStringLimitData() {
    return new Object[][] {
        { "ms", "123", 123 },
        { "ms", "123s", 123000 },
        { "s", "123", 123000 },
        { "s", "123s", 123000 },
        { "m", "10", 600000 },
        { "m", "10s", 10000 }
    };
  }
  /**
   * Tests setting/getting of lower limit as String.
   *
   * @param unit
   *          The unit.
   * @param value
   *          The limit value.
   * @param expected
   *          The expected limit in ms.
   */
  @Test(dataProvider = "stringLimitData")
  public void testLowerLimit3(String unit, String value, long expected) {
    DurationPropertyDefinition.Builder builder = createTestBuilder();
    builder.setBaseUnit(DurationUnit.getUnit(unit));
    builder.setLowerLimit(value);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    assertEquals(spd.getLowerLimit(), expected);
  }
  /**
@@ -107,7 +143,7 @@
    DurationPropertyDefinition.Builder builder = createTestBuilder();
    builder.setLowerLimit((long) 1);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    assert spd.getLowerLimit() == 1;
    assertEquals(spd.getLowerLimit(), 1);
  }
  /**
@@ -120,7 +156,7 @@
    DurationPropertyDefinition.Builder builder = createTestBuilder();
    builder.setUpperLimit(limit);
    DurationPropertyDefinition spd = buildTestDefinition(builder);
    assert spd.getUpperLimit().equals(expectedValue);
    assertEquals((long) spd.getUpperLimit(), expectedValue);
  }
  /**
@@ -179,13 +215,13 @@
   * @return data
   */
  @DataProvider(name = "validateValueData")
  public Object[][] createvalidateValueData() {
  public Object[][] createValidateValueData() {
    return new Object[][]{
            {5L, 10L, false, 7L},
            {5L, null, true, -1L},
            {5L, 10L, false, 5L},
            {5L, 10L, false, 10L},
            {5L, null, false, 10000L}
            {5000L, 10000L, false, 7L},
            {5000L, null, true, -1L},
            {5000L, 10000L, false, 5L},
            {5000L, 10000L, false, 10L},
            {5000L, null, false, 10000L}
    };
  }
@@ -213,10 +249,10 @@
  @DataProvider(name = "illegalValidateValueData")
  public Object[][] createIllegalValidateValueData() {
    return new Object[][]{
            {5L, 10L, false, null},
            {5L, 10L, false, 1L},
            {5L, 10L, false, 11L},
            {5L, 10L, false, -1L}
            {5000L, 10000L, false, null},
            {5000L, 10000L, false, 1L},
            {5000L, 10000L, false, 11L},
            {5000L, 10000L, false, -1L}
    };
  }
@@ -364,17 +400,13 @@
            // syntax tests
            {"unlimited", -1L},
            {"0h", 0L},
            {"0.h", 0L},
            {"0.0h", 0L},
            {"0.00h", 0L},
            {"0 h", 0L},
            {"0. h", 0L},
            {"0.00 h", 0L},
            {"1h", 1L},
            {"1.h", 1L},
            {"1.1h", 1L},
            {"1 h", 1L},
            {"1. h", 1L},
            {"1.1 h", 1L},
            // conversion tests
@@ -399,7 +431,7 @@
//    if (spd.decodeValue(value) != expectedValue) {
//      System.out.println(spd.decodeValue(value) + "!=" + expectedValue);
//    }
    assert(spd.decodeValue(value) == expectedValue);
    assertEquals(spd.decodeValue(value), expectedValue);
  }
  /**
@@ -411,6 +443,10 @@
    return new Object[][]{
            {"a s"},
            {"1 x"},
            {"0.h"},
            {"0. h"},
            {"1.h"},
            {"1. h"},
            {"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
@@ -82,12 +82,13 @@
    @DataProvider(name = "testGetBestFitUnit")
    public Object[][] createGetBestFitData() {
      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.MAX_VALUE, MINUTES },
              { MINUTES, Double.MIN_VALUE, MINUTES }
      };
    }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/SizeUnitTest.java
@@ -72,7 +72,7 @@
   * @return The array of illegal test DN strings.
   */
  @DataProvider(name = "parseValue1Data")
  public Object[][] createParseValueData() {
  public Object[][] createParseValue1Data() {
    return new Object[][]{
            {"1.0 b", 1L},
            {"1.0 kb", 1000L},
@@ -95,17 +95,17 @@
   * @param expectedValue for comparison
   */
  @Test(dataProvider = "parseValue1Data")
  public void testParseValue1(String value, Long expectedValue) {
    assert SizeUnit.parseValue(value) == expectedValue;
  public void testParseValue1(String value, long expectedValue) {
    assertEquals(SizeUnit.parseValue(value), expectedValue);
  }
  /**
   * Creates illegal data for testing String to SizeUnit conversions
   *
   * @return The array of illegal test DN strings.
   * @return The array of illegal test strings.
   */
  @DataProvider(name = "parseValue2Data")
  public Object[][] createIllegalParseValueData() {
  public Object[][] createParseValue2Data() {
    return new Object[][]{
            {"a.0 b"},
            {"1.a kb"},
@@ -130,6 +130,62 @@
  }
  /**
   * Creates data for testing String to SizeUnit conversions
   *
   * @return The array of test strings.
   */
  @DataProvider(name = "parseValue3Data")
  public Object[][] createParseValue3Data() {
    return new Object[][]{
            {"1.0 b", 1L},
            {"1.0 kb", 1000L},
            {"1.0 kib", 1024L},
            {"1.0", 1000L},
            {"1000", 1000000L},
            {"1MB", 1000000L}
    };
  }
  /**
   * Tests parsing of SizeUnits specified as String values
   * @param value to parse
   * @param expectedValue for comparison
   */
  @Test(dataProvider = "parseValue3Data")
  public void testParseValue3(String value, long expectedValue) {
    assertEquals(SizeUnit.parseValue(value, SizeUnit.KILO_BYTES), expectedValue);
  }
  /**
   * Creates illegal data for testing String to SizeUnit conversions
   *
   * @return The array of illegal test DN strings.
   */
  @DataProvider(name = "parseValue4Data")
  public Object[][] createParseValue4Data() {
    return new Object[][]{
            {"a.0 b"},
            {"1.a kb"},
            {"1.0 xx"},
            { "" },
            { "hello" },
            { "-1" },
            { "-1b" },
            { "1x" },
            { "1.1y" }
    };
  }
  /**
   * Tests that illegal String specified SizeUnits throw exceptions
   * @param value to parse
   */
  @Test(dataProvider = "parseValue4Data", expectedExceptions = NumberFormatException.class)
  public void testParseValue4(String value) {
    SizeUnit.parseValue(value, SizeUnit.KILO_BYTES);
  }
  /**
   * Creates data for testing fromBytes
   *
   * @return data
@@ -150,7 +206,7 @@
   */
  @Test(dataProvider = "fromBytesTestData")
  public void testFromBytes(SizeUnit unit, long value, double expected) {
    assert unit.fromBytes(value) == expected;
    assertEquals(unit.fromBytes(value), expected);
  }
  /**
@@ -265,7 +321,7 @@
   */
  @Test(dataProvider = "sizeData")
  public void testGetSize(SizeUnit unit, long expectedSize) {
    assert unit.getSize() == expectedSize;
    assertEquals(unit.getSize(), expectedSize);
  }
  /**
@@ -287,7 +343,7 @@
   */
  @Test(dataProvider = "toBytesData")
  public void testToBytes(SizeUnit unit, double amt, long expected) {
    assert unit.toBytes(amt) == expected;
    assertEquals(unit.toBytes(amt), expected);
  }
  /**