/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. */ package org.opends.server.util; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.opends.server.TestCaseUtils; import org.opends.messages.Message; import org.opends.server.core.DirectoryServer; import org.opends.server.types.*; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * This class defines a set of tests for the * {@link org.opends.server.util.LDIFReader} class. */ public final class TestLDIFReader extends UtilTestCase { // Top object class. private ObjectClass OC_TOP; // Person object class. private ObjectClass OC_PERSON; // Object class attribute type. private AttributeType AT_OC; // Common name attribute type. private AttributeType AT_CN; // Surname attribute type. private AttributeType AT_SN; // Description attribute type. private AttributeType AT_DESCR; // Telephone number attribute type. private AttributeType AT_TELN; // Temporary file containing an attribute value. private File TEMP_FILE = null; // Temporary file content. private static final String TEMP_FILE_STRING = "hello world"; // Temporary file LDIF. private static final String TEMP_FILE_LDIF = "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:< file:///"; /** * String of valid LDIF change records. * * Take from example 6 in the LDIF RFC + a couple of additions. */ private static final String VALID_LDIF = "version: 1\n" + "# Add a new entry\n" + "dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com\n" + "changetype: add\n" + "objectclass: top\n" + "objectclass: person\n" + "objectclass: organizationalPerson\n" + "cn: Fiona Jensen\n" + "sn: Jensen\n" + "uid: fiona\n" + "telephonenumber: +1 408 555 1212\n" + "\n" + "# Delete an existing entry\n" + "dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com\n" + "changetype: delete\n" + "\n" + "# Modify an entry's relative distinguished name\n" + "dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=Paula Jensen\n" + "deleteoldrdn: 1\n" + "\n" + "# Rename an entry and move all of its children to a new location in\n" + "# the directory tree (only implemented by LDAPv3 servers).\n" + "dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com\n" + "changetype: modrdn\n" + "newrdn: ou=Product Development Accountants\n" + "deleteoldrdn: 0\n" + "newsuperior: ou=Accounting, dc=airius, dc=com\n" + "\n" + "# Modify an entry: add an additional value to the postaladdress\n" + "# attribute, completely delete the description attribute, replace\n" + "# the telephonenumber attribute with two values, and delete a specific\n" + "# value from the facsimiletelephonenumber attribute\n" + "dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com\n" + "changetype: modify\n" + "add: postaladdress\n" + "postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086\n" + "-\n" + "delete: description\n" + "-\n" + "replace: telephonenumber\n" + "telephonenumber: +1 408 555 1234\n" + "telephonenumber: +1 408 555 5678\n" + "-\n" + "delete: facsimiletelephonenumber\n" + "facsimiletelephonenumber: +1 408 555 9876\n" + "-\n" + "\n" + "# Modify an entry: replace the postaladdress attribute with an empty\n" + "# set of values (which will cause the attribute to be removed), and\n" + "# delete the entire description attribute. Note that the first will\n" + "# always succeed, while the second will only succeed if at least\n" + "# one value for the description attribute is present.\n" + "dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com\n" + "changetype: modify\n" + "replace: postaladdress\n" + "-\n" + "delete: description\n" + "-\n" + "\n" + "# Modify rootDSE.\n" + "dn: \n" + "changetype: modify\n" + "delete: description\n" + "-\n" + "\n" + "# Modify base64 DN.\n" + "dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz\n" + "# dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius\n" + "changetype:: bW9kaWZ5\n" + "delete: description\n" + "-\n" + "\n"; /** * Once-only initialization. * * @throws Exception * If an unexpected error occurred. */ @BeforeClass public void setUp() throws Exception { // This test suite depends on having the schema available, so we'll // start the server. TestCaseUtils.startServer(); // Initialize schema bits. OC_TOP = DirectoryServer.getObjectClass("top"); OC_PERSON = DirectoryServer.getObjectClass("person"); AT_OC = DirectoryServer.getObjectClassAttributeType(); AT_CN = DirectoryServer.getAttributeType("cn"); AT_SN = DirectoryServer.getAttributeType("sn"); AT_DESCR = DirectoryServer.getAttributeType("description"); AT_TELN = DirectoryServer.getAttributeType("telephonenumber"); // Create a temporary file containing an attribute value. TEMP_FILE = File.createTempFile("tmp", "txt"); OutputStream out = null; try { out = new FileOutputStream(TEMP_FILE); out.write(TEMP_FILE_STRING.getBytes("UTF-8")); } finally { if (out != null) { out.close(); } } } /** * Once-only tear-down. * * @throws Exception * If an unexpected error occurred. */ @AfterClass public void tearDown() throws Exception { if (TEMP_FILE != null) { TEMP_FILE.delete(); } } /** * Check the initial state of an LDIF reader. * * @throws Exception * If the test failed unexpectedly. */ @Test public void testInitialState() throws Exception { LDIFReader reader = createLDIFReader(""); try { Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 0); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), -1); } finally { reader.close(); } } /** * Attempt to read an entry from an empty LDIF stream. * * @throws Exception * If the test failed unexpectedly. */ @Test public void testReadEntryEmptyStream() throws Exception { LDIFReader reader = createLDIFReader(""); try { Entry entry = reader.readEntry(); Assert.assertNull(entry); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 0); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), -1); } finally { reader.close(); } } /** * Attempt to read an entry from an empty LDIF stream containing just * the LDIF version. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadEntryEmptyStream" }) public void testReadEntryEmptyStreamVersion() throws Exception { LDIFReader reader = createLDIFReader("version: 1\n"); try { Entry entry = reader.readEntry(); Assert.assertNull(entry); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 0); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), 1); } finally { reader.close(); } } /** * Attempt to read a change record from an empty LDIF stream. * * @throws Exception * If the test failed unexpectedly. */ @Test public void testChangeRecordEmptyStream() throws Exception { LDIFReader reader = createLDIFReader(""); try { ChangeRecordEntry change = reader.readChangeRecord(true); Assert.assertNull(change); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 0); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), -1); } finally { reader.close(); } } /** * Attempt to read a single entry. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadEntryEmptyStream" }) public void testReadEntrySingle() throws Exception { final String ldifString = "dn: cn=john, dc=foo, dc=com\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n"; LDIFReader reader = createLDIFReader(ldifString); try { Entry entry = reader.readEntry(); Assert.assertNotNull(entry); Assert.assertEquals(entry.getDN(), DN .decode("cn=john, dc=foo, dc=com")); Assert.assertTrue(entry.hasObjectClass(OC_TOP)); Assert.assertTrue(entry.hasObjectClass(OC_PERSON)); Assert.assertTrue(entry.hasValue(AT_CN, null, AttributeValues.create( AT_CN, "john"))); Assert.assertTrue(entry.hasValue(AT_SN, null, AttributeValues.create( AT_SN, "smith"))); Assert.assertNull(reader.readEntry()); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 1); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), 1); } finally { reader.close(); } } /** * Attempt to read an entry containing a folded line. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadEntrySingle" }) public void testReadEntryFoldedLine() throws Exception { final String ldifString = "dn: cn=john, dc=foo, dc=com\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description: once upon a time\n" + " in the west\n"; LDIFReader reader = createLDIFReader(ldifString); try { Entry entry = reader.readEntry(); Assert.assertNotNull(entry); Assert.assertTrue(entry.hasValue(AT_DESCR, null, AttributeValues.create( AT_DESCR, "once upon a time in the west"))); } finally { reader.close(); } } /** * Attempt to read an entry containing a base64 line. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadEntrySingle" }) public void testReadEntryBase64() throws Exception { final String ldifString = "dn: cn=john, dc=foo, dc=com\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:: b25jZSB1cG9uIGEgdGltZSBpbiB0aGUgd2VzdA==\n"; LDIFReader reader = createLDIFReader(ldifString); try { Entry entry = reader.readEntry(); Assert.assertNotNull(entry); Assert.assertTrue(entry.hasValue(AT_DESCR, null, AttributeValues.create( AT_DESCR, "once upon a time in the west"))); } finally { reader.close(); } } /** * Attempt to read multiple entries. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadEntrySingle" }) public void testReadEntryMultiple() throws Exception { final String ldifString = "dn: cn=john, dc=foo, dc=com\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "\n" + "dn: cn=anne, dc=foo, dc=com\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: anne\n" + "sn: other\n" + "\n"; LDIFReader reader = createLDIFReader(ldifString); try { reader.readEntry(); Entry entry = reader.readEntry(); Assert.assertNotNull(entry); Assert.assertEquals(entry.getDN(), DN .decode("cn=anne, dc=foo, dc=com")); Assert.assertTrue(entry.hasObjectClass(OC_TOP)); Assert.assertTrue(entry.hasObjectClass(OC_PERSON)); Assert.assertTrue(entry.hasValue(AT_CN, null, AttributeValues.create( AT_CN, "anne"))); Assert.assertTrue(entry.hasValue(AT_SN, null, AttributeValues.create( AT_SN, "other"))); Assert.assertNull(reader.readEntry()); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 2); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), 7); } finally { reader.close(); } } /** * Attempt to read multiple changes. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testChangeRecordEmptyStream" }) public void testReadChangeMultiple() throws Exception { LDIFReader reader = createLDIFReader(VALID_LDIF); try { ChangeRecordEntry change; AddChangeRecordEntry add; DeleteChangeRecordEntry delete; ModifyChangeRecordEntry modify; ModifyDNChangeRecordEntry modifyDN; DN dn; RDN rdn; Iterator<RawModification> i; Modification mod; Attribute attr; // Change record #1. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof AddChangeRecordEntry); add = (AddChangeRecordEntry) change; dn = DN.decode("cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com"); Assert.assertEquals(add.getDN(), dn); List<Attribute> attrs = new ArrayList<Attribute>(); AttributeBuilder builder = new AttributeBuilder(AT_OC, "objectclass"); builder.add(AttributeValues.create(AT_OC, "top")); builder.add(AttributeValues.create(AT_OC, "person")); builder.add(AttributeValues.create(AT_OC, "organizationalPerson")); attrs.add(builder.toAttribute()); attrs.add(Attributes.create("cn", "Fiona Jensen")); attrs.add(Attributes.create("sn", "Jensen")); attrs.add(Attributes.create("uid", "fiona")); attrs.add(Attributes.create("telephonenumber", "+1 408 555 1212")); Assert.assertTrue(add.getAttributes().containsAll(attrs)); // Change record #2. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof DeleteChangeRecordEntry); delete = (DeleteChangeRecordEntry) change; dn = DN.decode("cn=Robert Jensen, ou=Marketing, dc=airius, dc=com"); Assert.assertEquals(delete.getDN(), dn); // Change record #3. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyDNChangeRecordEntry); modifyDN = (ModifyDNChangeRecordEntry) change; dn = DN .decode("cn=Paul Jensen, ou=Product Development, dc=airius, dc=com"); Assert.assertEquals(modifyDN.getDN(), dn); rdn = RDN.decode("cn=paula jensen"); Assert.assertEquals(modifyDN.getNewRDN(), rdn); Assert.assertNull(modifyDN.getNewSuperiorDN()); Assert.assertTrue(modifyDN.deleteOldRDN()); // Change record #4. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyDNChangeRecordEntry); modifyDN = (ModifyDNChangeRecordEntry) change; dn = DN .decode("ou=PD Accountants, ou=Product Development, dc=airius, dc=com"); Assert.assertEquals(modifyDN.getDN(), dn); rdn = RDN.decode("ou=Product Development Accountants"); Assert.assertEquals(modifyDN.getNewRDN(), rdn); dn = DN.decode("ou=Accounting, dc=airius, dc=com"); Assert.assertEquals(modifyDN.getNewSuperiorDN(), dn); Assert.assertFalse(modifyDN.deleteOldRDN()); // Change record #5. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyChangeRecordEntry); modify = (ModifyChangeRecordEntry) change; dn = DN .decode("cn=Paula Jensen, ou=Product Development, dc=airius, dc=com"); Assert.assertEquals(modify.getDN(), dn); i = modify.getModifications().iterator(); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.ADD); attr = Attributes.create("postaladdress", "123 Anystreet $ Sunnyvale, CA $ 94086"); Assert.assertEquals(mod.getAttribute(), attr); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.DELETE); attr = Attributes.empty(AT_DESCR); Assert.assertEquals(mod.getAttribute(), attr); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.REPLACE); builder = new AttributeBuilder(AT_TELN, "telephonenumber"); builder.add(AttributeValues.create(AT_TELN, "+1 408 555 1234")); builder.add(AttributeValues.create(AT_TELN, "+1 408 555 5678")); Assert.assertEquals(mod.getAttribute(), builder.toAttribute()); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.DELETE); attr = Attributes.create("facsimiletelephonenumber", "+1 408 555 9876"); Assert.assertEquals(mod.getAttribute(), attr); Assert.assertFalse(i.hasNext()); // Change record #6. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyChangeRecordEntry); modify = (ModifyChangeRecordEntry) change; dn = DN .decode("cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com"); Assert.assertEquals(modify.getDN(), dn); i = modify.getModifications().iterator(); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.REPLACE); attr = Attributes.empty(DirectoryServer .getAttributeType("postaladdress")); Assert.assertEquals(mod.getAttribute(), attr); // Change record #7. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyChangeRecordEntry); modify = (ModifyChangeRecordEntry) change; Assert.assertTrue(modify.getDN().isNullDN()); i = modify.getModifications().iterator(); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.DELETE); attr = Attributes.empty(AT_DESCR); Assert.assertEquals(mod.getAttribute(), attr); // Change record #8. change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof ModifyChangeRecordEntry); modify = (ModifyChangeRecordEntry) change; dn = DN.decode("uid=rogasawara, ou=\u55b6\u696d\u90e8, o=airius"); Assert.assertEquals(modify.getDN(), dn); i = modify.getModifications().iterator(); Assert.assertTrue(i.hasNext()); mod = i.next().toModification(); Assert.assertEquals(mod.getModificationType(), ModificationType.DELETE); attr = Attributes.empty(AT_DESCR); Assert.assertEquals(mod.getAttribute(), attr); Assert.assertFalse(i.hasNext()); // Check final state. Assert.assertNull(reader.readChangeRecord(false)); Assert.assertEquals(reader.getEntriesIgnored(), 0); Assert.assertEquals(reader.getEntriesRead(), 0); Assert.assertEquals(reader.getEntriesRejected(), 0); Assert.assertEquals(reader.getLastEntryLineNumber(), 72); } finally { reader.close(); } } /** * Attempt to read multiple changes and rejects one. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadChangeMultiple" }) public void testReadChangeMultipleAndReject() throws Exception { LDIFReader reader = createLDIFReader(VALID_LDIF); try { reader.readChangeRecord(false); reader.readChangeRecord(false); reader.readChangeRecord(false); reader.readChangeRecord(false); reader.rejectLastEntry(Message.raw("Rejected")); reader.readChangeRecord(false); reader.rejectLastEntry(Message.raw("Rejected")); reader.readChangeRecord(false); reader.readChangeRecord(false); reader.readChangeRecord(false); // Check final state. Assert.assertNull(reader.readChangeRecord(false)); Assert.assertEquals(reader.getEntriesRejected(), 2); } finally { reader.close(); } } /** * Attempt to read a change containing a file-based attribute. * * @throws Exception * If the test failed unexpectedly. */ @Test(dependsOnMethods = { "testReadChangeMultiple" }) public void testReadChangeWithFileBaseAttribute() throws Exception { StringBuilder buffer = new StringBuilder(TEMP_FILE_LDIF); buffer.append(TEMP_FILE.getCanonicalPath()); buffer.append("\n"); LDIFReader reader = createLDIFReader(buffer.toString()); try { ChangeRecordEntry change = reader.readChangeRecord(false); Assert.assertTrue(change instanceof AddChangeRecordEntry); AddChangeRecordEntry add = (AddChangeRecordEntry) change; DN dn = DN.decode("cn=john smith, dc=com"); Assert.assertEquals(add.getDN(), dn); Attribute attr = Attributes.create("description", TEMP_FILE_STRING); Assert.assertTrue(add.getAttributes().contains(attr)); // Check final state. Assert.assertNull(reader.readChangeRecord(false)); } finally { reader.close(); } } /** * LDIF change reader - invalid data provider. * * @return Returns an array of invalid LDIF change records. */ @DataProvider(name = "invalidLDIFChangeRecords") public Object[][] createInvalidLDIFChangeRecords() { return new Object[][] { { "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { ": cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "x: cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: foo\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn,=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "chaxxngetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: foo\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype:: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + ": add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype:\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "xxxx\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectClass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "cn: john\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + ": top\n" + "objectClass: person\n" + "cn: john\n" + "objectClass: person\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:: YnJva2VuIGJhc2U2NA*==" }, { "dn:: YnJva2VuIGJhc2U2NA*==" + "changetype: add\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn:: Y249YnJva2VuIGJhc2U2NCBkbix4" + "changetype: add\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:< brok@n:///bad/url" }, { "dn: cn=john smith, dc=com\n" + "changetype: add\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:< file:///bad/path/name" }, { "dn: cn=john smith, dc=com\n" + "changetype: delete\n" + "objectclass: top\n" + "objectClass: person\n" + "cn: john\n" + "sn: smith\n" + "description:< file:///bad/path/name" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: x\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=foo\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=foo\n" + "deleteoldxx: xxx\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=foo\n" + "deleteoldrdn: xxx\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=foo\n" + "deleteoldrdn: 0\n" + "newsu: xxxx\n" }, { "dn: cn=john smith, dc=com\n" + "changetype: modrdn\n" + "newrdn: cn=foo\n" + "deleteoldrdn: 0\n" + "newsuperior: xxxx\n" }, }; } /** * Tests the read change record method against invalid LDIF records. * * @param ldifString * The invalid LDIF change record. * @throws Exception * If the test failed unexpectedly. */ @Test(dataProvider = "invalidLDIFChangeRecords", expectedExceptions = { LDIFException.class }) public void testReadChangeInvalidData(String ldifString) throws Exception { LDIFReader reader = createLDIFReader(ldifString); ChangeRecordEntry change = null; try { change = reader.readChangeRecord(false); } finally { reader.close(); } Assert.fail("Expected exception but got result: " + change.getChangeOperationType() + " - " + change.getDN()); } /** * Create an LDIF reader from a string of LDIF. * * @param ldifString * The string of LDIF. * * @return Returns the LDIF reader. * @throws Exception * If an error occurred. */ private LDIFReader createLDIFReader(String ldifString) throws Exception { byte[] bytes = StaticUtils.getBytes(ldifString); LDIFReader reader = new LDIFReader(new LDIFImportConfig( new ByteArrayInputStream(bytes))); return reader; } }