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

Gaetan Boismal
04.18.2014 84e187d76943fe5bb6f9537968e351d36add94d8
OPENDJ-1505 (CR-3946) OpenDJ SDK tools prompt for user credentials even when none are needed
* ConnectionFactoryProvider.java DSConfig.java
** Refactoring code by removing unused constructor and fields
** Perform anonymous connection by default
* src/main[..]/ldap/tools/*.java
** Making tools not interactive
* src/test[..]/ldap/tools/*.java
** Adding some basic integration tests cases to ensure that general tools behavior is ok
* pom.xml
** Update and clean dependencies
4 files added
9 files modified
531 ■■■■■ changed files
opendj-cli/src/main/java/com/forgerock/opendj/cli/ConnectionFactoryProvider.java 30 ●●●● patch | view | raw | blame | history
opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java 2 ●●● patch | view | raw | blame | history
opendj-ldap-toolkit/pom.xml 29 ●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java 15 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java 33 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java 10 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java 8 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java 14 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java 8 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java 84 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java 103 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java 100 ●●●●● patch | view | raw | blame | history
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsITCase.java 95 ●●●●● patch | view | raw | blame | history
opendj-cli/src/main/java/com/forgerock/opendj/cli/ConnectionFactoryProvider.java
@@ -155,9 +155,6 @@
    /** The console application linked to this connection in interactive mode. */
    private final ConsoleApplication app;
    /** The LDAP options for this connection. */
    private LDAPOptions options;
    /** If this connection should be an admin connection. */
    private boolean isAdminConnection = false;
@@ -174,25 +171,7 @@
     */
    public ConnectionFactoryProvider(final ArgumentParser argumentParser,
            final ConsoleApplication app) throws ArgumentException {
        this(argumentParser, app, CliConstants.DEFAULT_ROOT_USER_DN, DEFAULT_LDAP_PORT, false, null);
    }
    /**
     * Default constructor to create a connection factory designed for use with command line tools,
     * adding basic LDAP connection arguments to the specified parser (e.g: hostname, bindname...etc).
     *
     * @param argumentParser
     *            The argument parser.
     * @param app
     *            The console application linked to this connection factory.
     * @param options
     *            The common options for this LDAP client connection.
     * @throws ArgumentException
     *             If an error occurs during parsing the arguments.
     */
    public ConnectionFactoryProvider(final ArgumentParser argumentParser, final ConsoleApplication app,
            final LDAPOptions options) throws ArgumentException {
        this(argumentParser, app, CliConstants.DEFAULT_ROOT_USER_DN, DEFAULT_LDAP_PORT, false, options);
        this(argumentParser, app, "", DEFAULT_LDAP_PORT, false);
    }
    /**
@@ -209,16 +188,13 @@
     *            The LDAP port default's value.
     * @param alwaysSSL
     *            {@code true} if this connection should be used with SSL.
     * @param options
     *            The LDAP options of this connection factory.
     * @throws ArgumentException
     *             If an error occurs during parsing the elements.
     */
    public ConnectionFactoryProvider(final ArgumentParser argumentParser,
            final ConsoleApplication app, final String defaultBindDN, final int defaultPort,
            final boolean alwaysSSL, final LDAPOptions options) throws ArgumentException {
            final boolean alwaysSSL) throws ArgumentException {
        this.app = app;
        this.options = options == null ? new LDAPOptions() : options;
        useSSLArg = CommonArguments.getUseSSL();
        if (!alwaysSSL) {
@@ -450,6 +426,8 @@
                        e);
            }
            LDAPOptions options = new LDAPOptions();
            if (sslContext != null) {
                options.setSSLContext(sslContext).setUseStartTLS(useStartTLSArg.isPresent());
            }
opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java
@@ -567,7 +567,7 @@
        ConnectionFactoryProvider cfp = null;
        try {
            cfp = new ConnectionFactoryProvider(parser, this, CliConstants.DEFAULT_ROOT_USER_DN,
                    CliConstants.DEFAULT_ADMINISTRATION_CONNECTOR_PORT, true, null);
                    CliConstants.DEFAULT_ADMINISTRATION_CONNECTOR_PORT, true);
            cfp.setIsAnAdminConnection();
            // Parse the command-line arguments provided to this program.
opendj-ldap-toolkit/pom.xml
@@ -40,9 +40,13 @@
  <dependencies>
    <dependency>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-ldap-sdk</artifactId>
      <artifactId>opendj-core</artifactId>
      <version>${project.version}</version>
      <type>pom</type>
    </dependency>
    <dependency>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-grizzly</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
@@ -62,7 +66,14 @@
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>org.forgerock</groupId>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-core</artifactId>
      <version>${project.version}</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.forgerock</groupId>
      <artifactId>forgerock-build-tools</artifactId>
      <version>${forgerockBuildToolsVersion}</version>
      <scope>test</scope>
