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

Gaetan Boismal
23.30.2016 caf74d75e44a4769e6d4489970838703eedb745f
OPENDJ-2272 OPENDJ-2773 Tools unit tests migration

Unit tests which were present in opendj-server-legacy have been migrated
into QA as part of a functionnal suite since they were integration
tests.

For ldap* tools, create some unit tests in opendj-ldap-toolkit with a
fake server to test simple use cases and ensure that tools are not
broken.
For ldif* tools, migrate opendj-server-legacy unit tests (and their
resources) into opendj-ldap-toolkit in order to keep a good coverage for
allowed arguments.
8 files copied
12 files deleted
21 files added
21 files renamed
7 files modified
12602 ■■■■ changed files
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/Utils.java 1 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ArgumentParserToolsTestCase.java 140 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/Base64TestCase.java 252 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java 3 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareTestCase.java 197 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPDeleteTestCase.java 140 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPModifyTestCase.java 288 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModifyTestCase.java 160 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java 3 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchTestCase.java 267 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPToolsTestCase.java 101 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFDiffTestCase.java 214 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFModifyTestCase.java 145 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFSearchTestCase.java 224 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/MakeLDIFITCase.java 31 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolLdapServer.java 170 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestCase.java 66 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestUtils.java 140 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-emptytosingle.ldif 1 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-ignore-attributes.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-ignore-entries.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-reverse-singlevalue.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-reverse.ldif 37 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-singlevalue.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries.ldif 30 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle-reverse-singlevalue.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle-reverse.ldif 26 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle.ldif 14 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-nochanges.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singleentry-reverse.ldif 2 ●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singleentry.ldif 2 ●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletoempty.ldif 2 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-no-wrapping.ldif 17 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-reverse.ldif 10 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-singlevalue.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple.ldif 17 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/ignore-attributes patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/ignore-entries patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-empty.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-multipleentries.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-singleentry.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-empty.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-multipleentries.ldif 1 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-singleentry.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-continue-on-error.ldif 6 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-no-wrapping.ldif 5 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected.ldif 6 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications-invalid.ldif 3 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications-with-error.ldif 40 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications.ldif 34 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_1.ldif 17 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_2.ldif 15 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_3.ldif 14 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifmodify/source.ldif patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/resources/ldifsearch.ldif 523 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/pom.xml 1 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPCompareTestCase.java 1632 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPDeleteTestCase.java 936 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPModifyTestCase.java 1905 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPPasswordModifyTestCase.java 1124 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPSearchNoServerTestCase.java 57 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPSearchTestCase.java 2464 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDIFDiffTestCase.java 782 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/tools/LDIFSearchTestCase.java 200 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries-reverse.ldif 58 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipletosingle-reverse.ldif 42 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipletosingle.ldif 29 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletoempty.ldif 6 ●●●●● patch | view | raw | blame | history
pom.xml 2 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/Utils.java
@@ -291,6 +291,7 @@
                while ((line = reader.readLine()) != null) {
                    filesLines.add(line);
                }
                filesLines.add("");
            } catch (final IOException e) {
                throw newToolParamException(
                        e, ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(filePath, e.getLocalizedMessage()));
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ArgumentParserToolsTestCase.java
New file
@@ -0,0 +1,140 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.INFO_GLOBAL_HELP_REFERENCE;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS;
import static com.forgerock.opendj.ldap.tools.Utils.runTool;
import static org.assertj.core.api.Assertions.assertThat;
import static org.forgerock.opendj.ldap.ResultCode.CLIENT_SIDE_PARAM_ERROR;
import static org.forgerock.util.Utils.closeSilently;
import java.io.PrintStream;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.testng.ForgeRockTestCase;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * This class tests that help reference message is prompted for all tools when
 * no arguments are provided or if they failed to be parsed.
 */
@Test
public class ArgumentParserToolsTestCase extends ForgeRockTestCase {
    ByteStringBuilder out;
    ByteStringBuilder err;
    PrintStream outStream;
    PrintStream errStream;
    @BeforeMethod
    void refreshStream() {
        out = new ByteStringBuilder();
        err = new ByteStringBuilder();
        outStream = new PrintStream(out.asOutputStream());
        errStream = new PrintStream(err.asOutputStream());
    }
    @AfterMethod
    void closeStream() {
        closeSilently(outStream, errStream);
    }
    String errOnSingleLine() {
        return err.toString().replace(System.lineSeparator(), " ");
    }
    @DataProvider
    public Object[][] invalidArg() throws Exception {
        return new Object[][] { { new String[] { "-42" } } };
    }
    @DataProvider
    public Object[][] invalidArgs() throws Exception {
        return new Object[][] { { new String[] {} }, { new String[] { "-42" } } };
    }
    @Test(dataProvider = "invalidArg")
    public void testBase64(final String[] args) throws LDAPToolException {
        assertThat(runTool(new Base64(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArgs")
    public void testLDAPCompare(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDAPCompare(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArg")
    public void testLDAPDelete(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDAPDelete(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArg")
    public void testLDAPModify(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDAPModify(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArg")
    public void testLDAPPasswordModify(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDAPPasswordModify(outStream, errStream), args))
                  .isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArgs")
    public void testLDAPSearch(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDAPSearch(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArgs")
    public void testLDIFDiff(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDIFDiff(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArgs")
    public void testLDIFModify(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDIFModify(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArg")
    public void testLDIFSearch(final String[] args) throws LDAPToolException {
        assertThat(runTool(new LDIFSearch(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    @Test(dataProvider = "invalidArg")
    public void testMakeLdif(final String[] args) throws LDAPToolException {
        assertThat(runTool(new MakeLDIF(outStream, errStream), args)).isEqualTo(CLIENT_SIDE_PARAM_ERROR.intValue());
        assertToolFailsWithUsage();
    }
    private void assertToolFailsWithUsage() {
        assertThat(out.toString()).isEmpty();
        final String streamToCheck = errOnSingleLine();
        assertThat(streamToCheck).matches(".*" + INFO_GLOBAL_HELP_REFERENCE.get("(.*)") + ".*");
        assertThat(streamToCheck).contains(ERR_ERROR_PARSING_ARGS.get(""));
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/Base64TestCase.java
New file
@@ -0,0 +1,252 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_FILEARG_NO_SUCH_FILE;
import static com.forgerock.opendj.cli.CliMessages.ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID;
import static com.forgerock.opendj.cli.CliMessages.ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID;
import static com.forgerock.opendj.cli.CliMessages.ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_BASE64_DECODE_INVALID_LENGTH;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_BASE64_ERROR_DECODING_RAW_DATA;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ResultCode;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** This class defines a set of tests for the {@link com.forgerock.opendj.ldap.tools.Base64} class. */
@Test
public final class Base64TestCase extends ToolsTestCase {
    private static final boolean ENCODE = true;
    private static final boolean DECODE = false;
    @BeforeMethod
    private void testSetup() {
        refreshStream();
    }
    @AfterMethod
    private void testTearDown() {
        closeStream();
    }
    @Test
    public void testNoSubcommandProvided() throws Exception {
        final int res = runTool();
        assertThat(res).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(err.toString()).contains(ToolsMessages.ERR_BASE64_NO_SUBCOMMAND_SPECIFIED.get().toString());
        assertThat(out.toString()).isEmpty();
    }
    @DataProvider
    public Object[][] invalidArgumentsEncode() throws Exception {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        addValueNeededShortArgs(argLists, reasonList, "d", "f", "o");
        argLists.add(args("-I"));
        reasonList.add(ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get("I"));
        argLists.add(args("--invalidLongArgument"));
        reasonList.add(ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID.get("invalidLongArgument"));
        argLists.add(args("--rawData"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("rawdata"));
        argLists.add(args("--rawDataFile"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("rawdatafile"));
        argLists.add(args("--toEncodedFile"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("toencodedfile"));
        argLists.add(args("-f", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "rawDataFile"));
        argLists.add(args("--rawDataFile", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "rawDataFile"));
        return toDataProviderArray(argLists, reasonList);
    }
    @Override
    @Test(dataProvider = "invalidArgumentsEncode")
    public void testInvalidArguments(final String[] args, String invalidReason) throws LDAPToolException {
        assertThat(testBase64(ENCODE, args)).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(invalidReason);
        assertThat(out.toString()).isEmpty();
    }
    @DataProvider
    public Object[][] invalidArgumentsDecode() throws Exception {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        addValueNeededShortArgs(argLists, reasonList, "d", "f", "o");
        argLists.add(args("-I"));
        reasonList.add(ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get("I"));
        argLists.add(args("--invalidLongArgument"));
        reasonList.add(ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID.get("invalidLongArgument"));
        argLists.add(args("--encodedData"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("encodeddata"));
        argLists.add(args("--encodedDataFile"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("encodeddatafile"));
        argLists.add(args("--toRawFile"));
        reasonList.add(ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get("torawfile"));
        argLists.add(args("-f", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "encodedDataFile"));
        argLists.add(args("--encodedDataFile", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "encodedDataFile"));
        return toDataProviderArray(argLists, reasonList);
    }
    @DataProvider
    public Object[][] invalidEncodedDataLength() {
        // FIXME: fix cases ==== and ==x=
        return new Object[][] { { "=" }, { "==" }, { "===" }, { "A" }, { "AA" }, { "AAA" } };
    }
    @Test(dataProvider = "invalidEncodedDataLength")
    public void testDecodeInvalidDataLength(final String encodedData) throws Exception {
        final int res = testBase64(DECODE, "-d", encodedData);
        assertThat(res).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(ERR_BASE64_DECODE_INVALID_LENGTH.get(encodedData));
        assertThat(out.toString()).isEmpty();
    }
    @DataProvider
    public Object[][] invalidEncodedData() {
        return new Object[][] {
            { "AA`=" }, { "AA~=" }, { "AA!=" }, { "AA@=" },
            { "AA#=" }, { "AA$=" }, { "AA%=" }, { "AA^=" },
            { "AA*=" }, { "AA(=" }, { "AA)=" }, { "AA_=" },
            { "AA-=" }, { "AA{=" }, { "AA}=" }, { "AA|=" },
            { "AA[=" }, { "AA]=" }, { "AA\\=" }, { "AA;=" },
            { "AA'=" }, { "AA\"=" }, { "AA:=" }, { "AA,=" },
            { "AA.=" }, { "AA<=" }, { "AA>=" }, { "AA?=" },
            { "AA;=" }
        };
    }
    @Test(dataProvider = "invalidEncodedData")
    public void testDecodeInvalidData(final String encodedData) throws Exception {
        final int res = testBase64(DECODE, "-d", encodedData);
        assertThat(res).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(ERR_BASE64_ERROR_DECODING_RAW_DATA.get(encodedData));
        assertThat(out.toString()).isEmpty();
    }
    /**
     * Base 64 valid test data provider.
     *
     * @return Returns an array of decoded and valid encoded base64 data.
     */
    @DataProvider
    public Object[][] validData() {
        return new Object[][] {
            { "dont panic", "ZG9udCBwYW5pYw==" },
            { "Time is an illusion. Lunchtime doubly so.",
              "VGltZSBpcyBhbiBpbGx1c2lvbi4gTHVuY2h0aW1lIGRvdWJseSBzby4=" },
            { "I would far rather be happy than right any day.",
              "SSB3b3VsZCBmYXIgcmF0aGVyIGJlIGhhcHB5IHRoYW4gcmlnaHQgYW55IGRheS4=" },
            { "This must be Thursday, said Arthur to himself, sinking low over his beer. "
                      + "I never could get the hang of Thursdays",
              "VGhpcyBtdXN0IGJlIFRodXJzZGF5LCBzYWlkIEFydGh1ciB0byBoaW1zZWxmLCBzaW5raW5nIGxvdyBvdmVyIGhpcyBiZWVy"
                      + "LiBJIG5ldmVyIGNvdWxkIGdldCB0aGUgaGFuZyBvZiBUaHVyc2RheXM=" },
        };
    }
    @Test(dataProvider = "validData")
    public void testEncodeRawData(final String clearData, final String encodedData) throws Exception {
        testValidData(ENCODE, clearData, encodedData);
    }
    @Test(dataProvider = "validData")
    public void testDecodeRawData(final String encodedData, final String clearData) throws Exception {
        testValidData(DECODE, clearData, encodedData);
    }
    @Test(dataProvider = "validData")
    public void testEncodeDataWithFiles(final String clearData, final String encodedData) throws Exception {
        testValidDataWithFiles(ENCODE, clearData, encodedData);
    }
    @Test(dataProvider = "validData")
    public void testDecodeDataWithFiles(final String encodedData, final String clearData) throws Exception {
        testValidDataWithFiles(DECODE, clearData, encodedData);
    }
    private void testValidData(final boolean mode, final String dataIn, final String dataOut) throws LDAPToolException {
        final int res = testBase64(mode, "-d", dataIn);
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        assertThat(out.toString()).contains(dataOut);
    }
    private void testValidDataWithFiles(final boolean mode, final String dataIn, final String dataOut)
            throws Exception {
        final File dataInFile = File.createTempFile("Base64TestCase", ".data");
        Files.write(dataInFile.toPath(), dataIn.getBytes());
        final String dataOutFilePath = ToolsTestUtils.createTempFile();
        final int res = testBase64(mode, "-f", dataInFile.getAbsolutePath(), "-o", dataOutFilePath);
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        assertThat(out.toString()).isEmpty();
        assertThat(err.toString()).isEmpty();
        assertThat(readFirstLine(dataOutFilePath)).isEqualTo(dataOut);
    }
    private String readFirstLine(final String resultFilePath) throws IOException {
        try (final BufferedReader reader = new BufferedReader(new FileReader(resultFilePath))) {
            return reader.readLine();
        }
    }
    private Integer testBase64(final boolean encode, final String... args) throws LDAPToolException {
        final List<String> arguments = new ArrayList<>();
        arguments.add(encode ? "encode" : "decode");
        arguments.addAll(Arrays.asList(args));
        return runTool(arguments.toArray(new String[arguments.size()]));
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new Base64(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java
@@ -19,6 +19,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_COMPARE_OPERATION_RESULT_FALSE;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_COMPARE_OPERATION_RESULT_TRUE;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_LDAPCOMPARE_TOOL_DESCRIPTION;
import static com.forgerock.opendj.ldap.tools.Utils.runTool;
import java.io.PrintStream;
import java.util.Random;
@@ -85,7 +86,7 @@
        try (PrintStream outStream = new PrintStream(out.asOutputStream());
             PrintStream errStream = new PrintStream(err.asOutputStream())) {
            LDAPCompare.run(outStream, errStream, arguments);
            runTool(new LDAPCompare(outStream, errStream), arguments);
            checkOuputStreams(out, err, expectedOut, expectedErr);
        } catch (final LDAPToolException ae) {
            checkOuputStreams(out, err, expectedOut, expectedErr);
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareTestCase.java
New file
@@ -0,0 +1,197 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions Copyright 2013-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static com.forgerock.opendj.cli.CliMessages.ERR_FILEARG_NO_SUCH_FILE;
import static com.forgerock.opendj.cli.CliMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static com.forgerock.opendj.cli.CliMessages.ERR_TOOL_CONFLICTING_ARGS;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_FILTER_NO_EQUAL_SIGN;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_LDAPCOMPARE_INVALID_ATTR_STRING;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_TOOL_INVALID_CONTROL_STRING;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldap.ResultCode.COMPARE_TRUE;
import java.util.ArrayList;
import java.util.List;
import com.forgerock.opendj.ldap.controls.RealAttributesOnlyRequestControl;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.Responses;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDAPCompare tool. */
@SuppressWarnings("javadoc")
@Test
public class LDAPCompareTestCase extends LDAPToolsTestCase {
    private final class LdapCompareToolLdapServer extends ToolLdapServer {
        private final class LdapCompareRequestHandler extends ToolLdapServer.ToolLdapServerConnection {
            @Override
            public void handleCompare(final Integer requestContext,
                                      final CompareRequest request,
                                      final IntermediateResponseHandler intermediateResponseHandler,
                                      final LdapResultHandler<CompareResult> resultHandler) {
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                assertThat(request.getAssertionValueAsString()).isEqualTo("the paranoid android");
                assertThat(request.getAttributeDescription().toString()).isEqualTo("description");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newCompareResult(COMPARE_TRUE));
            }
        }
        @Override
        ToolLdapServerConnection newServerConnection() {
            return new LdapCompareRequestHandler();
        }
    }
    @Override
    ToolLdapServer createFakeServer() {
        return new LdapCompareToolLdapServer();
    }
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize
     * the LDAPCompare tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the
     * LDAPCompare tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() throws Exception {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        argLists.add(args());
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(2));
        addValueNeededShortArgs(argLists, reasonList, "D", "w", "j", "K", "P", "W", "h", "p", "J", "o");
        addValueNeededLongArgs(argLists, reasonList, "assertionFilter", "hostname", "port", "control");
        argLists.add(args("-I"));
        reasonList.add(ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get("I"));
        argLists.add(args("--invalidLongArgument"));
        reasonList.add(ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID.get("invalidLongArgument"));
        argLists.add(args("--assertionFilter", "(invalidfilter)", "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_LDAP_FILTER_NO_EQUAL_SIGN.get("(invalidfilter)", 1, 14));
        argLists.add(args("-D", "cn=Directory Manager", "-j", "no.such.file", "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "bindPasswordFile"));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password", "-j", "src/test/resources/dummy-truststore",
                          "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("bindPassword", "bindPasswordFile"));
        argLists.add(args("-J", "1.2.3.4:invalidcriticality", "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_TOOL_INVALID_CONTROL_STRING.get("1.2.3.4:invalidcriticality"));
        argLists.add(args("-Z", "-q", "o=test", "o=test2"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("useStartTLS", "useSSL"));
        argLists.add(args("-p", "nonnumeric", "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "port"));
        argLists.add(args("-p", "999999", "uid:test.user", "uid=test.user,o=test"));
        reasonList.add(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get("port", 999999, 65535));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password"));
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(2));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password", "uid:test.user"));
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(2));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password", "malformed", "uid=test.user,o=test"));
        reasonList.add(ERR_LDAPCOMPARE_INVALID_ATTR_STRING.get("malformed"));
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void simpleComparison() throws Exception {
        runToolOnMockedServer("description:the paranoid android",
                              "uid=marvin");
    }
    @Test
    public void simpleComparisonUseReturnCode() throws Exception {
        runToolOnMockedServer(ResultCode.COMPARE_TRUE,
                              "-m",
                              "description:the paranoid android",
                              "uid=marvin");
    }
    @Test
    public void simpleComparisonWithProxyAs() throws Exception {
        controls.add(ProxiedAuthV2RequestControl.newControl("u:arthurdent"));
        runToolOnMockedServer("-Y", "u:arthurdent",
                              "description:the paranoid android",
                              "uid=marvin");
    }
    @Test
    public void comparisonWithAssertionFilter() throws Exception {
        controls.add(AssertionRequestControl.newControl(true, Filter.equality("initials", "FP")));
        runToolOnMockedServer("--assertionFilter", "(initials=FP)",
                              "description:the paranoid android",
                              "uid=marvin");
    }
    @Test
    public void comparisonWithAssertionFilterAndControl() throws Exception {
        controls.add(RealAttributesOnlyRequestControl.newControl(true));
        controls.add(AssertionRequestControl.newControl(true, Filter.equality("initials", "M")));
        runToolOnMockedServer("--assertionFilter", "(initials=M)",
                              "-J", "2.16.840.1.113730.3.4.17:true",
                              "description:the paranoid android",
                              "uid=marvin");
    }
    @Test
    public void comparisonWithAssertionFilterAndControlDryRun() throws Exception {
        controls.add(RealAttributesOnlyRequestControl.newControl(true));
        controls.add(AssertionRequestControl.newControl(true, Filter.equality("initials", "M")));
        runToolOnMockedServer("--assertionFilter", "(initials=M)",
                              "-J", "2.16.840.1.113730.3.4.17:true",
                              "-n",
                              "description:the paranoid android",
                              "uid=marvin");
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDAPCompare(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPDeleteTestCase.java
New file
@@ -0,0 +1,140 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static com.forgerock.opendj.cli.CliMessages.ERR_FILEARG_NO_SUCH_FILE;
import static com.forgerock.opendj.cli.CliMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static com.forgerock.opendj.cli.CliMessages.ERR_TOOL_CONFLICTING_ARGS;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_TOOL_INVALID_CONTROL_STRING;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.GenericControl;
import org.forgerock.opendj.ldap.controls.SubtreeDeleteRequestControl;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDAPDelete tool. */
@Test
public class LDAPDeleteTestCase extends LDAPToolsTestCase {
    private final class LdapDeleteToolLdapServer extends ToolLdapServer {
        private final class LdapDeleteRequestHandler extends ToolLdapServer.ToolLdapServerConnection {
            @Override
            public void handleDelete(final Integer requestContext,
                                     final DeleteRequest request,
                                     final IntermediateResponseHandler intermediateResponseHandler,
                                     final LdapResultHandler<Result> resultHandler) {
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
        }
        @Override
        ToolLdapServerConnection newServerConnection() {
            return new LdapDeleteRequestHandler();
        }
    }
    @Override
    ToolLdapServer createFakeServer() {
        return new LdapDeleteToolLdapServer();
    }
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize
     * the LDAPDelete tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the
     * LDAPDelete tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        addValueNeededShortArgs(
                argLists, reasonList, "D", "w", "j", "K", "P", "W", "h", "p", "J", "o");
        argLists.add(args("-D", "cn=Directory Manager", "-j", "no.such.file", "o=test"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "bindPasswordFile"));
        argLists.add(args("-J", "1.2.3.4:invalidcriticality", "o=test"));
        reasonList.add(ERR_TOOL_INVALID_CONTROL_STRING.get("1.2.3.4:invalidcriticality"));
        argLists.add(args("-Z", "-q", "o=test"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("useStartTLS", "useSSL"));
        argLists.add(args("-p", "nonnumeric", "o=test"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "port"));
        argLists.add(args("-p", "999999", "o=test"));
        reasonList.add(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get("port", 999999, 65535));
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void simpleDelete() throws Exception {
        runToolOnMockedServer("uid=marvin");
    }
    @Test
    public void deleteWithControl() throws Exception {
        controls.add(GenericControl.newControl("1.2.3.4.5.6.7.42", false, "testcontrol"));
        runToolOnMockedServer("-J", "1.2.3.4.5.6.7.42:false:testcontrol",
                              "uid=marvin");
    }
    @Test
    public void subtreeDeleteWithControl() throws Exception {
        controls.add(GenericControl.newControl("1.2.3.4.5.6.7.42", false, "testcontrol"));
        controls.add(SubtreeDeleteRequestControl.newControl(false));
        runToolOnMockedServer("-J", "1.2.3.4.5.6.7.42:false:testcontrol",
                              "--deleteSubtree",
                              "uid=marvin");
    }
    @Test
    public void subtreeDeleteWithControlDryRun() throws Exception {
        controls.add(GenericControl.newControl("1.2.3.4.5.6.7.42", false, "testcontrol"));
        controls.add(SubtreeDeleteRequestControl.newControl(false));
        runToolOnMockedServer("-J", "1.2.3.4.5.6.7.42:false:testcontrol",
                              "--deleteSubtree",
                              "-n",
                              "uid=marvin");
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDAPDelete(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPModifyTestCase.java
New file
@@ -0,0 +1,288 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static com.forgerock.opendj.cli.CliMessages.ERR_FILEARG_NO_SUCH_FILE;
import static com.forgerock.opendj.cli.CliMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static com.forgerock.opendj.cli.CliMessages.ERR_TOOL_CONFLICTING_ARGS;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_FILTER_NO_EQUAL_SIGN;
import static com.forgerock.opendj.ldap.tools.ToolLdapServer.DIRECTORY_MANAGER;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_TOOL_INVALID_CONTROL_STRING;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.createTempFile;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldap.ModificationType.ADD;
import static org.forgerock.opendj.ldap.ModificationType.DELETE;
import static org.forgerock.opendj.ldap.ModificationType.REPLACE;
import java.util.ArrayList;
import java.util.List;
import com.forgerock.opendj.ldap.controls.RealAttributesOnlyRequestControl;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.Modification;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
import org.forgerock.opendj.ldap.controls.PostReadRequestControl;
import org.forgerock.opendj.ldap.controls.PreReadRequestControl;
import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDAPModify tool. */
@SuppressWarnings("javadoc")
@Test
public class LDAPModifyTestCase extends LDAPToolsTestCase {
    private final class LdapModifyToolLdapServer extends ToolLdapServer {
        private final class LdapModifyRequestHandler extends ToolLdapServer.ToolLdapServerConnection {
            @Override
            public void handleAdd(final Integer requestContext,
                                  final AddRequest request,
                                  final IntermediateResponseHandler intermediateResponseHandler,
                                  final LdapResultHandler<Result> resultHandler) {
                if (request.getName().toString().equals("uid=error")) {
                    errorRaised = true;
                    resultHandler.handleResult(Responses.newResult(ResultCode.INSUFFICIENT_ACCESS_RIGHTS));
                    return;
                }
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
            @Override
            public void handleDelete(final Integer requestContext,
                                     final DeleteRequest request,
                                     final IntermediateResponseHandler intermediateResponseHandler,
                                     final LdapResultHandler<Result> resultHandler) {
                if (errorRaised && !continueOnError) {
                    throw new RuntimeException(
                            "ldapmodify continues to process requests without the --continueOnError flag");
                }
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
            @Override
            public void handleModify(final Integer requestContext,
                                     final ModifyRequest request,
                                     final IntermediateResponseHandler intermediateResponseHandler,
                                     final LdapResultHandler<Result> resultHandler) {
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                final List<Modification> modifications = request.getModifications();
                assertThat(modifications.size()).isEqualTo(3);
                assertThatModificationIsEqualTo(modifications.get(0), ADD, "attributetoadd", "value");
                assertThatModificationIsEqualTo(
                        modifications.get(1), REPLACE, "description", "The paranoid android");
                assertThatModificationIsEqualTo(
                        modifications.get(2), DELETE, "todelete", "");
                assertThat(modifications.get(1).getModificationType()).isEqualTo(REPLACE);
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
            private void assertThatModificationIsEqualTo(final Modification modification,
                                                         final ModificationType type,
                                                         final String attributeName,
                                                         final String attributeValue) {
                assertThat(modification.getModificationType()).isEqualTo(type);
                assertThat(modification.getAttribute().getAttributeDescriptionAsString()).isEqualTo(attributeName);
                if (type != DELETE) {
                    assertThat(modification.getAttribute().firstValueAsString()).isEqualTo(attributeValue);
                }
            }
            @Override
            public void handleModifyDN(final Integer requestContext,
                                       final ModifyDNRequest request,
                                       final IntermediateResponseHandler intermediateResponseHandler,
                                       final LdapResultHandler<Result> resultHandler) {
                assertThat(request.getName().toString()).isEqualTo("uid=marvin");
                assertThat(request.getNewRDN().toString()).isEqualTo("uid=arthurdent");
                assertThat(request.isDeleteOldRDN()).isTrue();
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
        }
        @Override
        ToolLdapServerConnection newServerConnection() {
            return new LdapModifyRequestHandler();
        }
    }
    @Override
    ToolLdapServer createFakeServer() {
        return new LdapModifyToolLdapServer();
    }
    private boolean continueOnError;
    private boolean errorRaised;
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize
     * the LDAPModify tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the
     * LDAPModify tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        addValueNeededShortArgs(argLists, reasonList, "D", "w", "j", "Y", "K", "P", "W", "h", "p", "J", "o");
        addValueNeededLongArgs(argLists, reasonList, "assertionFilter", "hostname",
                               "port", "control", "preReadAttributes", "postReadAttributes");
        argLists.add(args("-D", "cn=Directory Manager", "-j", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "bindPasswordFile"));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password", "-j", "src/test/resources/dummy-truststore"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("bindPassword", "bindPasswordFile"));
        argLists.add(args("-J", "1.2.3.4:invalidcriticality"));
        reasonList.add(ERR_TOOL_INVALID_CONTROL_STRING.get("1.2.3.4:invalidcriticality"));
        argLists.add(args("-Z", "-q"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("useStartTLS", "useSSL"));
        argLists.add(args("-p", "nonnumeric"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "port"));
        argLists.add(args("-p", "999999"));
        reasonList.add(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get("port", 999999, 65535));
        argLists.add(args("--assertionFilter", "(invalid)"));
        reasonList.add(ERR_LDAP_FILTER_NO_EQUAL_SIGN.get("(invalid)", 1, 8));
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void testNoContinueOnError() throws Exception {
        final String tmpFilePath = createTempFile("dn: uid=error",
                                                  "changetype: add",
                                                  "description: An error will be raised by server",
                                                  "",
                                                  "dn: uid=marvin",
                                                  "changetype: delete");
        final int res = runTool("-h", server.getHostName(),
                                "-p", server.getPort(),
                                "-D", DIRECTORY_MANAGER,
                                "-w", "password",
                                "-f", tmpFilePath);
        assertThat(res).isEqualTo(ResultCode.INSUFFICIENT_ACCESS_RIGHTS.intValue());
    }
    @Test
    public void testSimpleModifyRequests() throws Exception {
        final String tmpFilePath = createTempFile("dn: uid=marvin",
                                                  "changetype: modify",
                                                  "add: attributetoadd",
                                                  "attributetoadd: value",
                                                  "-",
                                                  "replace: description",
                                                  "description: The paranoid android",
                                                  "-",
                                                  "delete: todelete",
                                                  "");
        final String tmpFilePath2 = createTempFile("dn: uid=marvin",
                                                   "changetype: add");
        runToolOnMockedServer(tmpFilePath, tmpFilePath2);
    }
    @Test
    public void testAddAndDeleteRequests() throws Exception {
        controls.add(AssertionRequestControl.newControl(true,
                Filter.and(Filter.equality("uid", "marvin"), Filter.equality("description", "The paranoid android"))));
        controls.add(PostReadRequestControl.newControl(true, "uid"));
        final String tmpFilePath = createTempFile("dn: uid=marvin",
                                                  "changetype: add",
                                                  "description: The paranoid android",
                                                  "",
                                                  "dn: uid=marvin",
                                                  "changetype: delete");
        runToolOnMockedServer("--postReadAttributes", "uid",
                              "--assertionFilter", "(&(uid=marvin)(description=The paranoid android))",
                              "-f", tmpFilePath);
    }
    @Test
    public void testContinueOnError() throws Exception {
        continueOnError = true;
        controls.add(RealAttributesOnlyRequestControl.newControl(true));
        final String tmpFilePath = createTempFile("dn: uid=error",
                                                  "changetype: add",
                                                  "description: An error will be raised by server",
                                                  "",
                                                  "dn: uid=marvin",
                                                  "changetype: delete");
        runToolOnMockedServer("-c",
                              "-J", "2.16.840.1.113730.3.4.17:true",
                              tmpFilePath);
    }
    @Test
    public void testModifyDN() throws Exception {
        controls.add(ProxiedAuthV2RequestControl.newControl("dn: uid=marvin"));
        controls.add(PreReadRequestControl.newControl(true, "uid"));
        final String tmpFilePath = createTempFile("dn: uid=marvin",
                                                  "changetype: moddn",
                                                  "newrdn: uid=arthurdent",
                                                  "deleteoldrdn: 1");
        runToolOnMockedServer("-c",
                              "--preReadAttributes", "uid",
                              "-Y", "dn: uid=marvin",
                              tmpFilePath);
    }
    @Test
    public void testModifyDNDryRun() throws Exception {
        controls.add(ProxiedAuthV2RequestControl.newControl("dn: uid=marvin"));
        controls.add(PreReadRequestControl.newControl(true, "uid"));
        final String tmpFilePath = createTempFile("dn: uid=marvin",
                                                  "changetype: moddn",
                                                  "newrdn: uid=arthurdent",
                                                  "deleteoldrdn: 1");
        runToolOnMockedServer("-c",
                              "--preReadAttributes", "uid",
                              "-Y", "dn: uid=marvin",
                              "-n",
                              tmpFilePath);
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDAPModify(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModifyTestCase.java
New file
@@ -0,0 +1,160 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static com.forgerock.opendj.cli.CliMessages.ERR_FILEARG_NO_SUCH_FILE;
import static com.forgerock.opendj.cli.CliMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static com.forgerock.opendj.cli.CliMessages.ERR_TOOL_CONFLICTING_ARGS;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.buildArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.createTempFile;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.assertj.core.api.Assertions.fail;
import static org.fest.assertions.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import com.forgerock.opendj.ldap.controls.AccountUsabilityRequestControl;
import com.forgerock.opendj.ldap.tools.ToolsTestUtils.Args;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.PasswordPolicyRequestControl;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Responses;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDAPPasswordModify tool. */
@Test
public class LDAPPasswordModifyTestCase extends LDAPToolsTestCase {
    private final class LdapPasswordModifyToolLdapServer extends ToolLdapServer {
        private final class LdapPasswordModifyRequestHandler extends ToolLdapServer.ToolLdapServerConnection {
            @Override
            public <R extends ExtendedResult> void handleExtendedRequest(final Integer requestContext,
                                                                         final ExtendedRequest<R> request,
                                                                         final IntermediateResponseHandler irh,
                                                                         final LdapResultHandler<R> resultHandler) {
                assertThat(request.getOID()).isEqualTo("1.3.6.1.4.1.4203.1.11.1");
                assertThat(request.getValue().toASCIIString()).isEqualTo(
                        "0*%80%0Edn: uid=marvin%81%0Boldpassword%82%0Bnewpassword");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                try {
                    resultHandler.handleResult(request.getResultDecoder().decodeExtendedResult(
                            Responses.newPasswordModifyExtendedResult(ResultCode.SUCCESS), new DecodeOptions()));
                } catch (DecodeException e) {
                    fail("Unexpected error occurred while mocking server password modify response.", e);
                }
            }
        }
        @Override
        ToolLdapServerConnection newServerConnection() {
            return new LdapPasswordModifyRequestHandler();
        }
    }
    @Override
    ToolLdapServer createFakeServer() {
        return new LdapPasswordModifyToolLdapServer();
    }
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize
     * the LDAPPasswordModify tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the
     * LDAPPasswordModify tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        addValueNeededShortArgs(argLists, reasonList, "a", "N", "n", "c", "C", "D", "w", "j", "K", "P", "W", "h", "p");
        addValueNeededLongArgs(argLists, reasonList, "hostname", "port", "control",
                "keyStorePasswordFile", "trustStorePassword", "trustStorePasswordFile");
        argLists.add(args("-D", "cn=Directory Manager", "-j", "no.such.file"));
        reasonList.add(ERR_FILEARG_NO_SUCH_FILE.get("no.such.file", "bindPasswordFile"));
        argLists.add(args("-D", "cn=Directory Manager", "-w", "password", "-j", "src/test/resources/dummy-truststore"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("bindPassword", "bindPasswordFile"));
        argLists.add(args("-D", "cn=Directory Manager", "-c", "password", "-C", "src/test/resources/dummy-truststore"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("currentPassword", "currentPasswordFile"));
        argLists.add(args("-D", "cn=Directory Manager", "-n", "password", "-F", "src/test/resources/dummy-truststore"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("newPassword", "newPasswordFile"));
        argLists.add(args("-Z", "-q"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("useStartTLS", "useSSL"));
        argLists.add(args("-p", "nonnumeric"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "port"));
        argLists.add(args("-p", "999999"));
        reasonList.add(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get("port", 999999, 65535));
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void testLdapPasswordModify() throws Exception {
        runToolOnMockedServer("-c", "oldpassword",
                              "-n", "newpassword");
    }
    @Test
    public void testLdapPasswordModifyWithPasswordInFiles() throws Exception {
        final String oldPwdFilePath = createTempFile("oldpassword");
        final String newPwdFilePath = createTempFile("newpassword");
        runToolOnMockedServer("-C", oldPwdFilePath,
                              "-F", newPwdFilePath);
    }
    @Test
    public void testLdapPasswordModifyWithControls() throws Exception {
        controls.add(PasswordPolicyRequestControl.newControl(false));
        controls.add(AccountUsabilityRequestControl.newControl(false));
        runToolOnMockedServer("-J", "1.3.6.1.4.1.42.2.27.8.5.1:false",
                              "-J", "1.3.6.1.4.1.42.2.27.9.5.8:false",
                              "-c", "oldpassword",
                              "-n", "newpassword");
    }
    @Override
    Args toolConstantArguments() {
        return buildArgs().add("-a", "dn: uid=marvin");
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDAPPasswordModify(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java
@@ -19,6 +19,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_LDAPSEARCH_MATCHING_ENTRY_COUNT;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.INFO_LDAPSEARCH_TOOL_DESCRIPTION;
import static com.forgerock.opendj.ldap.tools.Utils.runTool;
import java.io.PrintStream;
import java.util.Random;
@@ -75,7 +76,7 @@
        try (PrintStream outStream = new PrintStream(out.asOutputStream());
             PrintStream errStream = new PrintStream(err.asOutputStream())) {
            LDAPSearch.run(outStream, errStream, arguments);
            runTool(new LDAPSearch(outStream, errStream), arguments);
            checkOuputStreams(out, err, expectedOut, expectedErr);
        } catch (final LDAPToolException e) {
            checkOuputStreams(out, err, expectedOut, expectedErr);
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchTestCase.java
New file
@@ -0,0 +1,267 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARG_CANNOT_DECODE_AS_INT;
import static com.forgerock.opendj.cli.CliMessages.ERR_INTARG_VALUE_ABOVE_UPPER_BOUND;
import static com.forgerock.opendj.cli.CliMessages.ERR_MCARG_VALUE_NOT_ALLOWED;
import static com.forgerock.opendj.cli.CliMessages.ERR_TOOL_CONFLICTING_ARGS;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_FILTER_NO_EQUAL_SIGN;
import static com.forgerock.opendj.ldap.tools.ToolLdapServer.DIRECTORY_MANAGER;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_PSEARCH_DOESNT_START_WITH_PS;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_PSEARCH_INVALID_CHANGE_TYPE;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_TOOL_INVALID_CONTROL_STRING;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.buildArgs;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.controls.AssertionRequestControl;
import org.forgerock.opendj.ldap.controls.GenericControl;
import org.forgerock.opendj.ldap.controls.GetEffectiveRightsRequestControl;
import org.forgerock.opendj.ldap.controls.MatchedValuesRequestControl;
import org.forgerock.opendj.ldap.controls.PersistentSearchChangeType;
import org.forgerock.opendj.ldap.controls.PersistentSearchRequestControl;
import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
import org.forgerock.opendj.ldap.controls.ServerSideSortRequestControl;
import org.forgerock.opendj.ldap.controls.SimplePagedResultsControl;
import org.forgerock.opendj.ldap.controls.SubentriesRequestControl;
import org.forgerock.opendj.ldap.controls.VirtualListViewRequestControl;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDAPSearch tool. */
@SuppressWarnings("javadoc")
@Test
public class LDAPSearchTestCase extends LDAPToolsTestCase {
    private final class LdapSearchToolLdapServer extends ToolLdapServer {
        private final class LdapSearchRequestHandler extends ToolLdapServer.ToolLdapServerConnection {
            @Override
            public void handleSearch(final Integer requestContext,
                                     final SearchRequest request,
                                     final IntermediateResponseHandler intermediateResponseHandler,
                                     final SearchResultHandler entryHandler,
                                     final LdapResultHandler<Result> resultHandler) {
                assertThat(request.getName().toString()).isEqualTo("ou=people,dc=example,dc=com");
                assertThat(request.getDereferenceAliasesPolicy()).isEqualTo(DereferenceAliasesPolicy.FINDING_BASE);
                assertThat(request.getSizeLimit()).isEqualTo(100);
                assertThat(request.isTypesOnly()).isTrue();
                assertThat(request.getTimeLimit()).isEqualTo(120);
                assertThat(request.getScope()).isEqualTo(SearchScope.SUBORDINATES);
                assertThat(request.getAttributes()).containsExactly("uid", "objectclass", "description");
                assertThat(request.getFilter().toString()).isEqualTo("(st=Alabama)");
                assertThatControlsHaveBeenSentInRequest(request.getControls());
                resultHandler.handleResult(Responses.newResult(ResultCode.SUCCESS));
            }
        }
        @Override
        ToolLdapServerConnection newServerConnection() {
            return new LdapSearchRequestHandler();
        }
    }
    @Override
    ToolLdapServer createFakeServer() {
        return new LdapSearchToolLdapServer();
    }
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize
     * the LDAPSearch tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the
     * LDAPSearch tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        argLists.add(args());
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(1));
        addValueNeededShortArgs(argLists, reasonList,
                "b", "D", "w", "j", "Y", "K", "P", "W", "h", "p", "J", "z", "l", "s", "a", "o");
        addValueNeededLongArgs(argLists, reasonList,
                               "assertionFilter", "matchedValuesFilter", "hostname", "port", "control");
        argLists.add(args("(objectClass=*)"));
        reasonList.add(ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG.get("baseDN"));
        argLists.add(args("-b", ""));
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(1));
        argLists.add(args("-b", "", "--assertionFilter", "(invalidfilter)", "(objectClass=*)"));
        reasonList.add(ERR_LDAP_FILTER_NO_EQUAL_SIGN.get("(invalidfilter)", 1, 14));
        argLists.add(args("-b", "", "--matchedValuesFilter", "(invalidfilter)", "(objectClass=*)"));
        reasonList.add(ERR_LDAP_FILTER_NO_EQUAL_SIGN.get("(invalidfilter)", 1, 14));
        argLists.add(args("-D", "cn=Directory Manager",
                          "-j", "src/test/resources/dummy-truststore",
                          "-w", "password",
                          "-b", "",
                          "(objectClass=*)"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("bindPassword", "bindPasswordFile"));
        argLists.add(args("-b", "", "-J", "1.2.3.4:invalidcriticality", "(objectClass=*)"));
        reasonList.add(ERR_TOOL_INVALID_CONTROL_STRING.get("1.2.3.4:invalidcriticality"));
        argLists.add(args("-b", "", "-s", "invalid", "(objectClass=*)"));
        reasonList.add(ERR_MCARG_VALUE_NOT_ALLOWED.get("searchScope", "invalid"));
        argLists.add(args("-b", "", "-a", "invalid", "(objectClass=*)"));
        reasonList.add(ERR_MCARG_VALUE_NOT_ALLOWED.get("dereferencePolicy", "invalid"));
        argLists.add(args("-b", "", "-C", "invalid", "(objectClass=*)"));
        reasonList.add(ERR_PSEARCH_DOESNT_START_WITH_PS.get("invalid"));
        argLists.add(args("-b", "", "-C", "ps:invalid", "(objectClass=*)"));
        reasonList.add(ERR_PSEARCH_INVALID_CHANGE_TYPE.get("invalid"));
        argLists.add(args("-Z", "-q", "-b", "", "(objectClass=*"));
        reasonList.add(ERR_TOOL_CONFLICTING_ARGS.get("useStartTLS", "useSSL"));
        argLists.add(args("-p", "nonnumeric", "-b", "", "(objectClass=*)"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "port"));
        argLists.add(args("-p", "999999", "-b", "", "(objectClass=*)"));
        reasonList.add(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get("port", 999999, 65535));
        argLists.add(args("-z", "nonnumeric", "-b", "", "(objectClass=*)"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "sizeLimit"));
        argLists.add(args("-l", "nonnumeric", "-b", "", "(objectClass=*)"));
        reasonList.add(ERR_ARG_CANNOT_DECODE_AS_INT.get("nonnumeric", "timeLimit"));
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void testLdapSearch() throws Exception {
        runToolOnMockedServer();
    }
    @Test
    public void testLdapSearchWithAssertionFilter() throws Exception {
        controls.add(AssertionRequestControl.newControl(true, Filter.or(Filter.equality("uid", "user.1"),
                                                                        Filter.greaterOrEqual("age", "40"))));
        runToolOnMockedServer("--assertionFilter", "(|(uid=user.1)(age>=40))");
    }
    @Test
    public void testLdapSearchWithPersistentSearch() throws Exception {
        controls.add(PersistentSearchRequestControl.newControl(true, false, true, PersistentSearchChangeType.ADD));
        runToolOnMockedServer("-C", "ps:add:0:1");
    }
    @Test
    public void testLdapSearchWithProxyAuthz() throws Exception {
        controls.add(ProxiedAuthV2RequestControl.newControl("dn: uid=marvin"));
        runToolOnMockedServer("-Y", "dn: uid=marvin");
    }
    @Test
    public void testLdapSearchWithGetEffectiveRightsProxyAuthz() throws Exception {
        controls.add(GetEffectiveRightsRequestControl.newControl(false, "uid=marvin", "description", "objectclass"));
        runToolOnMockedServer("-g", "dn: uid=marvin",
                              "-e", "description",
                              "-e", "objectclass");
    }
    @Test
    public void testLdapSearchWithVLVControl() throws Exception {
        controls.add(ServerSideSortRequestControl.newControl(false, "sn"));
        controls.add(VirtualListViewRequestControl.newOffsetControl(true, 10, 2, 1, 3, null));
        runToolOnMockedServer("-G", "1:3:10:2",
                              "--sortOrder", "sn");
    }
    @Test
    public void testLdapSearchWithMatchedValuesFilter() throws Exception {
        controls.add(MatchedValuesRequestControl.newControl(true, "uid=user.1*"));
        runToolOnMockedServer("--matchedValuesFilter", "uid=user.1*");
    }
    @Test
    public void testLdapSearchWithSubEntriesControl() throws Exception {
        controls.add(GenericControl.newControl("1.2.3.4.5.6.7.8", false, "myvalue"));
        controls.add(SubentriesRequestControl.newControl(true, true));
        runToolOnMockedServer("-J", "1.2.3.4.5.6.7.8:false:myvalue",
                              "--subEntries");
    }
    @Test
    public void testLdapSearchWithSubEntriesControlDryRun() throws Exception {
        controls.add(GenericControl.newControl("1.2.3.4.5.6.7.8", false, "myvalue"));
        controls.add(SubentriesRequestControl.newControl(true, true));
        runToolOnMockedServer("-J", "1.2.3.4.5.6.7.8:false:myvalue",
                              "--subEntries",
                              "-n");
    }
    @Test
    public void testLdapSearchWithSimplePaged() throws Exception {
        controls.add(SimplePagedResultsControl.newControl(true, 10, ByteString.empty()));
        runToolOnMockedServer("--simplePageSize", "10");
    }
    @Override
    int runToolOnMockedServer(final String... additionalArgs) {
        final int res = runTool(buildArgs().add("-h", server.getHostName())
                                           .add("-p", server.getPort())
                                           .add("-D", DIRECTORY_MANAGER)
                                           .add("-w", "password")
                                           .add("-b", "ou=people,dc=example,dc=com")
                                           .add("-a", "find")
                                           .add("-A")
                                           .add("-s", "subordinates")
                                           .add("-l", "120")
                                           .add("-z", "100")
                                           .addAll(additionalArgs)
                                           .addAll("(st=Alabama)", "uid", "objectclass", "description")
                                           .toArray());
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        return res;
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDAPSearch(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPToolsTestCase.java
New file
@@ -0,0 +1,101 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.ldap.tools.ToolLdapServer.DIRECTORY_MANAGER;
import static org.fest.assertions.Assertions.assertThat;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.buildArgs;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.forgerock.opendj.ldap.tools.ToolsTestUtils.Args;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.controls.Control;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@SuppressWarnings("javadocs")
@Test
abstract class LDAPToolsTestCase extends ToolsTestCase {
    List<Control> controls;
    ToolLdapServer server;
    @BeforeClass
    void setUp() throws IOException {
        server = createFakeServer();
        server.start();
    }
    @AfterClass
    void tearDown() throws IOException {
        server.stop();
    }
    @BeforeMethod
    void initializeTest() {
        controls = new ArrayList<>();
    }
    void assertThatControlsHaveBeenSentInRequest(final List<Control> requestControls) {
        if (!controls.isEmpty()) {
            int i = 0;
            assertThat(requestControls.size()).isEqualTo(controls.size());
            for (final Control requestControl : requestControls) {
                final Control clientControl = controls.get(i++);
                assertThat(requestControl.getOID()).isEqualTo(clientControl.getOID());
                assertThat(requestControl.isCritical()).isEqualTo(clientControl.isCritical());
                assertThat(requestControl.getValue()).isEqualTo(clientControl.getValue());
            }
        }
    }
    /**
     * Run this ldap* tool on this mocked server.
     * Use root user DN and root user password common to the tests.
     * Other constant arguments should be added by the tool implementation by overriding
     * {@link LDAPToolsTestCase#toolConstantArguments()}
     *
     * @param specificTestArgs
     *         Arguments specific for a test case.
     * @return An int which represents the code returned by the ldap* tool
     */
    int runToolOnMockedServer(final String... specificTestArgs) {
        return runToolOnMockedServer(ResultCode.SUCCESS, specificTestArgs);
    }
    int runToolOnMockedServer(final ResultCode expectedRC, final String... specificTestArgs) {
        final int res = runTool(buildArgs().add("-h", server.getHostName())
                                           .add("-p", server.getPort())
                                           .add("-D", DIRECTORY_MANAGER)
                                           .add("-w", "password")
                                           .addAll(toolConstantArguments())
                                           .addAll(specificTestArgs)
                                           .toArray());
        assertThat(res).isEqualTo(expectedRC.intValue());
        return res;
    }
    Args toolConstantArguments() {
        return buildArgs();
    }
    abstract ToolLdapServer createFakeServer();
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFDiffTestCase.java
New file
@@ -0,0 +1,214 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS;
import static com.forgerock.opendj.ldap.tools.LDIFDiff.DIFFERENCES_FOUND;
import static com.forgerock.opendj.ldap.tools.LDIFDiff.NO_DIFFERENCES_FOUND;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_LDIFDIFF_MULTIPLE_USES_OF_STDIN;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.calcChecksum;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ResultCode;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** A set of test cases for the LDIFDiff tool. */
@Test
public class LDIFDiffTestCase extends ToolsTestCase {
    private static final String LDIF_RESOURCES_PATH =
            Paths.get("src", "test", "resources", "ldifdiff").toAbsolutePath().toString();
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     */
    @DataProvider
    public Object[][] invalidArgs() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        argLists.add(args());
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(2));
        addValueNeededShortArgs(argLists, reasonList, "o");
        addValueNeededLongArgs(argLists, reasonList, "outputLdif");
        return toDataProviderArray(argLists, reasonList);
    }
    /**
     * Retrieves the names of the files that should be used when testing the
     * ldifdiff tool.  Each element of the outer array should be an array
     * containing the following elements:
     * <OL>
     * <LI>The path to the source LDIF file</LI>
     * <LI>The path to the target LDIF file</LI>
     * <LI>The path to the diff file, or {@code null} if the diff is supposed
     * to fail</LI>
     * </OL>
     */
    @DataProvider
    public Object[][] testDataNoDiffs() {
        return new Object[][] {
            // Both files are empty.
            { "source-empty.ldif", "target-empty.ldif" },
            // Both files are the single-entry source.
            { "source-singleentry.ldif", "source-singleentry.ldif" },
            // Both files are the single-entry target.
            { "target-singleentry.ldif", "target-singleentry.ldif" },
            // Both files are the multiple-entry source.
            { "source-multipleentries.ldif", "source-multipleentries.ldif" },
            // Both files are the multiple-entry target.
            { "target-multipleentries.ldif", "target-multipleentries.ldif" },
        };
    }
    @Test(dataProvider = "testDataNoDiffs")
    public void testLdifDiffWithoutDiffs(final String sourceFileName, final String targetFileName) throws Exception {
        testLdifDiff(sourceFileName, targetFileName, "diff-nochanges.ldif");
    }
    /**
     * Retrieves the names of the files that should be used when testing the
     * ldifdiff tool.  Each element of the outer array should be an array
     * containing the following elements:
     * <OL>
     * <LI>The path to the source LDIF file</LI>
     * <LI>The path to the target LDIF file</LI>
     * <LI>The path to the diff file, or {@code null} if the diff is supposed
     * to fail</LI>
     * </OL>
     */
    @DataProvider
    public Object[][] testDataWithDiffs() {
        return new Object[][] {
            // The source is empty but the target has a single entry.
            { "source-empty.ldif", "target-singleentry.ldif", "diff-emptytosingle.ldif" },
            // The source has a single entry but the target is empty.
            { "source-singleentry.ldif", "target-empty.ldif", "diff-singletoempty.ldif" },
            // Make a change to only a single entry in the source->target direction.
            { "source-singleentry.ldif", "target-singleentry.ldif", "diff-singleentry.ldif" },
            // Make a change to only a single entry in the target->source direction.
            { "target-singleentry.ldif", "source-singleentry.ldif", "diff-singleentry-reverse.ldif" },
            // Make changes to multiple entries in the source->target direction.
            { "source-multipleentries.ldif", "target-multipleentries.ldif", "diff-multipleentries.ldif" },
            // Make changes to multiple entries in the target->source direction.
            { "target-multipleentries.ldif", "source-multipleentries.ldif", "diff-multipleentries-reverse.ldif" },
            // Go from one entry to multiple in the source->target direction.
            { "source-singleentry.ldif", "target-multipleentries.ldif", "diff-singletomultiple.ldif" },
            // Go from one entry to multiple in the target->source direction.
            { "target-singleentry.ldif", "source-multipleentries.ldif", "diff-singletomultiple-reverse.ldif" },
            // Go from multiple entries to one in the source->target direction.
            { "source-multipleentries.ldif", "target-singleentry.ldif", "diff-multipletosingle.ldif" },
            // Go from multiple entries to one in the target->source direction.
            { "target-multipleentries.ldif", "source-singleentry.ldif", "diff-multipletosingle-reverse.ldif" }
        };
    }
    @Test(dataProvider = "testDataWithDiffs")
    public void testReconstructWithLdifModify(final String sourceFileName,
                                              final String targetFileName,
                                              final String expectedResultFileName) throws Exception {
        final String ldifDiffResultFilePath = testLdifDiff(sourceFileName, targetFileName, expectedResultFileName);
        final File ldifModifyResultFile = new File(LDIF_RESOURCES_PATH, "ldifDiffAndModifyTestCase.ldif");
        ldifModifyResultFile.deleteOnExit();
        final int ldifModifyRes = Utils.runTool(new LDIFModify(outStream, errStream),
                                                "-o", ldifModifyResultFile.getAbsolutePath(),
                                                absolutePath(sourceFileName),
                                                ldifDiffResultFilePath);
        assertThat(ldifModifyRes).isEqualTo(ResultCode.SUCCESS.intValue());
        testLdifDiff(targetFileName, "ldifDiffAndModifyTestCase.ldif", "diff-nochanges.ldif");
    }
    private String testLdifDiff(final String sourceFileName,
                                final String targetFileName,
                                final String expectedResultFileName) throws Exception {
        final String ldifDiffOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool("-o", ldifDiffOutputFilePath,
                                absolutePath(sourceFileName),
                                absolutePath(targetFileName));
        final boolean expectNoDiffs = expectedResultFileName.equals("diff-nochanges.ldif");
        assertThat(res).isEqualTo(expectNoDiffs ? NO_DIFFERENCES_FOUND
                                                : DIFFERENCES_FOUND);
        assertThat(calcChecksum(ldifDiffOutputFilePath)).isEqualTo(
                   calcChecksum(absolutePath(expectedResultFileName)));
        return ldifDiffOutputFilePath;
    }
    @Test
    public void testLdifDiffWithoutWrapping() throws Exception {
        final String ldifDiffOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool("-o", ldifDiffOutputFilePath,
                                "-t", "0",
                                absolutePath("source-singleentry.ldif"),
                                absolutePath("target-multipleentries.ldif"));
        assertThat(res).isEqualTo(DIFFERENCES_FOUND);
        assertThat(calcChecksum(ldifDiffOutputFilePath)).isEqualTo(
                   calcChecksum(absolutePath("diff-singletomultiple-no-wrapping.ldif")));
    }
    @Test
    public void testLdifDiffWithBothSourceAndTargetOnStdin() throws Exception {
        final String ldifDiffOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool("-o", ldifDiffOutputFilePath,
                                "--",
                                "-",
                                "-");
        assertThat(res).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(ERR_LDIFDIFF_MULTIPLE_USES_OF_STDIN.get().toString());
    }
    private String absolutePath(final String fileName) {
        return LDIF_RESOURCES_PATH + File.separator + fileName;
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDIFDiff(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFModifyTestCase.java
New file
@@ -0,0 +1,145 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS;
import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDIF_NO_DN;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_LDIFMODIFY_MULTIPLE_USES_OF_STDIN;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.buildArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.calcChecksum;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ResultCode;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@SuppressWarnings("javadoc")
@Test
public class LDIFModifyTestCase extends ToolsTestCase {
    private static final String LDIF_RESOURCES_PATH =
            Paths.get("src", "test", "resources", "ldifmodify").toAbsolutePath().toString();
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     */
    @DataProvider
    public Object[][] invalidArgs() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        argLists.add(args());
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(1));
        addValueNeededShortArgs(argLists, reasonList, "o");
        addValueNeededLongArgs(argLists, reasonList, "outputLdif");
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void testSimpleLdifModifyWithMultipleChangeFiles() throws Exception {
        final String ldifModifyOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool(buildArgs().add("-o", ldifModifyOutputFilePath)
                                           .add(absolutePath("source.ldif"))
                                           .add(absolutePath("modifications_part_1.ldif"))
                                           .add(absolutePath("modifications_part_2.ldif"))
                                           .add(absolutePath("modifications_part_3.ldif"))
                                           .toArray());
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        assertThat(calcChecksum(absolutePath("expected-no-wrapping.ldif"))).isEqualTo(
                   calcChecksum(ldifModifyOutputFilePath));
    }
    @Test
    public void testSimpleLdifModifyWithWrapping() throws Exception {
        testSimpleLdifModify(ResultCode.SUCCESS, "modifications.ldif", "expected.ldif", "-t", "80");
    }
    @Test
    public void testLdifModifyWithBothSourceAndChangesOnStdin() throws Exception {
        final String ldifDiffOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool("-o", ldifDiffOutputFilePath,
                                "--",
                                "-",
                                "-");
        assertThat(res).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(ERR_LDIFMODIFY_MULTIPLE_USES_OF_STDIN.get().toString());
    }
    @Test
    public void testSimpleLdifModifyWithoutWrapping() throws Exception {
        testSimpleLdifModify(ResultCode.SUCCESS, "modifications.ldif", "expected-no-wrapping.ldif", "-t", "0");
    }
    @Test
    public void testSimpleLdifModifyWithErrorInModifications() throws Exception {
        testSimpleLdifModify(ResultCode.CLIENT_SIDE_LOCAL_ERROR, "modifications-with-error.ldif", "Not Applicable");
    }
    @Test
    public void testSimpleLdifModifyWithContinueOnError() throws Exception {
        testSimpleLdifModify(ResultCode.SUCCESS,
                             "modifications-with-error.ldif",
                             "expected-continue-on-error.ldif",
                             "-c");
    }
    @Test
    public void testSimpleLdifModifyWithIncorrectLdifModifications() throws Exception {
        testSimpleLdifModify(ResultCode.CLIENT_SIDE_LOCAL_ERROR, "modifications-invalid.ldif", "Not Applicable");
        assertThat(errOnSingleLine()).contains(ERR_LDIF_NO_DN.get(1, "changetype: modify").toString());
        assertThat(out.toString()).isEmpty();
    }
    private void testSimpleLdifModify(final ResultCode expectedRC,
                                      final String modificationsFileName,
                                      final String expectedOutputFileName,
                                      final String... additionalArgs) throws Exception {
        final String ldifModifyOutputFilePath = ToolsTestUtils.createTempFile();
        final int res = runTool(buildArgs().add("-o", ldifModifyOutputFilePath)
                                           .addAll(additionalArgs)
                                           .add(absolutePath("source.ldif"))
                                           .add(absolutePath(modificationsFileName))
                                           .toArray());
        assertThat(res).isEqualTo(expectedRC.intValue());
        if (expectedRC == ResultCode.SUCCESS) {
            assertThat(calcChecksum(absolutePath(expectedOutputFileName))).isEqualTo(
                       calcChecksum(ldifModifyOutputFilePath));
        }
    }
    private String absolutePath(final String fileName) {
        return LDIF_RESOURCES_PATH + File.separator + fileName;
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDIFModify(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDIFSearchTestCase.java
New file
@@ -0,0 +1,224 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededLongArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.addValueNeededShortArgs;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.args;
import static com.forgerock.opendj.ldap.tools.ToolsTestUtils.toDataProviderArray;
import static org.fest.assertions.Assertions.assertThat;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.TestCaseUtils;
import org.forgerock.opendj.ldif.LDIFEntryReader;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/** LDIFSearch test cases. */
@SuppressWarnings("javadoc")
@Test
public class LDIFSearchTestCase extends ToolsTestCase {
    private String ldifSearchSourceFilePath;
    private String ldifSearchOutputFilePath;
    @BeforeClass
    private void setUp() throws Exception {
        ldifSearchSourceFilePath = Paths.get("src", "test", "resources", "ldifsearch.ldif").toAbsolutePath().toString();
        ldifSearchOutputFilePath = TestCaseUtils.createTempFile();
    }
    /**
     * Retrieves sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     *
     * @return Sets of invalid arguments that may not be used to initialize the LDAPSearch tool.
     */
    @DataProvider(name = "invalidArgs")
    public Object[][] getInvalidArgumentLists() {
        final List<List<String>> argLists = new ArrayList<>();
        final List<LocalizableMessage> reasonList = new ArrayList<>();
        argLists.add(args());
        reasonList.add(ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(2));
        addValueNeededShortArgs(argLists, reasonList, "b", "l", "s", "z");
        addValueNeededLongArgs(argLists, reasonList, "baseDN", "timeLimit", "outputLDIF", "searchScope", "sizeLimit");
        return toDataProviderArray(argLists, reasonList);
    }
    @Test
    public void testLDIFSearchStarOps() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                ldifSearchSourceFilePath,
                                "(objectclass=*)",
                                "*", "+");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            while (reader.hasNext()) {
                assertThat(reader.readEntry().getAllAttributes("objectclass")).isNotEmpty();
            }
        }
    }
    @Test
    public void testLDIFSearchOperationalAttributesOnly() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                "-s", "sub",
                                ldifSearchSourceFilePath,
                                "(objectclass=*)",
                                "+");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            while (reader.hasNext()) {
                assertThat(reader.readEntry().getAllAttributes("objectclass")).isEmpty();
            }
        }
    }
    @Test
    public void testLDIFSearchUserAndOperationalAttributes() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                "-s", "subordinates",
                                ldifSearchSourceFilePath,
                                "(objectclass=*)",
                                "+", "mail", "uid");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            while (reader.hasNext()) {
                final Entry e = reader.readEntry();
                assertThat(e.getAllAttributes("objectclass")).isEmpty();
                assertThat(e.getAllAttributes("mail")).isNotEmpty();
                assertThat(e.getAllAttributes("uid")).isNotEmpty();
            }
        }
    }
    @Test
    public void testLDIFSearchAttrsOnly() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                "-s", "subordinates",
                                "-A",
                                ldifSearchSourceFilePath,
                                "(objectclass=*)",
                                "mail");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            while (reader.hasNext()) {
                final Entry e = reader.readEntry();
                assertThat(e.getAllAttributes("objectclass")).isEmpty();
                final Iterable<Attribute> mails = e.getAllAttributes("mail");
                assertThat(mails).isNotEmpty();
                for (final Attribute mail : mails) {
                    assertThat(mail.firstValueAsString()).isEmpty();
                }
            }
        }
    }
    @Test
    public void testLDIFSearchSizeLimit() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                "-s", "subordinates",
                                "-z", "10",
                                ldifSearchSourceFilePath,
                                "(objectclass=*)",
                                "mail", "uid", "initials");
        assertThat(res).isEqualTo(ResultCode.SIZE_LIMIT_EXCEEDED.intValue());
        int nbEntriesRead = 0;
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            while (reader.hasNext()) {
                nbEntriesRead++;
                final Entry e = reader.readEntry();
                assertThat(e.getAllAttributes("mail")).isNotEmpty();
                assertThat(e.getAllAttributes("initials")).isNotEmpty();
                assertThat(e.getAllAttributes("cn")).isEmpty();
            }
        }
        assertThat(nbEntriesRead).isEqualTo(10);
    }
    @Test
    public void testLDIFSearchWrapping() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                "-t", "80",
                                ldifSearchSourceFilePath,
                                "(uid=user.1)",
                                "mail", "uid", "description");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        assertThatUser1DescriptionIsReadable();
        assertThat(countLdifSearchOutputFileLines()).isEqualTo(7);
    }
    @Test
    public void testLDIFSearchNoWrapping() throws Exception {
        final int res = runTool("-b", "ou=ldifsearch,o=unit tests,dc=example,dc=com",
                                "-o", ldifSearchOutputFilePath,
                                ldifSearchSourceFilePath,
                                "(uid=user.1)",
                                "mail", "uid", "description");
        assertThat(res).isEqualTo(ResultCode.SUCCESS.intValue());
        assertThatUser1DescriptionIsReadable();
        assertThat(countLdifSearchOutputFileLines()).isEqualTo(5);
    }
    private int countLdifSearchOutputFileLines() throws Exception {
        try (final BufferedReader reader = new BufferedReader(new FileReader(ldifSearchOutputFilePath))) {
            int nbLines = 0;
            while (reader.readLine() != null) {
                nbLines++;
            }
            return nbLines;
        }
    }
    private void assertThatUser1DescriptionIsReadable() throws Exception {
        try (final LDIFEntryReader reader = new LDIFEntryReader(new FileReader(ldifSearchOutputFilePath))) {
            final Entry e = reader.readEntry();
            assertThat(e.getAllAttributes("mail")).isNotEmpty();
            assertThat(e.getAllAttributes("uid")).isNotEmpty();
            final Iterable<Attribute> descriptions = e.getAllAttributes("description");
            assertThat(descriptions).isNotEmpty();
            for (final Attribute desc : descriptions) {
                assertThat(desc.firstValueAsString()).endsWith("to not wrap is specified.");
            }
            assertThat(reader.hasNext()).isFalse();
        }
    }
    @Override
    ToolConsoleApplication createInstance() {
        return new LDIFSearch(outStream, errStream);
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/MakeLDIFITCase.java
@@ -15,6 +15,7 @@
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.ldap.tools.Utils.runTool;
import static org.fest.assertions.Assertions.*;
import static org.forgerock.util.Utils.*;
import static com.forgerock.opendj.ldap.CoreMessages.*;
@@ -105,22 +106,22 @@
    @Test(dataProvider = "validArguments")
    public void testMakeLDIFValidUseCases(final String[] arguments, final LocalizableMessage expectedOut)
            throws Exception {
        run(arguments, SUCCESS, expectedOut);
        run(arguments, SUCCESS, expectedOut, "");
    }
    @Test(dataProvider = "invalidArguments")
    public void testMakeLDIFInvalidUseCases(final String[] arguments, final LocalizableMessage expectedErr)
            throws Exception {
        run(arguments, FAILURE, expectedErr);
        run(arguments, FAILURE, "", expectedErr);
    }
    /** See OPENDJ-2505 */
    @Test
    public void testMakeLDIFInvalidLineFolding() throws Exception {
        final LocalizableMessage expectedOutput = ERR_LDIF_GEN_TOOL_EXCEPTION_DURING_PARSE.get(
        final LocalizableMessage expectedErr = ERR_LDIF_GEN_TOOL_EXCEPTION_DURING_PARSE.get(
                ERR_TEMPLATE_FILE_INVALID_LEADING_SPACE.get(
                        27, " \"lineFoldingTest\":\\[\"This line should not be accepted by the parser\"\\],"));
        run(args("src/test/resources/invalid_test_template.ldif"), FAILURE, expectedOutput);
        run(args("src/test/resources/invalid_test_template.ldif"), FAILURE, "", expectedErr);
    }
    /** See OPENDJ-2505 */
@@ -130,7 +131,9 @@
        run(args("-o", tempOutputFile.toString(),
                 "-t", "80",
                 VALID_TEMPLATE_FILE_PATH),
                SUCCESS, INFO_MAKELDIF_PROCESSING_COMPLETE.get(2));
            SUCCESS,
            INFO_MAKELDIF_PROCESSING_COMPLETE.get(2),
            "");
        assertFilesAreEquals(TEMP_OUTPUT_FILE, "expected_output_80_column.ldif");
        Files.delete(tempOutputFile);
    }
@@ -139,8 +142,12 @@
    @Test
    public void testMakeLDIFSupportsLineFoldingAndLineWrapping() throws Exception {
        final Path tempOutputFile = Paths.get(TEST_RESOURCE_PATH, TEMP_OUTPUT_FILE);
        run(args("-o", tempOutputFile.toString(), "-t", "0", VALID_TEMPLATE_FILE_PATH),
                SUCCESS, INFO_MAKELDIF_PROCESSING_COMPLETE.get(2));
        run(args("-o", tempOutputFile.toString(),
                 "-t", "0",
                 VALID_TEMPLATE_FILE_PATH),
            SUCCESS,
            INFO_MAKELDIF_PROCESSING_COMPLETE.get(2),
            "");
        assertFilesAreEquals(TEMP_OUTPUT_FILE, "expected_output.ldif");
        Files.delete(tempOutputFile);
    }
@@ -150,10 +157,12 @@
                   Files.readAllBytes(Paths.get(TEST_RESOURCE_PATH, expectedOutputFileName)));
    }
    private void run(final String[] arguments, final boolean expectsSuccess, final LocalizableMessage expectedOutput)
            throws Exception {
        final int retCode = MakeLDIF.run(outStream, errStream, arguments);
        checkOuputStreams(out, err, expectedOutput, "");
    private void run(final String[] arguments,
                     final boolean expectsSuccess,
                     final Object expectedOutput,
                     final Object expectedErr) throws Exception {
        final int retCode = runTool(new MakeLDIF(outStream, errStream), arguments);
        checkOuputStreams(out, err, expectedOutput, expectedErr);
        if (expectsSuccess) {
            assertThat(retCode).isEqualTo(0);
        } else {
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolLdapServer.java
New file
@@ -0,0 +1,170 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress;
import java.io.IOException;
import org.forgerock.opendj.ldap.IntermediateResponseHandler;
import org.forgerock.opendj.ldap.LDAPClientContext;
import org.forgerock.opendj.ldap.LDAPListener;
import org.forgerock.opendj.ldap.LdapException;
import org.forgerock.opendj.ldap.LdapResultHandler;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.ServerConnection;
import org.forgerock.opendj.ldap.ServerConnectionFactory;
import org.forgerock.opendj.ldap.requests.AbandonRequest;
import org.forgerock.opendj.ldap.requests.AddRequest;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.requests.UnbindRequest;
import org.forgerock.opendj.ldap.responses.BindResult;
import org.forgerock.opendj.ldap.responses.CompareResult;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
/** Mocked request handler sketelon for tools test cases. */
class ToolLdapServer implements ServerConnectionFactory<LDAPClientContext, Integer> {
    static final String DIRECTORY_MANAGER = "cn=Directory Manager";
    static class ToolLdapServerConnection implements ServerConnection<Integer> {
        @Override
        public void handleAbandon(final Integer requestContext, final AbandonRequest request) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleBind(final Integer requestContext,
                               final int version,
                               final BindRequest request,
                               final IntermediateResponseHandler intermediateResponseHandler,
                               final LdapResultHandler<BindResult> resultHandler) {
            assertThat(request.getName()).isEqualTo(DIRECTORY_MANAGER);
            resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
        }
        @Override
        public void handleConnectionClosed(final Integer requestContext, final UnbindRequest request) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleConnectionDisconnected(final ResultCode resultCode, final String message) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleConnectionError(final Throwable error) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleAdd(final Integer requestContext,
                              final AddRequest request,
                              final IntermediateResponseHandler intermediateResponseHandler,
                              final LdapResultHandler<Result> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleCompare(final Integer requestContext,
                                  final CompareRequest request,
                                  final IntermediateResponseHandler intermediateResponseHandler,
                                  final LdapResultHandler<CompareResult> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleDelete(final Integer requestContext,
                                 final DeleteRequest request,
                                 final IntermediateResponseHandler intermediateResponseHandler,
                                 final LdapResultHandler<Result> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public <R extends ExtendedResult> void handleExtendedRequest(final Integer requestContext,
                                                                     final ExtendedRequest<R> request,
                                                                     final IntermediateResponseHandler responseHandler,
                                                                     final LdapResultHandler<R> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleModify(final Integer requestContext,
                                 final ModifyRequest request,
                                 final IntermediateResponseHandler intermediateResponseHandler,
                                 final LdapResultHandler<Result> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleModifyDN(final Integer requestContext,
                                   final ModifyDNRequest request,
                                   final IntermediateResponseHandler intermediateResponseHandler,
                                   final LdapResultHandler<Result> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
        @Override
        public void handleSearch(final Integer requestContext,
                                 final SearchRequest request,
                                 final IntermediateResponseHandler intermediateResponseHandler,
                                 final SearchResultHandler entryHandler,
                                 final LdapResultHandler<Result> resultHandler) {
            throw new UnsupportedOperationException("This method should not have been called in the test.");
        }
    }
    private LDAPListener listener;
    @Override
    public ServerConnection<Integer> handleAccept(final LDAPClientContext clientContext) throws LdapException {
        return newServerConnection();
    }
    /** Must be overriding by client code. */
    ToolLdapServerConnection newServerConnection() {
        return new ToolLdapServerConnection();
    }
    void start() throws IOException {
        listener = new LDAPListener(findFreeSocketAddress(), this);
    }
    void stop() {
        listener.close();
    }
    String getHostName() {
        return listener.getSocketAddress().getHostName();
    }
    String getPort() {
        return Integer.toString(listener.getSocketAddress().getPort());
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestCase.java
@@ -12,19 +12,79 @@
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 * Copyright 2010 Sun Microsystems, Inc.
 * Portions copyright 2012 ForgeRock AS.
 * Portions copyright 2012-2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static org.fest.assertions.Assertions.assertThat;
import static org.forgerock.util.Utils.closeSilently;
import java.io.PrintStream;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.testng.ForgeRockTestCase;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
 * An abstract class that all tools unit tests should extend. A tool represents
 * the classes found directly under the package com.forgerock.opendj.ldap.tools.
 */
@Test(groups = { "precommit", "tools", "sdk" })
@Test
public abstract class ToolsTestCase extends ForgeRockTestCase {
    ByteStringBuilder out;
    ByteStringBuilder err;
    PrintStream outStream;
    PrintStream errStream;
    @BeforeMethod
    void refreshStream() {
        out = new ByteStringBuilder();
        err = new ByteStringBuilder();
        outStream = new PrintStream(out.asOutputStream());
        errStream = new PrintStream(err.asOutputStream());
    }
    @AfterMethod
    void closeStream() {
        closeSilently(outStream, errStream);
    }
    /**
     * Tests the LDAPSearch tool with sets of invalid arguments.
     *
     * @param args
     *         The set of arguments to use for the LDAPDelete tool.
     * @param invalidReason
     *         The reason the provided set of arguments is invalid.
     */
    @Test(dataProvider = "invalidArgs")
    public void testInvalidArguments(String[] args, String invalidReason) throws Exception {
        assertThat(runTool(args)).isEqualTo(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
        assertThat(errOnSingleLine()).contains(invalidReason);
        assertThat(out.toString()).isEmpty();
    }
    /** Tests the LDAPSearch tool with the "--help" option. */
    @Test
    public void testHelp() throws Exception {
        final int success = ResultCode.SUCCESS.intValue();
        assertThat(runTool("--help")).isEqualTo(success);
        assertThat(runTool("-H")).isEqualTo(success);
        assertThat(runTool("-?")).isEqualTo(success);
    }
    String errOnSingleLine() {
        return err.toString().replace(System.lineSeparator(), " ");
    }
    int runTool(final String... args) {
        return Utils.runTool(createInstance(), args);
    }
    abstract ToolConsoleApplication createInstance();
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsTestUtils.java
New file
@@ -0,0 +1,140 @@
/*
 * The contents of this file are subject to the terms of the Common Development and
 * Distribution License (the License). You may not use this file except in compliance with the
 * License.
 *
 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
 * specific language governing permission and limitations under the License.
 *
 * When distributing Covered Software, include this CDDL Header Notice in each file and include
 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
 * Header, with the fields enclosed by brackets [] replaced by your own identifying
 * information: "Portions Copyright [year] [name of copyright owner]".
 *
 *  Copyright 2016 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID;
import static com.forgerock.opendj.cli.CliMessages.ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
/** Useful set of methods to manage tools unit tests. **/
@SuppressWarnings("javadoc")
class ToolsTestUtils {
    static Args buildArgs() {
        return new Args();
    }
    /** Helper class to represent arguments for command-line programs. */
    static class Args {
        private final List<String> args = new ArrayList<>();
        Args add(String arg) {
            args.add(arg);
            return this;
        }
        Args add(String arg, Object value) {
            args.add(arg);
            args.add(value.toString());
            return this;
        }
        Args addAll(String... args) {
            this.args.addAll(Arrays.asList(args));
            return this;
        }
        Args addAll(final Args args) {
            this.args.addAll(Arrays.asList(args.toArray()));
            return this;
        }
        String[] toArray() {
            return args.toArray(new String[args.size()]);
        }
        @Override
        public String toString() {
            return args.toString();
        }
    }
    static List<String> args(final String... arguments) {
        return Arrays.asList(arguments);
    }
    static void addValueNeededShortArgs(
            final List<List<String>> argsList, final List<LocalizableMessage> reasonList, final String... args) {
        testValueNeededArg(argsList, reasonList, "-", args);
    }
    static void addValueNeededLongArgs(
            final List<List<String>> argsList, final List<LocalizableMessage> reasonList, final String... args) {
        testValueNeededArg(argsList, reasonList, "--", args);
    }
    private static void testValueNeededArg(final List<List<String>> argsList,
                                           final List<LocalizableMessage> reasonList,
                                           final String prefix,
                                           final String[] argIDs) {
        for (final String argID : argIDs) {
            argsList.add(args(prefix + argID));
            reasonList.add(prefix.equals("--")
                                           ? ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get(argID)
                                           : ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID.get(argID));
        }
    }
    static Object[][] toDataProviderArray(final List<List<String>> argLists,
                                          final List<LocalizableMessage> reasonList) {
        final Object[][] array = new Object[argLists.size()][2];
        for (int i = 0; i < argLists.size(); i++) {
            final List<String> args = argLists.get(i);
            array[i][0] = args.toArray(new String[args.size()]);
            array[i][1] = reasonList.get(i).toString();
        }
        return array;
    }
    static String createTempFile(final String... lines) throws Exception {
        final File f = File.createTempFile("ToolsTestUtils", ".txt");
        f.deleteOnExit();
        if (lines.length > 0) {
            final StringBuilder builder = new StringBuilder();
            for (final String line : lines) {
                builder.append(line).append(System.lineSeparator());
            }
            try (final FileOutputStream fos = new FileOutputStream(f.getPath())) {
                fos.write(builder.toString().getBytes());
            }
        }
        return f.getAbsolutePath();
    }
    /** Calculates the checksum of a file. */
    static long calcChecksum(final String filePath) throws Exception {
        long checksum = 0L;
        try (final BufferedReader reader = new BufferedReader(new FileReader(new File(filePath)))) {
            String line;
            while ((line = reader.readLine()) != null) {
                checksum += line.hashCode();
            }
        }
        return checksum;
    }
}
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-emptytosingle.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-emptytosingle.ldif
@@ -4,4 +4,3 @@
objectClass: domain
dc: example
description: test
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-ignore-attributes.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-ignore-entries.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-reverse-singlevalue.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-reverse.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-reverse.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple.ldif
@@ -1,42 +1,47 @@
dn: dc=example,dc=com
changetype: modify
delete: objectClass
objectClass: domain
-
add: objectClass
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
add: objectClass
objectClass: domain
-
add: description
delete: description
description: description 1
description: description 2
description: description 3
-
delete: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: delete
dn: ou=Groups,dc=example,dc=com
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: Applications
ou: Groups
dn: ou=People,dc=example,dc=com
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: People
changetype: modify
delete: description
description: This is where you put the people
-
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: delete
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries-singlevalue.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipleentries.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries.ldif
@@ -7,13 +7,14 @@
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
@@ -23,36 +24,25 @@
dn: ou=Groups,dc=example,dc=com
changetype: delete
# objectClass: top
# objectClass: organizationalUnit
# ou: Groups
dn: ou=People,dc=example,dc=com
changetype: modify
add: description
description: This is where you put the people
-
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: delete
# objectClass: inetOrgPerson
# objectClass: person
# objectClass: top
# objectClass: organizationalPerson
# cn: Test User
# givenName: Test
# sn: User
# uid: test.user
# userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle-reverse-singlevalue.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle-reverse.ldif
New file
@@ -0,0 +1,26 @@
dn: dc=example,dc=com
changetype: modify
delete: objectClass
objectClass: organization
objectClass: dcObject
-
add: objectClass
objectClass: domain
-
delete: description
description: description 1
description: description 2
description: description 3
-
delete: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: delete
dn: ou=People,dc=example,dc=com
changetype: delete
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-multipletosingle.ldif
New file
@@ -0,0 +1,14 @@
dn: dc=example,dc=com
changetype: modify
add: description
description: test
-
dn: ou=Groups,dc=example,dc=com
changetype: delete
dn: ou=People,dc=example,dc=com
changetype: delete
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-nochanges.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singleentry-reverse.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singleentry-reverse.ldif
@@ -2,4 +2,4 @@
changetype: modify
delete: description
description: test
-
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singleentry.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singleentry.ldif
@@ -2,4 +2,4 @@
changetype: modify
add: description
description: test
-
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletoempty.ldif
New file
@@ -0,0 +1,2 @@
dn: dc=example,dc=com
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-no-wrapping.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple.ldif
@@ -7,13 +7,14 @@
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
@@ -30,13 +31,13 @@
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-reverse.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple-reverse.ldif
@@ -2,6 +2,7 @@
changetype: modify
delete: description
description: test
-
dn: ou=Groups,dc=example,dc=com
changetype: add
@@ -17,13 +18,12 @@
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple-singlevalue.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifdiff/diff-singletomultiple.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletomultiple.ldif
@@ -7,13 +7,14 @@
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
@@ -30,13 +31,13 @@
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
opendj-ldap-toolkit/src/test/resources/ldifdiff/ignore-attributes
opendj-ldap-toolkit/src/test/resources/ldifdiff/ignore-entries
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-empty.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-multipleentries.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/source-singleentry.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-empty.ldif
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-multipleentries.ldif
File was renamed from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif
@@ -29,4 +29,5 @@
sn: User
cn: Test User
userPassword: password
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
opendj-ldap-toolkit/src/test/resources/ldifdiff/target-singleentry.ldif
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-continue-on-error.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-continue-on-error.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif
@@ -3,21 +3,22 @@
objectClass: organization
objectClass: dcObject
dc: example
o: Example Corp.
description: description 1
description: description 2
description: description 3
o: Example Corp.
dn: ou=Applications,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Applications
description: An entry with this DN has already been added. If -c flag is present this modification should be ignored, otherwise an error should be raised.
dn: ou=People,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People
description: This is where you put the people
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
dn: cn=Test User,ou=People,dc=example,dc=com
objectClass: top
@@ -29,4 +30,3 @@
sn: User
cn: Test User
userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-no-wrapping.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/expected-no-wrapping.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif
@@ -3,10 +3,10 @@
objectClass: organization
objectClass: dcObject
dc: example
o: Example Corp.
description: description 1
description: description 2
description: description 3
o: Example Corp.
dn: ou=Applications,dc=example,dc=com
objectClass: top
@@ -17,7 +17,7 @@
objectClass: top
objectClass: organizationalUnit
ou: People
description: This is where you put the people
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
dn: cn=Test User,ou=People,dc=example,dc=com
objectClass: top
@@ -29,4 +29,3 @@
sn: User
cn: Test User
userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifmodify/expected.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/expected.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/target-multipleentries.ldif
@@ -3,10 +3,10 @@
objectClass: organization
objectClass: dcObject
dc: example
o: Example Corp.
description: description 1
description: description 2
description: description 3
o: Example Corp.
dn: ou=Applications,dc=example,dc=com
objectClass: top
@@ -17,7 +17,8 @@
objectClass: top
objectClass: organizationalUnit
ou: People
description: This is where you put the people
description: This is a very long description used to test that the ldif tools ma
 nage to deal with ldif wrapping standards.
dn: cn=Test User,ou=People,dc=example,dc=com
objectClass: top
@@ -29,4 +30,3 @@
sn: User
cn: Test User
userPassword: password
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications-invalid.ldif
New file
@@ -0,0 +1,3 @@
changetype: modify
delete: objectClass
objectClass: domain
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications-with-error.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications-with-error.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries.ldif
@@ -7,13 +7,14 @@
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
@@ -23,36 +24,31 @@
dn: ou=Groups,dc=example,dc=com
changetype: delete
# objectClass: top
# objectClass: organizationalUnit
# ou: Groups
dn: ou=People,dc=example,dc=com
changetype: modify
add: description
description: This is where you put the people
description: This is a very long description used to test that the ldif tools manage to deal with ldif wrapping standards.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: Applications
description: An entry with this DN has already been added. If -c flag is present this modification should be ignored, otherwise an error should be raised.
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: delete
# objectClass: inetOrgPerson
# objectClass: person
# objectClass: top
# objectClass: organizationalPerson
# cn: Test User
# givenName: Test
# sn: User
# uid: test.user
# userPassword: password
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications.ldif
File was copied from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries.ldif
@@ -7,13 +7,14 @@
objectClass: organization
objectClass: dcObject
-
add: o
o: Example Corp.
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
dn: ou=Applications,dc=example,dc=com
changetype: add
@@ -23,36 +24,25 @@
dn: ou=Groups,dc=example,dc=com
changetype: delete
# objectClass: top
# objectClass: organizationalUnit
# ou: Groups
dn: ou=People,dc=example,dc=com
changetype: modify
add: description
description: This is where you put the people
description: This is a very long description used to test that the ldif tools manage to deal with ldif
  wrapping standards.
-
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
objectClass: person
objectClass: top
objectClass: person
objectClass: organizationalPerson
cn: Test User
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
uid: test.user
cn: Test User
userPassword: password
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: delete
# objectClass: inetOrgPerson
# objectClass: person
# objectClass: top
# objectClass: organizationalPerson
# cn: Test User
# givenName: Test
# sn: User
# uid: test.user
# userPassword: password
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_1.ldif
New file
@@ -0,0 +1,17 @@
dn: dc=example,dc=com
changetype: modify
delete: objectClass
objectClass: domain
-
add: objectClass
objectClass: organization
objectClass: dcObject
-
add: description
description: description 1
description: description 2
description: description 3
-
add: o
o: Example Corp.
-
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_2.ldif
New file
@@ -0,0 +1,15 @@
dn: ou=Applications,dc=example,dc=com
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: Applications
dn: ou=Groups,dc=example,dc=com
changetype: delete
dn: ou=People,dc=example,dc=com
changetype: modify
add: description
description: This is a very long description used to test that the ldif tools manage to deal with ldif
  wrapping standards.
-
opendj-ldap-toolkit/src/test/resources/ldifmodify/modifications_part_3.ldif
New file
@@ -0,0 +1,14 @@
dn: cn=Test User,ou=People,dc=example,dc=com
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: test.user
givenName: Test
sn: User
cn: Test User
userPassword: password
dn: uid=test.user,ou=People,dc=example,dc=com
changetype: delete
opendj-ldap-toolkit/src/test/resources/ldifmodify/source.ldif
copy from opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/source-multipleentries.ldif copy to opendj-ldap-toolkit/src/test/resources/ldifmodify/source.ldif
opendj-ldap-toolkit/src/test/resources/ldifsearch.ldif
New file
@@ -0,0 +1,523 @@
dn: dc=com
objectClass: top
objectClass: domain
dc: com
dn: dc=example,dc=com
objectClass: top
objectClass: domain
dc: example
dn: o=unit tests,dc=example,dc=com
objectClass: top
objectClass: organization
o: unit tests
dn: ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: organizationalunit
ou: ldifsearch
dn: uid=user.0,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Aaccf
sn: Amar
cn: Aaccf Amar
initials: APA
employeeNumber: 0
uid: user.0
mail: user.0@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 140 374 9062
homePhone: +1 413 500 4984
pager: +1 250 147 3106
mobile: +1 086 604 6557
street: 83837 Central Street
l: Santa Barbara
st: NJ
postalCode: 57656
postalAddress: Aaccf Amar$83837 Central Street$Santa Barbara, NJ  57656
description: This is the description for Aaccf Amar.
dn: uid=user.1,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Aaren
sn: Atp
cn: Aaren Atp
initials: AVA
employeeNumber: 1
uid: user.1
mail: user.1@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 705 284 6303
homePhone: +1 119 705 9603
pager: +1 575 714 2075
mobile: +1 206 947 0972
street: 90369 Lincoln Street
l: Lafayette
st: RI
postalCode: 61381
postalAddress: Aaren Atp$90369 Lincoln Street$Lafayette, RI  61381
description: This is the very long description for Aaren Atp. This text should be automatically wrapped by ldif tools unless the specific option to not wrap is specified.
dn: uid=user.2,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Aarika
sn: Atpco
cn: Aarika Atpco
initials: AQA
employeeNumber: 2
uid: user.2
mail: user.2@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 240 116 1006
homePhone: +1 524 998 9690
pager: +1 808 020 8342
mobile: +1 885 252 0855
street: 64447 Spruce Street
l: Providence
st: WA
postalCode: 89035
postalAddress: Aarika Atpco$64447 Spruce Street$Providence, WA  89035
description: This is the description for Aarika Atpco.
dn: uid=user.3,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Aaron
sn: Atrc
cn: Aaron Atrc
initials: AAA
employeeNumber: 3
uid: user.3
mail: user.3@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 980 000 3369
homePhone: +1 870 933 0016
pager: +1 096 390 4404
mobile: +1 863 963 6402
street: 96369 Sixth Street
l: San Antonio
st: ND
postalCode: 07852
postalAddress: Aaron Atrc$96369 Sixth Street$San Antonio, ND  07852
description: This is the description for Aaron Atrc.
dn: uid=user.4,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Aartjan
sn: Aalders
cn: Aartjan Aalders
initials: AYA
employeeNumber: 4
uid: user.4
mail: user.4@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 428 104 9299
homePhone: +1 239 749 1115
pager: +1 205 023 3110
mobile: +1 188 661 6039
street: 38248 Johnson Street
l: North Platte
st: LA
postalCode: 03941
postalAddress: Aartjan Aalders$38248 Johnson Street$North Platte, LA  03941
description: This is the description for Aartjan Aalders.
dn: uid=user.5,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abagael
sn: Aasen
cn: Abagael Aasen
initials: AEA
employeeNumber: 5
uid: user.5
mail: user.5@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 093 200 1952
homePhone: +1 691 947 3811
pager: +1 932 721 7390
mobile: +1 614 906 3581
street: 23182 Park Street
l: Albany
st: ID
postalCode: 12135
postalAddress: Abagael Aasen$23182 Park Street$Albany, ID  12135
description: This is the description for Abagael Aasen.
dn: uid=user.6,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abagail
sn: Abadines
cn: Abagail Abadines
initials: AMA
employeeNumber: 6
uid: user.6
mail: user.6@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 694 083 3855
homePhone: +1 500 993 9169
pager: +1 533 256 0160
mobile: +1 230 330 8000
street: 26941 Spring Street
l: Odessa
st: NC
postalCode: 83936
postalAddress: Abagail Abadines$26941 Spring Street$Odessa, NC  83936
description: This is the description for Abagail Abadines.
dn: uid=user.7,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abahri
sn: Abazari
cn: Abahri Abazari
initials: AQA
employeeNumber: 7
uid: user.7
mail: user.7@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 161 596 0055
homePhone: +1 969 953 0776
pager: +1 457 746 5176
mobile: +1 067 931 1430
street: 46783 Broadway Street
l: Utica
st: IA
postalCode: 38700
postalAddress: Abahri Abazari$46783 Broadway Street$Utica, IA  38700
description: This is the description for Abahri Abazari.
dn: uid=user.8,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbas
sn: Abbatantuono
cn: Abbas Abbatantuono
initials: AWA
employeeNumber: 8
uid: user.8
mail: user.8@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 823 213 8309
homePhone: +1 600 875 1608
pager: +1 820 928 3917
mobile: +1 581 548 0349
street: 00731 Elm Street
l: Idaho Falls
st: UT
postalCode: 73519
postalAddress: Abbas Abbatantuono$00731 Elm Street$Idaho Falls, UT  73519
description: This is the description for Abbas Abbatantuono.
dn: uid=user.9,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbe
sn: Abbate
cn: Abbe Abbate
initials: ACA
employeeNumber: 9
uid: user.9
mail: user.9@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 279 584 8705
homePhone: +1 177 021 3181
pager: +1 384 810 8815
mobile: +1 906 839 9329
street: 17094 Pine Street
l: Sioux City
st: WV
postalCode: 41031
postalAddress: Abbe Abbate$17094 Pine Street$Sioux City, WV  41031
description: This is the description for Abbe Abbate.
dn: uid=user.10,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbey
sn: Abbie
cn: Abbey Abbie
initials: ABA
employeeNumber: 10
uid: user.10
mail: user.10@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 055 508 5801
homePhone: +1 793 080 9078
pager: +1 567 779 0093
mobile: +1 270 791 9926
street: 11399 Pine Street
l: Phoenix
st: DE
postalCode: 38670
postalAddress: Abbey Abbie$11399 Pine Street$Phoenix, DE  38670
description: This is the description for Abbey Abbie.
dn: uid=user.11,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbi
sn: Abbott
cn: Abbi Abbott
initials: AMA
employeeNumber: 11
uid: user.11
mail: user.11@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 694 313 5401
homePhone: +1 776 680 9667
pager: +1 202 494 4051
mobile: +1 945 344 9474
street: 76335 Twelfth Street
l: Austin
st: MN
postalCode: 06878
postalAddress: Abbi Abbott$76335 Twelfth Street$Austin, MN  06878
description: This is the description for Abbi Abbott.
dn: uid=user.12,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbie
sn: Abdalla
cn: Abbie Abdalla
initials: AOA
employeeNumber: 12
uid: user.12
mail: user.12@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 244 411 0729
homePhone: +1 242 003 0330
pager: +1 505 920 0623
mobile: +1 202 363 3841
street: 87230 Spruce Street
l: Bloomington
st: TN
postalCode: 02103
postalAddress: Abbie Abdalla$87230 Spruce Street$Bloomington, TN  02103
description: This is the description for Abbie Abdalla.
dn: uid=user.13,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abby
sn: Abdo
cn: Abby Abdo
initials: AXA
employeeNumber: 13
uid: user.13
mail: user.13@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 284 036 0260
homePhone: +1 038 533 8903
pager: +1 557 025 3367
mobile: +1 288 706 7620
street: 16749 Eighth Street
l: Minneapolis
st: NY
postalCode: 81286
postalAddress: Abby Abdo$16749 Eighth Street$Minneapolis, NY  81286
description: This is the description for Abby Abdo.
dn: uid=user.14,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abbye
sn: Abdollahi
cn: Abbye Abdollahi
initials: ALA
employeeNumber: 14
uid: user.14
mail: user.14@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 511 008 7304
homePhone: +1 957 901 3534
pager: +1 098 383 0133
mobile: +1 190 164 3464
street: 60320 Fourteenth Street
l: Victoria
st: LA
postalCode: 25003
postalAddress: Abbye Abdollahi$60320 Fourteenth Street$Victoria, LA  25003
description: This is the description for Abbye Abdollahi.
dn: uid=user.15,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abdalla
sn: Abdou
cn: Abdalla Abdou
initials: ARA
employeeNumber: 15
uid: user.15
mail: user.15@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 335 505 2675
homePhone: +1 339 080 8037
pager: +1 400 194 9235
mobile: +1 003 587 0243
street: 18792 Eleventh Street
l: Flint
st: AL
postalCode: 75440
postalAddress: Abdalla Abdou$18792 Eleventh Street$Flint, AL  75440
description: This is the description for Abdalla Abdou.
dn: uid=user.16,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abdallah
sn: Abdul-Nour
cn: Abdallah Abdul-Nour
initials: AHA
employeeNumber: 16
uid: user.16
mail: user.16@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 200 104 9808
homePhone: +1 544 505 0502
pager: +1 040 921 5645
mobile: +1 102 337 0237
street: 42171 Laurel Street
l: Dothan
st: MT
postalCode: 14713
postalAddress: Abdallah Abdul-Nour$42171 Laurel Street$Dothan, MT  14713
description: This is the description for Abdallah Abdul-Nour.
dn: uid=user.17,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abdul
sn: Abdulla
cn: Abdul Abdulla
initials: ACA
employeeNumber: 17
uid: user.17
mail: user.17@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 622 798 2216
homePhone: +1 008 048 2102
pager: +1 789 023 0275
mobile: +1 171 370 0198
street: 37767 Forest Street
l: Fort Wayne
st: NV
postalCode: 52716
postalAddress: Abdul Abdulla$37767 Forest Street$Fort Wayne, NV  52716
description: This is the description for Abdul Abdulla.
dn: uid=user.18,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abdullah
sn: Abdullah
cn: Abdullah Abdullah
initials: AZA
employeeNumber: 18
uid: user.18
mail: user.18@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 103 079 4939
homePhone: +1 974 673 5856
pager: +1 693 142 0500
mobile: +1 075 275 2392
street: 67821 Walnut Street
l: Superior
st: SC
postalCode: 30443
postalAddress: Abdullah Abdullah$67821 Walnut Street$Superior, SC  30443
description: This is the description for Abdullah Abdullah.
dn: uid=user.19,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abe
sn: Abe
cn: Abe Abe
initials: AGA
employeeNumber: 19
uid: user.19
mail: user.19@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 736 431 3653
homePhone: +1 940 495 0950
pager: +1 934 208 1404
mobile: +1 830 519 2697
street: 88733 Locust Street
l: Parkersburg
st: UT
postalCode: 69480
postalAddress: Abe Abe$88733 Locust Street$Parkersburg, UT  69480
description: This is the description for Abe Abe.
dn: uid=user.20,ou=ldifsearch,o=unit tests,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
givenName: Abel
sn: Abedi
cn: Abel Abedi
initials: AHA
employeeNumber: 20
uid: user.20
mail: user.20@example.com
userPassword: {SSHA}LrBv0i/fIEMDnvrCRXuZuRn5nNLdTKeQc1jBKw==
telephoneNumber: +1 806 813 1788
homePhone: +1 339 913 5003
pager: +1 838 937 9478
mobile: +1 196 300 2356
street: 76048 Fourteenth Street
l: Pocatello
st: MI
postalCode: 55008
postalAddress: Abel Abedi$76048 Fourteenth Street$Pocatello, MI  55008
description: This is the description for Abel Abedi.
opendj-server-legacy/pom.xml
@@ -90,6 +90,7 @@
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-config</artifactId>
    </dependency>
    <dependency>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-config</artifactId>
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPCompareTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPDeleteTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPModifyTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPPasswordModifyTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPSearchNoServerTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDAPSearchTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDIFDiffTestCase.java
File was deleted
opendj-server-legacy/src/test/java/org/opends/server/tools/LDIFSearchTestCase.java
File was deleted
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipleentries-reverse.ldif
File was deleted
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipletosingle-reverse.ldif
File was deleted
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-multipletosingle.ldif
File was deleted
opendj-server-legacy/tests/unit-tests-testng/resource/ldif-diff/diff-singletoempty.ldif
File was deleted
pom.xml
@@ -403,6 +403,8 @@
                            <disabledFile>legal-notices/CDDLv1_0.txt</disabledFile>
                            <disabledFile>**/tests/unit-tests-testng/resource/config-changes.ldif</disabledFile>
                            <disabledFile>opendj-rest2ldap-servlet/src/main/webapp/WEB-INF/classes/logging.properties</disabledFile>
                            <disabledFile>opendj-ldap-toolkit/src/test/resources/*.ldif</disabledFile>
                            <disabledFile>opendj-ldap-toolkit/src/test/resources/**/*.ldif</disabledFile>
                        </disabledFiles>
                    </configuration>
                </plugin>