From 47800d82adb5c09fe0fc3bd1e5dd6d7b505c026a Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 16 Mar 2016 20:45:56 +0000
Subject: [PATCH] OPENDJ-2776 Migrate remaining DN/RDN unit tests from the server
---
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java | 82 +++++-
opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties | 5
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java | 71 ++++-
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java | 228 ++++++++----------
opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java | 31 +-
opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java | 287 +++++++++++++++++------
6 files changed, 452 insertions(+), 252 deletions(-)
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
index 34691b7..935053a 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
@@ -176,86 +176,6 @@
}
}
- 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();
@@ -267,7 +187,6 @@
boolean lastWasPeriod = false;
while (reader.remaining() > 0) {
c = reader.read();
-
if (c == '=' || c == ' ') {
// This signals the end of the OID.
break;
@@ -283,29 +202,28 @@
}
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);
}
@@ -333,47 +251,18 @@
// 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();
@@ -433,6 +322,101 @@
}
}
+ 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;
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java
index ad247e0..3a1a44b 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/DN.java
@@ -24,7 +24,6 @@
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;
@@ -263,34 +262,33 @@
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")
@@ -320,7 +318,10 @@
*/
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. */
@@ -337,7 +338,7 @@
this.parent = parent;
this.rdn = rdn;
this.size = size;
- this.stringValue = rdn == null ? "" : null; // Compute lazily.
+ this.stringValue = rdn == null ? "" : null;
}
/**
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java
index 85854ac..5430c05 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RDN.java
@@ -16,12 +16,14 @@
*/
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;
@@ -72,12 +74,12 @@
* 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
@@ -160,14 +162,19 @@
*/
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);
@@ -189,10 +196,10 @@
} 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);
}
}
@@ -251,9 +258,40 @@
* 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;
}
/**
@@ -263,15 +301,18 @@
* 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
diff --git a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
index 27d3ed8..f2cf12d 100644
--- a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
+++ b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
@@ -469,6 +469,11 @@
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 \
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java
index 3d4d714..6c03e6f 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/DNTestCase.java
@@ -16,11 +16,12 @@
*/
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;
@@ -45,13 +46,19 @@
*/
@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
}
/**
@@ -61,9 +68,14 @@
*/
@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
+
}
/**
@@ -73,6 +85,7 @@
*/
@DataProvider(name = "testDNs")
public Object[][] createData() {
+ // @formatter:off
return new Object[][] {
{ "", "", "" },
{ " ", "", "" },
@@ -125,8 +138,12 @@
{ "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
}
/**
@@ -136,22 +153,19 @@
*/
@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 },
@@ -160,7 +174,9 @@
{ "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
}
/**
@@ -170,26 +186,40 @@
*/
@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
}
/**
@@ -199,7 +229,10 @@
*/
@DataProvider(name = "illegalDNs")
public Object[][] createIllegalData() {
- return new Object[][] { { "manager" }, { "manager " },
+ // @formatter:off
+ return new Object[][] {
+ { "manager" },
+ { "manager " },
{ "=Jim" },
{ " =Jim" },
{ "= Jim" },
@@ -209,18 +242,41 @@
{ "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
}
/**
@@ -230,11 +286,17 @@
*/
@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 },
@@ -242,8 +304,11 @@
{ "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
}
/**
@@ -253,8 +318,15 @@
*/
@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
}
/**
@@ -264,10 +336,15 @@
*/
@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
}
/**
@@ -277,12 +354,17 @@
*/
@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
}
/**
@@ -292,19 +374,29 @@
*/
@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
}
/**
@@ -314,19 +406,29 @@
*/
@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
@@ -561,12 +663,16 @@
* @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.
*
@@ -731,8 +837,8 @@
* @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);
}
@@ -742,8 +848,8 @@
* @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);
}
@@ -1266,4 +1372,25 @@
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);
+ }
}
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
index 3d59411..a6d6547 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
@@ -104,19 +104,42 @@
*/
@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
}
/**
@@ -142,10 +165,10 @@
{ "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 },
@@ -195,6 +218,11 @@
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.
*
@@ -238,9 +266,9 @@
@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();
@@ -248,16 +276,23 @@
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();
@@ -265,8 +300,15 @@
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));
}
/**
--
Gitblit v1.10.0