@@ -121,6 +132,18 @@
          </execution>
        </executions>
      </plugin>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-failsafe-plugin</artifactId>
          <executions>
              <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
              </execution>
          </executions>
     </plugin>
    </plugins>
  </build>
</project>
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java
@@ -31,6 +31,7 @@
import static com.forgerock.opendj.ldap.tools.Utils.setDefaultPerfToolProperties;
import static com.forgerock.opendj.cli.Utils.filterExitCode;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -356,6 +357,18 @@
        // Nothing to do.
    }
    /**
     * Constructor to allow tests.
     *
     * @param out
     *            output stream of console application
     * @param err
     *            error stream of console application
     */
    AuthRate(PrintStream out, PrintStream err) {
        super(out, err);
    }
    /** {@inheritDoc} */
    @Override
    public boolean isInteractive() {
@@ -374,7 +387,7 @@
        return verbose.isPresent();
    }
    private int run(final String[] args) {
    int run(final String[] args) {
        // Create the command-line argument parser for use with this program.
        final LocalizableMessage toolDescription = INFO_AUTHRATE_TOOL_DESCRIPTION.get();
        final ArgumentParser argParser =
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
@@ -30,12 +30,14 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.cli.Utils.filterExitCode;
import static com.forgerock.opendj.cli.Utils.readBytesFromFile;
import static org.forgerock.util.Utils.closeSilently;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import org.forgerock.i18n.LocalizableMessage;
@@ -86,6 +88,24 @@
    }
    /**
     * Constructor to allow tests.
     *
     * @param out output stream of console application
     * @param err error stream of console application
     */
    LDAPCompare(PrintStream out, PrintStream err) {
      super(out, err);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isInteractive() {
        return false;
    }
    /**
     * {@inheritDoc}
     */
    @Override
@@ -123,7 +143,7 @@
        return ResultCode.SUCCESS.intValue();
    }
    private int run(final String[] args) {
    int run(final String[] args) {
        // Create the command-line argument parser for use with this
        // program.
        final LocalizableMessage toolDescription = INFO_LDAPCOMPARE_TOOL_DESCRIPTION.get();
@@ -382,16 +402,7 @@
                }
            }
        } finally {
            if (connection != null) {
                connection.close();
            }
            if (rdr != null) {
                try {
                    rdr.close();
                } catch (final IOException ioe) {
                    // Just ignore
                }
            }
            closeSilently(connection, rdr);
        }
        return 0;
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java
@@ -237,11 +237,19 @@
     * {@inheritDoc}
     */
    @Override
    public boolean isInteractive() {
        return false;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isVerbose() {
        return verbose.isPresent();
    }
    private int run(final String[] args) {
    int run(final String[] args) {
        // Create the command-line argument parser for use with this program.
        final LocalizableMessage toolDescription = INFO_LDAPMODIFY_TOOL_DESCRIPTION.get();
        final ArgumentParser argParser =
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java
@@ -87,6 +87,14 @@
     * {@inheritDoc}
     */
    @Override
    public boolean isInteractive() {
        return false;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isVerbose() {
        return verbose.isPresent();
    }
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java
@@ -35,6 +35,7 @@
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
@@ -214,6 +215,16 @@
        // Nothing to do.
    }
    /**
     * Constructor to allow tests.
     *
     * @param out output stream of console application
     * @param err error stream of console application
     */
    LDAPSearch(PrintStream out, PrintStream err) {
      super(out, err);
    }
    /** {@inheritDoc} */
    public boolean isInteractive() {
        return false;
@@ -225,7 +236,8 @@
        return verbose.isPresent();
    }
    private int run(final String[] args, final boolean returnMatchingEntries) {
    /** Run ldapsearch with provided command-line arguments. **/
    int run(final String[] args, final boolean returnMatchingEntries) {
        /* Create the command-line argument parser for use with this
         program.*/
        final LocalizableMessage toolDescription = INFO_LDAPSEARCH_TOOL_DESCRIPTION.get();
opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
@@ -182,6 +182,14 @@
     * {@inheritDoc}
     */
    @Override
    public boolean isInteractive() {
        return false;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isScriptFriendly() {
        return scriptFriendly.isPresent();
    }
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/AuthRateITCase.java
New file
@@ -0,0 +1,84 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS;
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.TestCaseUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class AuthRateITCase extends ToolsITCase {
    private static final String THROUGHPUT_TEXT = "Recent throughput (ops/second)";
    @DataProvider
    public Object[][] authRateArgs() throws Exception {
        return new Object[][] {
            { args(""), "", ERR_ERROR_PARSING_ARGS.get("") },
            // Simple test
            {
                args("-h", TestCaseUtils.getServerSocketAddress().getHostName(), "-p",
                    Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()), "-g", "rand(0,1000)", "-D",
                    "uid=%d,ou=people,o=test", "-w", "password", "-i", "1", "-c", "1", "-m", "10", "-f", "-S"),
                THROUGHPUT_TEXT, "" }, };
    }
    @Test(dataProvider = "authRateArgs")
    public void testITAuthRate(String[] arguments, Object expectedOut, Object expectedErr) throws Exception {
        ByteStringBuilder out = new ByteStringBuilder();
        ByteStringBuilder err = new ByteStringBuilder();
        PrintStream outStream = new PrintStream(out.asOutputStream());
        PrintStream errStream = new PrintStream(err.asOutputStream());
        try {
            AuthRate authRate = new AuthRate(outStream, errStream);
            authRate.run(arguments);
            checkOuputStreams(out, err, expectedOut, expectedErr);
            String outContent = out.toString();
            if (outContent.contains(THROUGHPUT_TEXT)) {
                // Check that there was no error in search
                String[] authRateResLines = outContent.split(System.getProperty("line.separator"));
                //Skip header line
                for (int i = 1; i < authRateResLines.length; i++) {
                    String[] authRateLineData = authRateResLines[i].split(",");
                    assertThat(authRateLineData[authRateLineData.length - 1].trim()).isEqualTo("0.0");
                }
            }
        } finally {
            closeSilently(outStream, errStream);
        }
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java
New file
@@ -0,0 +1,103 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
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 org.forgerock.util.Utils.closeSilently;
import java.io.PrintStream;
import java.util.Random;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.TestCaseUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LDAPCompareITCase extends ToolsITCase {
    private static final int NB_RAND_SIMPLE_COMPARE = 10;
    private static final int NB_OTHER_SIMPLE_SEARCH = 1;
    @DataProvider
    public Object[][] ldapCompareArgs() throws Exception {
        Object[][] data = new Object[NB_RAND_SIMPLE_COMPARE + NB_OTHER_SIMPLE_SEARCH][];
        Random rand = new Random();
        long[] randUIDs = new long[NB_RAND_SIMPLE_COMPARE];
        // Check if the help message is correctly prompted
        data[0] = new Object[] { args("--help"), INFO_LDAPCOMPARE_TOOL_DESCRIPTION.get(), "" };
        // Perform some basic comparison on random user from the test server
        for (int i = 0; i < NB_RAND_SIMPLE_COMPARE; i++) {
            randUIDs[i] = Math.round(rand.nextInt(1000));
        }
        for (int i = 0; i < NB_RAND_SIMPLE_COMPARE; i++) {
            long firstUID = randUIDs[i];
            // For first test, ensure that both uids are equals
            long secondUID = i == 0 ? firstUID : randUIDs[rand.nextInt(randUIDs.length)];
            data[i + NB_OTHER_SIMPLE_SEARCH] = produceLDAPCompareBasicTest(firstUID, secondUID);
        }
        return data;
    }
    private Object[] produceLDAPCompareBasicTest(long firstUID, long secondUID) {
        String uid = String.format("uid:user.%d", firstUID);
        String dn = String.format("uid=user.%d,ou=people,o=test", secondUID);
        LocalizableMessage messageToCheck = INFO_COMPARE_OPERATION_RESULT_FALSE.get(dn);
        if (firstUID == secondUID) {
            messageToCheck = INFO_COMPARE_OPERATION_RESULT_TRUE.get(dn);
        }
        return new Object[] {
            args("-h", TestCaseUtils.getServerSocketAddress().getHostName(), "-p",
                Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()), uid, dn), messageToCheck, "" };
    }
    @Test(dataProvider = "ldapCompareArgs")
    public void testITLDAPSearch(String[] arguments, Object expectedOut, Object expectedErr) throws Exception {
        ByteStringBuilder out = new ByteStringBuilder();
        ByteStringBuilder err = new ByteStringBuilder();
        PrintStream outStream = new PrintStream(out.asOutputStream());
        PrintStream errStream = new PrintStream(err.asOutputStream());
        try {
            LDAPCompare ldapCompare = new LDAPCompare(outStream, errStream);
            ldapCompare.run(arguments);
            checkOuputStreams(out, err, expectedOut, expectedErr);
        } finally {
            closeSilently(outStream, errStream);
        }
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java
New file
@@ -0,0 +1,100 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS;
import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_TOOL_RESULT_CODE;
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 org.forgerock.util.Utils.closeSilently;
import java.io.PrintStream;
import java.util.Random;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.TestCaseUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
 * Simple integration tests to check the ldapsearch command
 */
@SuppressWarnings("javadoc")
public class LDAPSearchITCase extends ToolsITCase {
    private static final int NB_RAND_SIMPLE_SEARCH = 10;
    private static final int NB_OTHER_SIMPLE_SEARCH = 2;
    @DataProvider
    public Object[][] ldapSearchArgs() throws Exception {
        Object[][] data = new Object[NB_RAND_SIMPLE_SEARCH + NB_OTHER_SIMPLE_SEARCH][];
        // Check if the help message is correctly prompted
        data[0] = new Object[] { args("--help"), INFO_LDAPSEARCH_TOOL_DESCRIPTION.get(), "" };
        // Check that there is a error message if no arguments were given to the
        // ldapsearch command
        data[1] = new Object[] { args(""), "", ERR_ERROR_PARSING_ARGS.get("") };
        // Perform some basic ldapsearch for random user in the test server
        for (int i = 0; i < NB_RAND_SIMPLE_SEARCH; i++) {
            long userID = new Random().nextInt(1000);
            data[i + NB_OTHER_SIMPLE_SEARCH] = produceLDAPSearchBasicTestCase(userID);
        }
        return data;
    }
    private Object[] produceLDAPSearchBasicTestCase(long userID) {
        String dn = String.format("uid=user.%d,ou=people,o=test", userID);
        LocalizableMessage matchEntryCnt = INFO_LDAPSEARCH_MATCHING_ENTRY_COUNT.get(1);
        LocalizableMessage resultSuccess =
            ERR_TOOL_RESULT_CODE.get(ResultCode.SUCCESS.intValue(), ResultCode.SUCCESS.getName().toString());
        return new Object[] {
            args("--countEntries", "-h", TestCaseUtils.getServerSocketAddress().getHostName(), "-p",
                Integer.toString(TestCaseUtils.getServerSocketAddress().getPort()), "-b", dn, "(uid=user.%d)", "uid"),
            matchEntryCnt, resultSuccess };
    }
    @Test(dataProvider = "ldapSearchArgs")
    public void testITLDAPSearch(String[] arguments, Object expectedOut, Object expectedErr) throws Exception {
        ByteStringBuilder out = new ByteStringBuilder();
        ByteStringBuilder err = new ByteStringBuilder();
        PrintStream outStream = new PrintStream(out.asOutputStream());
        PrintStream errStream = new PrintStream(err.asOutputStream());
        try {
            LDAPSearch ldapSearch = new LDAPSearch(outStream, errStream);
            ldapSearch.run(arguments, false);
            checkOuputStreams(out, err, expectedOut, expectedErr);
        } finally {
            closeSilently(outStream, errStream);
        }
    }
}
opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/ToolsITCase.java
New file
@@ -0,0 +1,95 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2014 ForgeRock AS.
 */
package com.forgerock.opendj.ldap.tools;
import static com.forgerock.opendj.cli.Utils.MAX_LINE_WIDTH;
import static com.forgerock.opendj.cli.Utils.wrapText;
import static org.fest.assertions.Assertions.assertThat;
import java.io.UnsupportedEncodingException;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.TestCaseUtils;
import org.forgerock.testng.ForgeRockTestCase;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
/**
 * Class used for the toolkit integration tests
 */
public abstract class ToolsITCase extends ForgeRockTestCase {
    @BeforeClass
    void setUp() throws Exception {
        TestCaseUtils.startServer();
    }
    @AfterClass
    void tearDown() throws Exception {
        TestCaseUtils.stopServer();
    }
    /**
     * Check both out and err outputs streams
     *
     * @param out
     *            output stream from the toolkit application
     * @param err
     *            error stream from the toolkit application
     * @param expectedOutput
     *            String or LocalizedMessage expected on output
     * @param expectedError
     *            String or LocalizedMessage expected on error output
     * @throws UnsupportedEncodingException
     */
    protected void checkOuputStreams(ByteStringBuilder out, ByteStringBuilder err, Object expectedOutput,
        Object expectedError) throws Exception {
        // Check error output
        checkOutputStream(out, expectedOutput);
        checkOutputStream(err, expectedError);
    }
    private void checkOutputStream(ByteStringBuilder out, Object expectedOutput) {
        String toCompare = expectedOutput.toString();
        if (expectedOutput instanceof LocalizableMessage) {
            toCompare = wrapText((LocalizableMessage) expectedOutput, MAX_LINE_WIDTH);
        }
        if (toCompare.isEmpty()) {
            assertThat(out.toString().length()).isEqualTo(0);
        } else {
            assertThat(out.toString()).contains(toCompare);
        }
    }
    /** Arguments passed to the command */
    protected String[] args(String... arguments) {
        return arguments;
    }
}