OPENDJ-2776 Migrate remaining DN/RDN unit tests from the server
The unit tests exposed several bugs:
* RDN.valueOf() ignored trailing RDN sequences or garbage
* RDN constructors allowed zero AVAs
* RDN constructors allowed AVAs having duplicate attribute types
* AVA decoding allowed OIDs with trailing "." characters.
| | |
| | | } |
| | | } |
| | | |
| | | private static ByteString delimitAndEvaluateEscape(final SubstringReader reader) { |
| | | final StringBuilder valueBuffer = new StringBuilder(); |
| | | StringBuilder hexBuffer = null; |
| | | reader.skipWhitespaces(); |
| | | |
| | | boolean escaped = false; |
| | | int trailingSpaces = 0; |
| | | while (reader.remaining() > 0) { |
| | | final char c = reader.read(); |
| | | if (escaped) { |
| | | // This character is escaped. |
| | | if (isHexDigit(c)) { |
| | | // Unicode characters. |
| | | if (reader.remaining() <= 0) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(reader.getString())); |
| | | } |
| | | |
| | | // Check the next byte for hex. |
| | | final char c2 = reader.read(); |
| | | if (isHexDigit(c2)) { |
| | | if (hexBuffer == null) { |
| | | hexBuffer = new StringBuilder(); |
| | | } |
| | | hexBuffer.append(c); |
| | | hexBuffer.append(c2); |
| | | // We may be at the end. |
| | | if (reader.remaining() == 0) { |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | } |
| | | } else { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(reader.getString())); |
| | | } |
| | | } else { |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.append(c); |
| | | } |
| | | escaped = false; |
| | | } else if (c == '\\') { |
| | | escaped = true; |
| | | trailingSpaces = 0; |
| | | } else { |
| | | // Check for delimited chars. |
| | | if (c == '+' || c == ',' || c == ';') { |
| | | reader.reset(); |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.setLength(valueBuffer.length() - trailingSpaces); |
| | | return ByteString.valueOfUtf8(valueBuffer); |
| | | } |
| | | // It is definitely not a delimiter at this point. |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.append(c); |
| | | trailingSpaces = c != ' ' ? 0 : trailingSpaces + 1; |
| | | } |
| | | reader.mark(); |
| | | } |
| | | |
| | | reader.reset(); |
| | | valueBuffer.setLength(valueBuffer.length() - trailingSpaces); |
| | | return ByteString.valueOfUtf8(valueBuffer); |
| | | } |
| | | |
| | | private static void appendHexChars(final SubstringReader reader, |
| | | final StringBuilder valueBuffer, |
| | | final StringBuilder hexBuffer) { |
| | | if (hexBuffer == null) { |
| | | return; |
| | | } |
| | | final ByteString bytes = ByteString.valueOfHex(hexBuffer.toString()); |
| | | try { |
| | | valueBuffer.append(new String(bytes.toByteArray(), "UTF-8")); |
| | | } catch (final Exception e) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE.get(reader.getString(), String.valueOf(e))); |
| | | } |
| | | // Clean up the hex buffer. |
| | | hexBuffer.setLength(0); |
| | | } |
| | | |
| | | private static String readAttributeName(final SubstringReader reader) { |
| | | int length = 1; |
| | | reader.mark(); |
| | |
| | | boolean lastWasPeriod = false; |
| | | while (reader.remaining() > 0) { |
| | | c = reader.read(); |
| | | |
| | | if (c == '=' || c == ' ') { |
| | | // This signals the end of the OID. |
| | | break; |
| | |
| | | } |
| | | length++; |
| | | } |
| | | if (lastWasPeriod) { |
| | | throw illegalCharacter(reader, '.'); |
| | | } |
| | | } else if (isAlpha(c)) { |
| | | // This must be an attribute description. In this case, we will |
| | | // only accept alphabetic characters, numeric digits, and the |
| | | // hyphen. |
| | | while (reader.remaining() > 0) { |
| | | c = reader.read(); |
| | | |
| | | if (c == '=' || c == ' ') { |
| | | // This signals the end of the OID. |
| | | break; |
| | | } else if (!isAlpha(c) && !isDigit(c) && c != '-') { |
| | | throw illegalCharacter(reader, c); |
| | | } |
| | | |
| | | length++; |
| | | } |
| | | } else { |
| | | throw illegalCharacter(reader, c); |
| | | } |
| | | |
| | | reader.reset(); |
| | | |
| | | // Return the position of the first non-space character after the token |
| | | reader.reset(); |
| | | return reader.read(length); |
| | | } |
| | | |
| | |
| | | // Value is HEX encoded BER. |
| | | return readAttributeValueAsBER(reader); |
| | | } else if (c == '"') { |
| | | // The value should continue until the corresponding closing quotation mark. |
| | | return readAttributeValueWithinQuotes(reader); |
| | | // Legacy support for RFC 2253. The value should continue until the |
| | | // corresponding closing quotation mark and has the same format as |
| | | // RFC 4514 attribute values, except that special characters, |
| | | // excluding double quote and back-slash, do not need escaping. |
| | | reader.mark(); |
| | | return readAttributeValue(reader, true); |
| | | } else { |
| | | // Otherwise, use general parsing to find the end of the value. |
| | | return readAttributeValueUnescaped(reader); |
| | | return readAttributeValue(reader, false); |
| | | } |
| | | } |
| | | |
| | | private static ByteString readAttributeValueUnescaped(final SubstringReader reader) { |
| | | reader.reset(); |
| | | final ByteString bytes = delimitAndEvaluateEscape(reader); |
| | | if (bytes.length() == 0) { |
| | | // We don't allow an empty attribute value. |
| | | final LocalizableMessage message = |
| | | ERR_ATTR_SYNTAX_DN_INVALID_REQUIRES_ESCAPE_CHAR.get(reader.getString(), reader.pos()); |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | } |
| | | return bytes; |
| | | } |
| | | |
| | | private static ByteString readAttributeValueWithinQuotes(final SubstringReader reader) { |
| | | int length = 0; |
| | | reader.mark(); |
| | | while (true) { |
| | | if (reader.remaining() <= 0) { |
| | | // We hit the end of the AVA before the closing quote. That's an error. |
| | | throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DN_UNMATCHED_QUOTE.get(reader.getString())); |
| | | } |
| | | |
| | | if (reader.read() == '"') { |
| | | // This is the end of the value. |
| | | break; |
| | | } |
| | | length++; |
| | | } |
| | | reader.reset(); |
| | | final ByteString retString = ByteString.valueOfUtf8(reader.read(length)); |
| | | reader.read(); |
| | | return retString; |
| | | } |
| | | |
| | | private static ByteString readAttributeValueAsBER(final SubstringReader reader) { |
| | | // The first two characters must be hex characters. |
| | | reader.mark(); |
| | |
| | | } |
| | | } |
| | | |
| | | private static ByteString readAttributeValue(final SubstringReader reader, final boolean isQuoted) { |
| | | reader.reset(); |
| | | final ByteString bytes = delimitAndEvaluateEscape(reader, isQuoted); |
| | | if (bytes.length() == 0) { |
| | | // We don't allow an empty attribute value. |
| | | final LocalizableMessage message = |
| | | ERR_ATTR_SYNTAX_DN_INVALID_REQUIRES_ESCAPE_CHAR.get(reader.getString(), reader.pos()); |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | } |
| | | return bytes; |
| | | } |
| | | |
| | | private static ByteString delimitAndEvaluateEscape(final SubstringReader reader, final boolean isQuoted) { |
| | | final StringBuilder valueBuffer = new StringBuilder(); |
| | | StringBuilder hexBuffer = null; |
| | | boolean escaped = false; |
| | | int trailingSpaces = 0; |
| | | while (reader.remaining() > 0) { |
| | | final char c = reader.read(); |
| | | if (escaped) { |
| | | // This character is escaped. |
| | | if (isHexDigit(c)) { |
| | | // Unicode characters. |
| | | if (reader.remaining() <= 0) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(reader.getString())); |
| | | } |
| | | |
| | | // Check the next byte for hex. |
| | | final char c2 = reader.read(); |
| | | if (isHexDigit(c2)) { |
| | | if (hexBuffer == null) { |
| | | hexBuffer = new StringBuilder(); |
| | | } |
| | | hexBuffer.append(c); |
| | | hexBuffer.append(c2); |
| | | // We may be at the end. |
| | | if (reader.remaining() == 0) { |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | } |
| | | } else { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ESCAPED_HEX_VALUE_INVALID.get(reader.getString())); |
| | | } |
| | | } else { |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.append(c); |
| | | } |
| | | escaped = false; |
| | | } else if (c == '\\') { |
| | | escaped = true; |
| | | trailingSpaces = 0; |
| | | } else if (isQuoted && c == '"') { |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | reader.skipWhitespaces(); |
| | | return ByteString.valueOfUtf8(valueBuffer); |
| | | } else if (!isQuoted && (c == '+' || c == ',' || c == ';')) { |
| | | reader.reset(); |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.setLength(valueBuffer.length() - trailingSpaces); |
| | | return ByteString.valueOfUtf8(valueBuffer); |
| | | } else { |
| | | // It is definitely not a delimiter at this point. |
| | | appendHexChars(reader, valueBuffer, hexBuffer); |
| | | valueBuffer.append(c); |
| | | trailingSpaces = c != ' ' ? 0 : trailingSpaces + 1; |
| | | } |
| | | reader.mark(); |
| | | } |
| | | if (isQuoted) { |
| | | // We hit the end of the AVA before the closing quote. That's an error. |
| | | throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DN_UNMATCHED_QUOTE.get(reader.getString())); |
| | | } |
| | | reader.reset(); |
| | | valueBuffer.setLength(valueBuffer.length() - trailingSpaces); |
| | | return ByteString.valueOfUtf8(valueBuffer); |
| | | } |
| | | |
| | | private static void appendHexChars(final SubstringReader reader, |
| | | final StringBuilder valueBuffer, |
| | | final StringBuilder hexBuffer) { |
| | | if (hexBuffer == null) { |
| | | return; |
| | | } |
| | | final ByteString bytes = ByteString.valueOfHex(hexBuffer.toString()); |
| | | try { |
| | | valueBuffer.append(new String(bytes.toByteArray(), "UTF-8")); |
| | | } catch (final Exception e) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_ATTR_SYNTAX_DN_ATTR_VALUE_DECODE_FAILURE.get(reader.getString(), String.valueOf(e))); |
| | | } |
| | | // Clean up the hex buffer. |
| | | hexBuffer.setLength(0); |
| | | } |
| | | |
| | | private final AttributeType attributeType; |
| | | private final String attributeName; |
| | | private final ByteString attributeValue; |
| | |
| | | import java.util.UUID; |
| | | import java.util.WeakHashMap; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.forgerock.opendj.ldap.schema.CoreSchema; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | |
| | | return ROOT_DN; |
| | | } |
| | | |
| | | RDN rdn; |
| | | final RDN rdn; |
| | | try { |
| | | rdn = RDN.decode(reader, schema); |
| | | } catch (final UnknownSchemaElementException e) { |
| | | final LocalizableMessage message = |
| | | ERR_DN_TYPE_NOT_FOUND.get(reader.getString(), e.getMessageObject()); |
| | | throw new LocalizedIllegalArgumentException(message); |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_DN_TYPE_NOT_FOUND.get(reader.getString(), e.getMessageObject())); |
| | | } |
| | | |
| | | DN parent; |
| | | if (reader.remaining() > 0 && reader.read() == ',') { |
| | | reader.skipWhitespaces(); |
| | | if (reader.remaining() == 0) { |
| | | throw new LocalizedIllegalArgumentException(ERR_ATTR_SYNTAX_DN_ATTR_NO_NAME.get(reader.getString())); |
| | | } |
| | | reader.mark(); |
| | | final String parentString = reader.read(reader.remaining()); |
| | | |
| | | parent = cache.get(parentString); |
| | | DN parent = cache.get(parentString); |
| | | if (parent == null) { |
| | | reader.reset(); |
| | | parent = decode(reader, schema, cache); |
| | | |
| | | // Only cache parent DNs since leaf DNs are likely to make the |
| | | // cache to volatile. |
| | | // Only cache parent DNs since leaf DNs are likely to make the cache to volatile. |
| | | cache.put(parentString, parent); |
| | | } |
| | | return new DN(schema, parent, rdn); |
| | | } else { |
| | | parent = ROOT_DN; |
| | | return new DN(schema, ROOT_DN, rdn); |
| | | } |
| | | |
| | | return new DN(schema, parent, rdn); |
| | | } |
| | | |
| | | @SuppressWarnings("serial") |
| | |
| | | */ |
| | | private ByteString normalizedDN; |
| | | |
| | | /** The RFC 4514 string representation of this DN. */ |
| | | /** |
| | | * The RFC 4514 string representation of this DN. A value of {@code null} |
| | | * indicates that the value needs to be computed lazily. |
| | | */ |
| | | private String stringValue; |
| | | |
| | | /** The schema used to create this DN. */ |
| | |
| | | this.parent = parent; |
| | | this.rdn = rdn; |
| | | this.size = size; |
| | | this.stringValue = rdn == null ? "" : null; // Compute lazily. |
| | | this.stringValue = rdn == null ? "" : null; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_RDN_DUPLICATE_AVA_TYPES; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_RDN_NO_AVAS; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_RDN_TRAILING_GARBAGE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_RDN_TYPE_NOT_FOUND; |
| | | import static org.forgerock.opendj.ldap.DN.AVA_CHAR_SEPARATOR; |
| | | import static org.forgerock.opendj.ldap.DN.RDN_CHAR_SEPARATOR; |
| | | import static org.forgerock.opendj.ldap.DN.NORMALIZED_AVA_SEPARATOR; |
| | | import static org.forgerock.opendj.ldap.DN.NORMALIZED_RDN_SEPARATOR; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_RDN_TYPE_NOT_FOUND; |
| | | import static org.forgerock.opendj.ldap.DN.RDN_CHAR_SEPARATOR; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | |
| | | * A constant holding a special RDN having zero AVAs |
| | | * and which sorts before any RDN other than itself. |
| | | */ |
| | | private static final RDN MIN_VALUE = new RDN(new AVA[0], ""); |
| | | private static final RDN MIN_VALUE = new RDN(); |
| | | /** |
| | | * A constant holding a special RDN having zero AVAs |
| | | * and which sorts after any RDN other than itself. |
| | | */ |
| | | private static final RDN MAX_VALUE = new RDN(new AVA[0], ""); |
| | | private static final RDN MAX_VALUE = new RDN(); |
| | | |
| | | /** |
| | | * Returns a constant containing a special RDN which sorts before any |
| | |
| | | */ |
| | | public static RDN valueOf(final String rdn, final Schema schema) { |
| | | final SubstringReader reader = new SubstringReader(rdn); |
| | | final RDN parsedRdn; |
| | | try { |
| | | return decode(reader, schema); |
| | | parsedRdn = decode(reader, schema); |
| | | } catch (final UnknownSchemaElementException e) { |
| | | throw new LocalizedIllegalArgumentException(ERR_RDN_TYPE_NOT_FOUND.get(rdn, e.getMessageObject())); |
| | | } |
| | | if (reader.remaining() > 0) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_RDN_TRAILING_GARBAGE.get(rdn, reader.read(reader.remaining()))); |
| | | } |
| | | return parsedRdn; |
| | | } |
| | | |
| | | /** FIXME: ensure that the decoded RDN does not contain multiple AVAs with the same type. */ |
| | | static RDN decode(final SubstringReader reader, final Schema schema) { |
| | | final AVA firstAVA = AVA.decode(reader, schema); |
| | | |
| | |
| | | } while (reader.remaining() > 0 && reader.read() == '+'); |
| | | |
| | | reader.reset(); |
| | | return new RDN(avas.toArray(new AVA[avas.size()]), null); |
| | | return new RDN(avas); |
| | | } else { |
| | | reader.reset(); |
| | | return new RDN(new AVA[] { firstAVA }, null); |
| | | return new RDN(firstAVA); |
| | | } |
| | | } |
| | | |
| | |
| | | * The attribute-value assertions used to build this RDN. |
| | | * @throws NullPointerException |
| | | * If {@code avas} is {@code null} or contains a null ava. |
| | | * @throws IllegalArgumentException |
| | | * If {@code avas} is empty. |
| | | */ |
| | | public RDN(final AVA... avas) { |
| | | this(avas, null); |
| | | Reject.ifNull(avas); |
| | | this.avas = validateAvas(avas); |
| | | } |
| | | |
| | | private AVA[] validateAvas(final AVA[] avas) { |
| | | switch (avas.length) { |
| | | case 0: |
| | | throw new LocalizedIllegalArgumentException(ERR_RDN_NO_AVAS.get()); |
| | | case 1: |
| | | // Guaranteed to be valid. |
| | | break; |
| | | case 2: |
| | | if (avas[0].getAttributeType().equals(avas[1].getAttributeType())) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_RDN_DUPLICATE_AVA_TYPES.get(avas[0].getAttributeName())); |
| | | } |
| | | break; |
| | | default: |
| | | final AVA[] sortedAVAs = Arrays.copyOf(avas, avas.length); |
| | | Arrays.sort(sortedAVAs); |
| | | AttributeType previousAttributeType = null; |
| | | for (AVA ava : sortedAVAs) { |
| | | if (ava.getAttributeType().equals(previousAttributeType)) { |
| | | throw new LocalizedIllegalArgumentException( |
| | | ERR_RDN_DUPLICATE_AVA_TYPES.get(ava.getAttributeName())); |
| | | } |
| | | previousAttributeType = ava.getAttributeType(); |
| | | } |
| | | } |
| | | return avas; |
| | | } |
| | | |
| | | /** |
| | |
| | | * The attribute-value assertions used to build this RDN. |
| | | * @throws NullPointerException |
| | | * If {@code ava} is {@code null} or contains null ava. |
| | | * @throws IllegalArgumentException |
| | | * If {@code avas} is empty. |
| | | */ |
| | | public RDN(Collection<AVA> avas) { |
| | | this(avas.toArray(new AVA[avas.size()]), null); |
| | | Reject.ifNull(avas); |
| | | this.avas = validateAvas(avas.toArray(new AVA[avas.size()])); |
| | | } |
| | | |
| | | private RDN(final AVA[] avas, final String stringValue) { |
| | | Reject.ifNull(avas); |
| | | this.avas = avas; |
| | | this.stringValue = stringValue; |
| | | // Special constructor for min/max RDN values. |
| | | private RDN() { |
| | | this.avas = new AVA[0]; |
| | | this.stringValue = ""; |
| | | } |
| | | |
| | | @Override |
| | |
| | | a subschemaSubentry attribute |
| | | ERR_RDN_TYPE_NOT_FOUND=The RDN "%s" could not be parsed due to the \ |
| | | following reason: %s |
| | | ERR_RDN_TRAILING_GARBAGE=The RDN "%s" could not be parsed because it \ |
| | | contained trailing content after the RDN: "%s" |
| | | ERR_RDN_DUPLICATE_AVA_TYPES=An RDN contained multiple components \ |
| | | having the same attribute type "%s" |
| | | ERR_RDN_NO_AVAS=An RDN must contain at least one attribute type and value |
| | | ERR_DN_TYPE_NOT_FOUND=The DN "%s" could not be parsed due to the \ |
| | | following reason: %s |
| | | ERR_ATTRIBUTE_DESCRIPTION_EMPTY=The attribute description \ |
| | |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | | import static java.lang.Integer.*; |
| | | |
| | | import static java.lang.Integer.signum; |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.assertj.core.api.Assertions.fail; |
| | | import static org.assertj.core.api.Assertions.*; |
| | | import static org.testng.Assert.*; |
| | | import static org.testng.Assert.assertEquals; |
| | | import static org.testng.Assert.assertFalse; |
| | | import static org.testng.Assert.assertTrue; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Iterator; |
| | |
| | | */ |
| | | @DataProvider(name = "createChildDNTestData") |
| | | public Object[][] createChildDNTestData() { |
| | | return new Object[][] { { "", "", "" }, { "", "dc=org", "dc=org" }, |
| | | { "", "dc=opendj,dc=org", "dc=opendj,dc=org" }, { "dc=org", "", "dc=org" }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "", "" }, |
| | | { "", "dc=org", "dc=org" }, |
| | | { "", "dc=opendj,dc=org", "dc=opendj,dc=org" }, |
| | | { "dc=org", "", "dc=org" }, |
| | | { "dc=org", "dc=opendj", "dc=opendj,dc=org" }, |
| | | { "dc=org", "dc=foo,dc=opendj", "dc=foo,dc=opendj,dc=org" }, |
| | | { "dc=opendj,dc=org", "", "dc=opendj,dc=org" }, |
| | | { "dc=opendj,dc=org", "dc=foo", "dc=foo,dc=opendj,dc=org" }, |
| | | { "dc=opendj,dc=org", "dc=bar,dc=foo", "dc=bar,dc=foo,dc=opendj,dc=org" }, }; |
| | | { "dc=opendj,dc=org", "dc=bar,dc=foo", "dc=bar,dc=foo,dc=opendj,dc=org" }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createChildRDNTestData") |
| | | public Object[][] createChildRDNTestData() { |
| | | return new Object[][] { { "", "dc=org", "dc=org" }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "dc=org", "dc=org" }, |
| | | { "dc=org", "dc=opendj", "dc=opendj,dc=org" }, |
| | | { "dc=opendj,dc=org", "dc=foo", "dc=foo,dc=opendj,dc=org" }, }; |
| | | { "dc=opendj,dc=org", "dc=foo", "dc=foo,dc=opendj,dc=org" }, |
| | | }; |
| | | // @formatter:on |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "testDNs") |
| | | public Object[][] createData() { |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "", "" }, |
| | | { " ", "", "" }, |
| | |
| | | { "OU= Sales + CN = J. Smith ,DC=example,DC=net", |
| | | "cn=j. smith+ou=sales,dc=example,dc=net", "OU=Sales+CN=J. Smith,DC=example,DC=net" }, |
| | | { "cn=John+dc=", "dc=+cn=john", "cn=John+dc=" }, |
| | | { "O=\"Sue, Grabbit and Runn\",C=US", "o=sue\\, grabbit and runn,c=us", |
| | | "O=Sue\\, Grabbit and Runn,C=US" }, }; |
| | | { "O=\"Sue, Grabbit + Runn\",C=US", "o=sue\\, grabbit \\+ runn,c=us", |
| | | "O=Sue\\, Grabbit \\+ Runn,C=US" }, |
| | | { "O=\"John \\\"Tiger\\\" Smith\",C=US", "o=john \\\"tiger\\\" smith,c=us", |
| | | "O=John \\\"Tiger\\\" Smith,C=US" }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createDNComparisonData") |
| | | public Object[][] createDNComparisonData() { |
| | | return new Object[][] { { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=hello world,dc=com", "CN=hello world,dc=com", 0 }, |
| | | { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { " cn = hello world ,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=hello world\\ ,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=HELLO WORLD,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=HELLO+sn=WORLD,dc=com", "sn=world+cn=hello,dc=com", 0 }, |
| | | /* |
| | | * { "x-test-integer-type=10,dc=com", |
| | | * "x-test-integer-type=9,dc=com", 1 }, { |
| | | * "x-test-integer-type=999,dc=com", |
| | | * "x-test-integer-type=1000,dc=com", -1 }, { |
| | | * "x-test-integer-type=-1,dc=com", "x-test-integer-type=0,dc=com", |
| | | * -1 }, { "x-test-integer-type=0,dc=com", |
| | | * "x-test-integer-type=-1,dc=com", 1 }, |
| | | **/ |
| | | { "governingStructureRule=10,dc=com", "governingStructureRule=9,dc=com", 1 }, |
| | | { "governingStructureRule=999,dc=com", "governingStructureRule=1000,dc=com", -1 }, |
| | | { "governingStructureRule=-1,dc=com", "governingStructureRule=0,dc=com", -1 }, |
| | | { "governingStructureRule=0,dc=com", "governingStructureRule=-1,dc=com", 1 }, |
| | | { "cn=aaa,dc=com", "cn=aaaa,dc=com", -1 }, { "cn=AAA,dc=com", "cn=aaaa,dc=com", -1 }, |
| | | { "cn=aaa,dc=com", "cn=AAAA,dc=com", -1 }, { "cn=aaaa,dc=com", "cn=aaa,dc=com", 1 }, |
| | | { "cn=AAAA,dc=com", "cn=aaa,dc=com", 1 }, { "cn=aaaa,dc=com", "cn=AAA,dc=com", 1 }, |
| | |
| | | { "dc=ccc,dc=aaa", "dc=bbb", -1 }, { "dc=aaa,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=bbb,dc=bbb", "dc=bbb", 1 }, { "dc=ccc,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=aaa,dc=ccc", "dc=bbb", 1 }, { "dc=bbb,dc=ccc", "dc=bbb", 1 }, |
| | | { "dc=ccc,dc=ccc", "dc=bbb", 1 }, { "", "dc=bbb", -1 }, { "dc=bbb", "", 1 } }; |
| | | { "dc=ccc,dc=ccc", "dc=bbb", 1 }, { "", "dc=bbb", -1 }, { "dc=bbb", "", 1 } |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createDNEqualityData") |
| | | public Object[][] createDNEqualityData() { |
| | | return new Object[][] { { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=hello world,dc=com", "CN=hello world,dc=com", 0 }, |
| | | { "cn=hello world,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { " cn = hello world ,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=hello world\\ ,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=HELLO WORLD,dc=com", "cn=hello world,dc=com", 0 }, |
| | | { "cn=HELLO+sn=WORLD,dc=com", "sn=world+cn=hello,dc=com", 0 }, |
| | | { "x-test-integer-type=10,dc=com", "x-test-integer-type=9,dc=com", 1 }, |
| | | { "x-test-integer-type=999,dc=com", "x-test-integer-type=1000,dc=com", -1 }, |
| | | { "x-test-integer-type=-1,dc=com", "x-test-integer-type=0,dc=com", -1 }, |
| | | { "x-test-integer-type=0,dc=com", "x-test-integer-type=-1,dc=com", 1 }, |
| | | { "cn=aaa,dc=com", "cn=aaaa,dc=com", -1 }, { "cn=AAA,dc=com", "cn=aaaa,dc=com", -1 }, |
| | | { "cn=aaa,dc=com", "cn=AAAA,dc=com", -1 }, { "cn=aaaa,dc=com", "cn=aaa,dc=com", 1 }, |
| | | { "cn=AAAA,dc=com", "cn=aaa,dc=com", 1 }, { "cn=aaaa,dc=com", "cn=AAA,dc=com", 1 }, |
| | | { "cn=aaab,dc=com", "cn=aaaa,dc=com", 1 }, { "cn=aaaa,dc=com", "cn=aaab,dc=com", -1 }, |
| | | { "dc=aaa,dc=aaa", "dc=bbb", -1 }, { "dc=bbb,dc=aaa", "dc=bbb", -1 }, |
| | | { "dc=ccc,dc=aaa", "dc=bbb", -1 }, { "dc=aaa,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=bbb,dc=bbb", "dc=bbb", 1 }, { "dc=ccc,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=aaa,dc=ccc", "dc=bbb", 1 }, { "dc=bbb,dc=ccc", "dc=bbb", 1 }, |
| | | { "dc=ccc,dc=ccc", "dc=bbb", 1 }, { "", "dc=bbb", -1 }, { "dc=bbb", "", 1 } }; |
| | | { "governingStructureRule=10,dc=com", "governingStructureRule=9,dc=com", 1 }, |
| | | { "governingStructureRule=999,dc=com", "governingStructureRule=1000,dc=com", -1 }, |
| | | { "governingStructureRule=-1,dc=com", "governingStructureRule=0,dc=com", -1 }, |
| | | { "governingStructureRule=0,dc=com", "governingStructureRule=-1,dc=com", 1 }, |
| | | { "cn=aaa,dc=com", "cn=aaaa,dc=com", -1 }, |
| | | { "cn=AAA,dc=com", "cn=aaaa,dc=com", -1 }, |
| | | { "cn=aaa,dc=com", "cn=AAAA,dc=com", -1 }, |
| | | { "cn=aaaa,dc=com", "cn=aaa,dc=com", 1 }, |
| | | { "cn=AAAA,dc=com", "cn=aaa,dc=com", 1 }, |
| | | { "cn=aaaa,dc=com", "cn=AAA,dc=com", 1 }, |
| | | { "cn=aaab,dc=com", "cn=aaaa,dc=com", 1 }, |
| | | { "cn=aaaa,dc=com", "cn=aaab,dc=com", -1 }, |
| | | { "dc=aaa,dc=aaa", "dc=bbb", -1 }, |
| | | { "dc=bbb,dc=aaa", "dc=bbb", -1 }, |
| | | { "dc=ccc,dc=aaa", "dc=bbb", -1 }, |
| | | { "dc=aaa,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=bbb,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=ccc,dc=bbb", "dc=bbb", 1 }, |
| | | { "dc=aaa,dc=ccc", "dc=bbb", 1 }, |
| | | { "dc=bbb,dc=ccc", "dc=bbb", 1 }, |
| | | { "dc=ccc,dc=ccc", "dc=bbb", 1 }, |
| | | { "", "dc=bbb", -1 }, |
| | | { "dc=bbb", "", 1 } |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "illegalDNs") |
| | | public Object[][] createIllegalData() { |
| | | return new Object[][] { { "manager" }, { "manager " }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "manager" }, |
| | | { "manager " }, |
| | | { "=Jim" }, |
| | | { " =Jim" }, |
| | | { "= Jim" }, |
| | |
| | | { "cn=Jim+" }, |
| | | { "cn=Jim+manager" }, |
| | | { "cn=Jim+manager " }, |
| | | { "cn=Jim+manager," }, // { "cn=Jim," }, { "cn=Jim, " }, { |
| | | // "c[n]=Jim" }, |
| | | { "_cn=Jim" }, { "c_n=Jim" }, { "cn\"=Jim" }, { "c\"n=Jim" }, { "1cn=Jim" }, |
| | | { "cn+uid=Jim" }, { "-cn=Jim" }, { "/tmp=a" }, { "\\tmp=a" }, { "cn;lang-en=Jim" }, |
| | | { "@cn=Jim" }, { "_name_=Jim" }, |
| | | { "cn=Jim+manager," }, |
| | | { "cn=Jim," }, |
| | | { "cn=Jim, " }, |
| | | { "c[n]=Jim" }, |
| | | { "_cn=Jim" }, |
| | | { "c_n=Jim" }, |
| | | { "cn\"=Jim" }, |
| | | { "c\"n=Jim" }, |
| | | { "1cn=Jim" }, |
| | | { "cn+uid=Jim" }, |
| | | { "-cn=Jim" }, |
| | | { "/tmp=a" }, |
| | | { "\\tmp=a" }, |
| | | { "cn;lang-en=Jim" }, |
| | | { "@cn=Jim" }, |
| | | { "_name_=Jim" }, |
| | | { "\u03c0=pi" }, |
| | | { "v1.0=buggy" }, // { "1.=buggy" }, { ".1=buggy" }, |
| | | { "oid.1." }, { "1.3.6.1.4.1.1466..0=#04024869" }, { "cn=#a" }, { "cn=#ag" }, |
| | | { "cn=#ga" }, { "cn=#abcdefgh" }, |
| | | { "cn=a\\b" }, // { "cn=a\\bg" }, { "cn=\"hello" }, |
| | | { "cn=+mail=,dc=example,dc=com" }, { "cn=xyz+sn=,dc=example,dc=com" }, |
| | | { "cn=,dc=example,dc=com" } }; |
| | | { "v1.0=buggy" }, |
| | | { "1.=buggy" }, |
| | | { ".1=buggy" }, |
| | | { "oid.1." }, |
| | | { "1.3.6.1.4.1.1466..0=#04024869" }, |
| | | { "cn=#a" }, |
| | | { "cn=#ag" }, |
| | | { "cn=#ga" }, |
| | | { "cn=#abcdefgh" }, |
| | | { "cn=a\\b" }, |
| | | { "cn=a\\bg" }, |
| | | { "cn=\"hello" }, |
| | | { "cn=+mail=,dc=example,dc=com" }, |
| | | { "cn=xyz+sn=,dc=example,dc=com" }, |
| | | { "cn=,dc=example,dc=com" }, |
| | | { "cn=a+cn=b,dc=example,dc=com" } |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createIsChildOfTestData") |
| | | public Object[][] createIsChildOfTestData() { |
| | | return new Object[][] { { "", "", false }, { "", "dc=org", false }, |
| | | { "", "dc=opendj,dc=org", false }, { "", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=org", "", true }, { "dc=org", "dc=org", false }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "", false }, |
| | | { "", "dc=org", false }, |
| | | { "", "dc=opendj,dc=org", false }, |
| | | { "", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=org", "", true }, |
| | | { "dc=org", "dc=org", false }, |
| | | { "dc=org", "dc=opendj,dc=org", false }, |
| | | { "dc=org", "dc=foo,dc=opendj,dc=org", false }, { "dc=opendj,dc=org", "", false }, |
| | | { "dc=org", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=opendj,dc=org", "", false }, |
| | | { "dc=opendj,dc=org", "dc=org", true }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", false }, |
| | |
| | | { "dc=foo,dc=opendj,dc=org", "dc=org", false }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=opendj,dc=org", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=org", "dc=com", false }, { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, }; |
| | | { "dc=org", "dc=com", false }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createNumComponentsTestData") |
| | | public Object[][] createNumComponentsTestData() { |
| | | return new Object[][] { { "", 0 }, { "dc=com", 1 }, { "dc=opendj,dc=com", 2 }, |
| | | { "dc=world,dc=opendj,dc=com", 3 }, { "dc=hello,dc=world,dc=opendj,dc=com", 4 }, }; |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", 0 }, |
| | | { "dc=com", 1 }, |
| | | { "dc=opendj,dc=com", 2 }, |
| | | { "dc=world,dc=opendj,dc=com", 3 }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 4 }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createParentAndRDNTestData") |
| | | public Object[][] createParentAndRDNTestData() { |
| | | return new Object[][] { { "", null, null }, { "dc=com", "", "dc=com" }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", null, null }, |
| | | { "dc=com", "", "dc=com" }, |
| | | { "dc=opendj,dc=com", "dc=com", "dc=opendj" }, |
| | | { "dc=world,dc=opendj,dc=com", "dc=opendj,dc=com", "dc=world" }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", "dc=world,dc=opendj,dc=com", "dc=hello" }, }; |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", "dc=world,dc=opendj,dc=com", "dc=hello" }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createRDNTestData") |
| | | public Object[][] createRDNTestData() { |
| | | return new Object[][] { { "dc=com", 0, "dc=com" }, { "dc=opendj,dc=com", 0, "dc=opendj" }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "dc=com", 0, "dc=com" }, |
| | | { "dc=opendj,dc=com", 0, "dc=opendj" }, |
| | | { "dc=opendj,dc=com", 1, "dc=com" }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 0, "dc=hello" }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 1, "dc=world" }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 2, "dc=opendj" }, |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 3, "dc=com" }, }; |
| | | { "dc=hello,dc=world,dc=opendj,dc=com", 3, "dc=com" }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createSubordinateTestData") |
| | | public Object[][] createSubordinateTestData() { |
| | | return new Object[][] { { "", "", true }, { "", "dc=org", false }, |
| | | { "", "dc=opendj,dc=org", false }, { "", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=org", "", true }, { "dc=org", "dc=org", true }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "", true }, |
| | | { "", "dc=org", false }, |
| | | { "", "dc=opendj,dc=org", false }, |
| | | { "", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=org", "", true }, |
| | | { "dc=org", "dc=org", true }, |
| | | { "dc=org", "dc=opendj,dc=org", false }, |
| | | { "dc=org", "dc=foo,dc=opendj,dc=org", false }, { "dc=opendj,dc=org", "", true }, |
| | | { "dc=org", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=opendj,dc=org", "", true }, |
| | | { "dc=opendj,dc=org", "dc=org", true }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=org", true }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", false }, |
| | | { "dc=foo,dc=opendj,dc=org", "", true }, { "dc=foo,dc=opendj,dc=org", "dc=org", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=org", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=opendj,dc=org", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=org", "dc=com", false }, { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, }; |
| | | { "dc=org", "dc=com", false }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @DataProvider(name = "createSuperiorTestData") |
| | | public Object[][] createSuperiorTestData() { |
| | | return new Object[][] { { "", "", true }, { "", "dc=org", true }, |
| | | { "", "dc=opendj,dc=org", true }, { "", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=org", "", false }, { "dc=org", "dc=org", true }, |
| | | { "dc=org", "dc=opendj,dc=org", true }, { "dc=org", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=opendj,dc=org", "", false }, { "dc=opendj,dc=org", "dc=org", false }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { "", "", true }, |
| | | { "", "dc=org", true }, |
| | | { "", "dc=opendj,dc=org", true }, |
| | | { "", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=org", "", false }, |
| | | { "dc=org", "dc=org", true }, |
| | | { "dc=org", "dc=opendj,dc=org", true }, |
| | | { "dc=org", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=opendj,dc=org", "", false }, |
| | | { "dc=opendj,dc=org", "dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=org", true }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=foo,dc=opendj,dc=org", "", false }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=org", false }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=opendj,dc=org", false }, |
| | | { "dc=foo,dc=opendj,dc=org", "dc=foo,dc=opendj,dc=org", true }, |
| | | { "dc=org", "dc=com", false }, { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, }; |
| | | { "dc=org", "dc=com", false }, |
| | | { "dc=opendj,dc=org", "dc=foo,dc=org", false }, |
| | | { "dc=opendj,dc=org", "dc=opendj,dc=com", false }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | @Test |
| | |
| | | * @throws Exception |
| | | * If the test failed unexpectedly. |
| | | */ |
| | | @Test(dataProvider = "illegalDNs", expectedExceptions = { |
| | | LocalizedIllegalArgumentException.class, NullPointerException.class }) |
| | | @Test(dataProvider = "illegalDNs", expectedExceptions = LocalizedIllegalArgumentException.class) |
| | | public void testIllegalStringDNs(final String dn) throws Exception { |
| | | DN.valueOf(dn); |
| | | } |
| | | |
| | | @Test(dataProvider = "illegalDNs", expectedExceptions = LocalizedIllegalArgumentException.class) |
| | | public void testIllegalByteStringDNs(final String dn) throws Exception { |
| | | DN.valueOf(ByteString.valueOfUtf8(dn)); |
| | | } |
| | | |
| | | /** |
| | | * Test the isChildOf method. |
| | | * |
| | |
| | | * @throws Exception |
| | | * If the test failed unexpectedly. |
| | | */ |
| | | @Test(expectedExceptions = { NullPointerException.class, AssertionError.class }) |
| | | public void testValueOfString() throws Exception { |
| | | @Test(expectedExceptions = NullPointerException.class) |
| | | public void valueOfStringShouldThrowNPEForNullParameter() { |
| | | DN.valueOf((String) null); |
| | | } |
| | | |
| | |
| | | * @throws Exception |
| | | * If the test failed unexpectedly. |
| | | */ |
| | | @Test(expectedExceptions = { NullPointerException.class, AssertionError.class }) |
| | | public void testValueOfByteString() throws Exception { |
| | | @Test(expectedExceptions = NullPointerException.class) |
| | | public void valueOfByteStringShouldThrowNPEForNullParameter() throws Exception { |
| | | DN.valueOf((ByteString) null); |
| | | } |
| | | |
| | |
| | | assertThat(DN.valueOf(withWhiteSpace).toNormalizedByteString()) |
| | | .isEqualTo(DN.valueOf(withoutWhiteSpace).toNormalizedByteString()); |
| | | } |
| | | |
| | | @DataProvider |
| | | public Object[][] rdnShouldReturnNullWhenIndexIsOutOfRangeData() { |
| | | return new Object[][] { |
| | | { "", 0 }, |
| | | { "", 1 }, |
| | | { "dc=com", 1 }, |
| | | { "dc=opends,dc=com", 2 }, |
| | | { "dc=hello,dc=world,dc=opends,dc=com", 4 }, |
| | | }; |
| | | } |
| | | |
| | | @Test(dataProvider = "rdnShouldReturnNullWhenIndexIsOutOfRangeData") |
| | | public void rdnShouldReturnNullWhenIndexIsOutOfRange(String rdn, int i) { |
| | | assertThat((Object) DN.valueOf(rdn).rdn(i)).isNull(); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void rdnShouldThrowIAEForNegativeIndexes() throws Exception { |
| | | DN.valueOf("dc=example,dc=com").rdn(-1); |
| | | } |
| | | } |
| | |
| | | */ |
| | | @DataProvider(name = "illegalRDNs") |
| | | public Object[][] createIllegalData() { |
| | | return new Object[][] { { null }, { "" }, { " " }, { "=" }, { "manager" }, { "manager " }, |
| | | { "cn+" }, { "cn+Jim" }, |
| | | // @formatter:off |
| | | return new Object[][] { |
| | | { null }, |
| | | { "" }, |
| | | { " " }, |
| | | { "=" }, |
| | | { "manager" }, |
| | | { "manager " }, |
| | | { "cn+" }, |
| | | { "cn+Jim" }, |
| | | { "cn=Jim+" }, |
| | | { "cn=Jim +" }, |
| | | { "cn=Jim+ " }, |
| | | { "cn=Jim+cn=John" }, |
| | | { "cn=Jim+sn" }, |
| | | { "cn=Jim+sn " }, |
| | | { "cn=Jim+sn equals" }, // { "cn=Jim," }, { "cn=Jim;" }, { |
| | | // "cn=Jim, " }, |
| | | // { "cn=Jim+sn=a," }, { "cn=Jim, sn=Jam " }, { "cn+uid=Jim" }, |
| | | { "-cn=Jim" }, { "/tmp=a" }, { "\\tmp=a" }, { "cn;lang-en=Jim" }, { "@cn=Jim" }, |
| | | { "_name_=Jim" }, { "\u03c0=pi" }, { "v1.0=buggy" }, { "cn=Jim+sn=Bob++" }, |
| | | { "cn=Jim+sn=Bob+," }, { "1.3.6.1.4.1.1466..0=#04024869" }, }; |
| | | { "cn=Jim+sn equals" }, |
| | | { "cn=Jim," }, |
| | | { "cn=Jim;" }, |
| | | { "cn=Jim, " }, |
| | | { "cn=Jim+sn=a," }, |
| | | { "cn=Jim, sn=Jam " }, |
| | | { "cn+uid=Jim" }, |
| | | { "-cn=Jim" }, |
| | | { "/tmp=a" }, |
| | | { "\\tmp=a" }, |
| | | { "cn;lang-en=Jim" }, |
| | | { "@cn=Jim" }, |
| | | { "_name_=Jim" }, |
| | | { "\u03c0=pi" }, |
| | | { "v1.0=buggy" }, |
| | | { "cn=Jim+sn=Bob++" }, |
| | | { "cn=Jim+sn=Bob+," }, |
| | | { "1.3.6.1.4.1.1466..0=#04024869" }, |
| | | }; |
| | | // @formatter:on |
| | | } |
| | | |
| | | /** |
| | |
| | | { "cn=hello+sn=world", "cn=hello+description=world", 1 }, |
| | | { "cn=hello", "sn=world", -1 }, |
| | | { "sn=hello", "cn=world", 1 }, |
| | | // { "x-test-integer-type=10", "x-test-integer-type=9", 1 }, |
| | | // { "x-test-integer-type=999", "x-test-integer-type=1000", -1 }, |
| | | // { "x-test-integer-type=-1", "x-test-integer-type=0", -1 }, |
| | | // { "x-test-integer-type=0", "x-test-integer-type=-1", 1 }, |
| | | { "governingStructureRule=10", "governingStructureRule=9", 1 }, |
| | | { "governingStructureRule=999", "governingStructureRule=1000", -1 }, |
| | | { "governingStructureRule=-1", "governingStructureRule=0", -1 }, |
| | | { "governingStructureRule=0", "governingStructureRule=-1", 1 }, |
| | | { "cn=aaa", "cn=aaaa", -1 }, |
| | | { "cn=AAA", "cn=aaaa", -1 }, |
| | | { "cn=aaa", "cn=AAAA", -1 }, |
| | |
| | | return (value instanceof RDN) ? ((RDN) value) : RDN.valueOf(value.toString()); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void ensureRDNIsCreatedWithNonEmptyArguments() { |
| | | new RDN(); |
| | | } |
| | | |
| | | /** |
| | | * Test RDN construction with single AVA. |
| | | * |
| | |
| | | @Test |
| | | public void testConstructorWithMultipleAVAs() throws Exception { |
| | | AVA example = new AVA("dc", "example"); |
| | | AVA org = new AVA("dc", "org"); |
| | | AVA user = new AVA("cn", "bjensen"); |
| | | |
| | | final RDN rdn = new RDN(example, org); |
| | | final RDN rdn = new RDN(example, user); |
| | | assertEquals(rdn.size(), 2); |
| | | Iterator<AVA> rdnIt = rdn.iterator(); |
| | | AVA firstAva = rdnIt.next(); |
| | |
| | | assertEquals(firstAva, example); |
| | | |
| | | AVA secondAva = rdnIt.next(); |
| | | assertEquals(secondAva.getAttributeType(), ATTR_TYPE_DC); |
| | | assertEquals(secondAva, org); |
| | | assertEquals(secondAva.getAttributeType(), ATTR_TYPE_CN); |
| | | assertEquals(secondAva, user); |
| | | } |
| | | |
| | | @Test(expectedExceptions = LocalizedIllegalArgumentException.class) |
| | | public void testConstructorWithDuplicateAVAs() { |
| | | AVA example = new AVA("dc", "example"); |
| | | AVA org = new AVA("dc", "org"); |
| | | new RDN(example, org); |
| | | } |
| | | |
| | | @Test |
| | | public void testConstructorWithCollectionOfAVAs() throws Exception { |
| | | AVA example = new AVA("dc", "example"); |
| | | AVA org = new AVA("dc", "org"); |
| | | AVA user = new AVA("cn", "bjensen"); |
| | | |
| | | final RDN rdn = new RDN(Arrays.asList(example, org)); |
| | | final RDN rdn = new RDN(Arrays.asList(example, user)); |
| | | assertEquals(rdn.size(), 2); |
| | | Iterator<AVA> rdnIt = rdn.iterator(); |
| | | AVA firstAva = rdnIt.next(); |
| | |
| | | assertEquals(firstAva, example); |
| | | |
| | | AVA secondAva = rdnIt.next(); |
| | | assertEquals(secondAva.getAttributeType(), ATTR_TYPE_DC); |
| | | assertEquals(secondAva, org); |
| | | assertEquals(secondAva.getAttributeType(), ATTR_TYPE_CN); |
| | | assertEquals(secondAva, user); |
| | | } |
| | | |
| | | @Test(expectedExceptions = LocalizedIllegalArgumentException.class) |
| | | public void testConstructorWithCollectionOfDuplicateAVAs() { |
| | | AVA example = new AVA("dc", "example"); |
| | | AVA org = new AVA("dc", "org"); |
| | | new RDN(Arrays.asList(example, org)); |
| | | } |
| | | |
| | | /** |