startServer method.
*/
public static boolean SERVER_STARTED = false;
/**
* The LDAP port the server is bound to on start.
*/
private static int serverLdapPort;
/**
* The Administration port the server is bound to on start.
*/
private static int serverAdminPort;
/**
* The JMX port the server is bound to on start.
*/
private static int serverJmxPort;
/**
* The LDAPS port the server is bound to on start.
*/
private static int serverLdapsPort;
/**
* Incremented by one each time the server has restarted.
*/
private static int serverRestarts = 0;
/**
* The config directory in the test environment.
*/
private static File testConfigDir;
/**
* Starts the Directory Server so that it will be available for use while
* running the unit tests. This will only actually start the server once, so
* subsequent attempts to start it will be ignored because it will already be
* available.
*
* @throws IOException If a problem occurs while interacting with the
* filesystem to prepare the test package root.
*
* @throws InitializationException If a problem occurs while starting the
* server.
*
* @throws ConfigException If there is a problem with the server
* configuration.
*/
public static void startServer()
throws IOException, InitializationException, ConfigException,
DirectoryException
{
try {
if (SERVER_STARTED)
{
return;
}
InvocationCounterPlugin.resetStartupCalled();
// Retrieves the location of a typical installation directory to use as a
// source to build our test instance.
String installedRoot = System.getProperty(PROPERTY_INSTALLED_ROOT);
// Get the build root and use it to create a test package directory.
String buildRoot = System.getProperty(PROPERTY_BUILD_ROOT);
String buildDirStr = System.getProperty(PROPERTY_BUILD_DIR,
buildRoot + File.separator + "build");
File buildDir = new File(buildDirStr);
File unitRoot = new File(buildDir, "unit-tests");
File testInstallRoot = null;
File testInstanceRoot = null;
if (installedRoot == null) {
testInstallRoot = new File(unitRoot, "package-install");
testInstanceRoot = new File(unitRoot, "package-instance");
} else {
testInstallRoot = new File(unitRoot, "package");
testInstanceRoot = testInstallRoot;
}
File testSrcRoot = new File(buildRoot + File.separator + "tests" +
File.separator + "unit-tests-testng");
boolean cleanupRequired = true;
String cleanupRequiredString =
System.getProperty(PROPERTY_CLEANUP_REQUIRED, "true");
if (cleanupRequiredString.equalsIgnoreCase("false"))
{
cleanupRequired = false;
}
if (cleanupRequired) {
if (testInstallRoot.exists())
{
deleteDirectory(testInstallRoot);
}
if (testInstanceRoot.exists())
{
deleteDirectory(testInstanceRoot);
}
testInstallRoot.mkdirs();
testInstanceRoot.mkdirs();
}
File testInstanceSchema =
new File (testInstanceRoot, "config" + File.separator + "schema");
testInstanceSchema.mkdirs();
//db_verify is second jeb backend used by the jeb verify test cases
//db_rebuild is the third jeb backend used by the jeb rebuild test cases
//db_unindexed is the forth backend used by the unindexed search privilege
//test cases
String[] installSubDirectories = { "bin", "lib", "bat", "config"};
String[] instanceSubDirectories = { "bak", "changelogDb", "classes",
"config", "db", "import-tmp", "db_verify",
"ldif", "locks", "logs", "db_rebuild",
"db_unindexed", "db_index_test",
"db_import_test"};
for (String s : installSubDirectories)
{
new File(testInstallRoot, s).mkdir();
}
for (String s : instanceSubDirectories)
{
new File(testInstanceRoot, s).mkdir();
}
// Copy the configuration, schema, and MakeLDIF resources into the
// appropriate place under the test package.
File serverClassesDir = new File(buildDir, "classes");
File unitClassesDir = new File(unitRoot, "classes");
File libDir = new File(buildRoot, "lib");
File resourceDir = new File(buildRoot, "resource");
File testResourceDir = new File(testSrcRoot, "resource");
// Set the class variable
testConfigDir = new File(testInstanceRoot, "config");
File testSchemaDir = new File(testInstallRoot, "config");
File testClassesDir = new File(testInstanceRoot, "classes");
File testLibDir = new File(testInstallRoot, "lib");
File testBinDir = new File(testInstallRoot, "bin");
// Snmp resource
String opendmkJarFileLocation =
System.getProperty(PROPERTY_OPENDMK_LOCATION);
File opendmkJar = new File(opendmkJarFileLocation, "jdmkrt.jar");
File snmpResourceDir = new File(buildRoot + File.separator + "src" +
File.separator + "snmp" + File.separator +
"resource");
File snmpConfigDir = new File(snmpResourceDir, "config");
File testSnmpResourceDir = new File (testConfigDir + File.separator +
"snmp");
if (Boolean.getBoolean(PROPERTY_COPY_CLASSES_TO_TEST_PKG))
{
copyDirectory(serverClassesDir, testClassesDir);
copyDirectory(unitClassesDir, testClassesDir);
}
if (installedRoot != null)
{
copyDirectory(new File(installedRoot), testInstallRoot);
// Get the instance location
}
else
{
copyDirectory(libDir, testLibDir);
copyDirectory(new File(resourceDir, "bin"), testBinDir);
copyDirectory(new File(resourceDir, "config"), testConfigDir);
copyDirectory(new File(resourceDir, "schema"),
new File(testSchemaDir, "schema"));
copyDirectory(new File(resourceDir, "MakeLDIF"),
new File(testConfigDir, "MakeLDIF"));
copyDirectory(new File(snmpResourceDir, "security"),
new File(testSnmpResourceDir, "security"));
copyFile(new File(testResourceDir, "server.keystore"),
new File(testConfigDir, "server.keystore"));
copyFile(new File(testResourceDir, "server.truststore"),
new File(testConfigDir, "server.truststore"));
copyFile(new File(testResourceDir, "client.keystore"),
new File(testConfigDir, "client.keystore"));
copyFile(new File(testResourceDir, "client.truststore"),
new File(testConfigDir, "client.truststore"));
copyFile(new File(testResourceDir, "server-cert.p12"),
new File(testConfigDir, "server-cert.p12"));
copyFile(new File(testResourceDir, "client-cert.p12"),
new File(testConfigDir, "client-cert.p12"));
// Update the install.loc file
File installLoc = new File(testInstallRoot + File.separator
+ "instance.loc");
installLoc.deleteOnExit();
FileWriter w = new FileWriter(installLoc);
w.write(testInstanceRoot.getAbsolutePath());
w.close();
if (opendmkJar.exists())
{
appendFile(new File(snmpConfigDir, "config.snmp.ldif"),
new File(testConfigDir, "config.ldif"));
}
for (File f : testBinDir.listFiles())
{
try
{
FilePermission.setPermissions(f, FilePermission.decodeUNIXMode("755"));
} catch (Exception e) {}
}
// Make the shell scripts in the bin directory executable, if possible.
OperatingSystem os = DirectoryServer.getOperatingSystem();
if ((os != null) && OperatingSystem.isUNIXBased(os) &&
FilePermission.canSetPermissions())
{
try
{
FilePermission perm = FilePermission.decodeUNIXMode("755");
for (File f : testBinDir.listFiles())
{
if (f.getName().endsWith(".sh"))
{
FilePermission.setPermissions(f, perm);
}
}
} catch (Exception e) {}
}
}
// Find some free ports for the listeners and write them to the
// config-chamges.ldif file.
ServerSocket serverLdapSocket = null;
ServerSocket serverAdminSocket = null;
ServerSocket serverJmxSocket = null;
ServerSocket serverLdapsSocket = null;
String ldapPort = System.getProperty(PROPERTY_LDAP_PORT);
if (ldapPort == null)
{
serverLdapSocket = bindFreePort();
serverLdapPort = serverLdapSocket.getLocalPort();
}
else
{
serverLdapPort = Integer.valueOf(ldapPort);
serverLdapSocket = bindPort(serverLdapPort);
}
String adminPort = System.getProperty(PROPERTY_ADMIN_PORT);
if (adminPort == null)
{
serverAdminSocket = bindFreePort();
serverAdminPort = serverAdminSocket.getLocalPort();
}
else
{
serverAdminPort = Integer.valueOf(adminPort);
serverAdminSocket = bindPort(serverAdminPort);
}
serverJmxSocket = bindFreePort();
serverJmxPort = serverJmxSocket.getLocalPort();
serverLdapsSocket = bindFreePort();
serverLdapsPort = serverLdapsSocket.getLocalPort();
String defaultConfigChangeFile = testResourceDir + File.separator
+ "config-changes.ldif";
String configChangeFile = System.getProperty(
PROPERTY_CONFIG_CHANGE_FILE, defaultConfigChangeFile);
BufferedReader reader = new BufferedReader(new FileReader(
new File(configChangeFile)));
FileOutputStream outFile = new FileOutputStream(
new File(testConfigDir, "config-changes.ldif"));
PrintStream writer = new PrintStream(outFile);
String line = reader.readLine();
while(line != null)
{
line = line.replaceAll("#ldapport#", String.valueOf(serverLdapPort));
line = line.replaceAll("#adminport#", String.valueOf(serverAdminPort));
line = line.replaceAll("#jmxport#", String.valueOf(serverJmxPort));
line = line.replaceAll("#ldapsport#", String.valueOf(serverLdapsPort));
writer.println(line);
line = reader.readLine();
}
writer.close();
outFile.close();
reader.close();
serverLdapSocket.close();
serverAdminSocket.close();
serverJmxSocket.close();
serverLdapsSocket.close();
// Create a configuration for the server.
DirectoryEnvironmentConfig config = new DirectoryEnvironmentConfig();
config.setServerRoot(testInstallRoot);
config.setInstanceRoot(testInstanceRoot);
config.setForceDaemonThreads(true);
config.setConfigClass(ConfigFileHandler.class);
config.setConfigFile(new File(testConfigDir, "config.ldif"));
AccessLogger.addAccessLogPublisher(
TextAccessLogPublisher.getStartupTextAccessPublisher(
ACCESS_TEXT_WRITER, false));
ErrorLogger.addErrorLogPublisher(
TextErrorLogPublisher.getStartupTextErrorPublisher(
ERROR_TEXT_WRITER));
DebugLogger.addDebugLogPublisher(
TextDebugLogPublisher.getStartupTextDebugPublisher(
DEBUG_TEXT_WRITER));
EmbeddedUtils.startServer(config);
assertTrue(InvocationCounterPlugin.startupCalled());
// Save config.ldif for when we restart the server
backupServerConfigLdif();
SERVER_STARTED = true;
initializeTestBackend(true);
} catch (IOException e) {
e.printStackTrace(originalSystemErr);
throw e;
} catch (NumberFormatException e) {
e.printStackTrace(originalSystemErr);
throw e;
} catch (InitializationException e) {
e.printStackTrace(originalSystemErr);
throw e;
} catch (ConfigException e) {
e.printStackTrace(originalSystemErr);
throw e;
} catch (DirectoryException e) {
e.printStackTrace(originalSystemErr);
throw e;
}
}
/**
* Similar to startServer, but it will restart the server each time it is
* called. Since this is somewhat expensive, it should be called under
* two circumstances. Either in an @AfterClass method for a test that
* makes lots of configuration changes to the server, or in a @BeforeClass
* method for a test that is very sensitive to running in a clean server.
*
* @throws IOException If a problem occurs while interacting with the
* filesystem to prepare the test package root.
*
* @throws InitializationException If a problem occurs while starting the
* server.
*
* @throws ConfigException If there is a problem with the server
* configuration.
*/
public static synchronized void restartServer()
throws IOException, InitializationException, ConfigException,
DirectoryException, Exception
{
if (!SERVER_STARTED) {
startServer();
return;
}
try {
long startMs = System.currentTimeMillis();
clearLoggersContents();
clearJEBackends();
restoreServerConfigLdif();
// We need it to be recreated and reregistered
MemoryBackend memoryBackend =
(MemoryBackend) DirectoryServer.getBackend(TEST_BACKEND_ID);
if (memoryBackend != null)
{
memoryBackend.finalizeBackend();
DirectoryServer.deregisterBackend(memoryBackend);
}
EmbeddedUtils.restartServer(null, null, DirectoryServer.getEnvironmentConfig());
initializeTestBackend(true);
// This generates too much noise, so it's disabled by default.
// outputLogContentsIfError("Potential problem during in-core restart. You be the judge.");
// Keep track of these so we can report how long they took in the test summary
long durationMs = System.currentTimeMillis() - startMs;
restartTimesMs.add(durationMs);
serverRestarts++;
} catch (Exception e) {
e.printStackTrace(originalSystemErr);
throw e;
}
}
public static ListTEST_ROOT_DN_STRING constant if they wish.
*
* @param createBaseEntry Indicate whether to automatically create the base
* entry and add it to the backend.
*
* @throws Exception If an unexpected problem occurs.
*/
public static void initializeTestBackend(boolean createBaseEntry)
throws IOException, InitializationException, ConfigException,
DirectoryException
{
initializeMemoryBackend(
TEST_BACKEND_ID, TEST_ROOT_DN_STRING, createBaseEntry);
}
/**
* Initializes a memory-based backend that may be used to perform operations
* while testing the server. This will ensure that the memory backend is
* created in the server if it does not yet exist, and that it is empty.
*
* @param backendID the ID of the backend to create
* @param namingContext the naming context to create in the backend
* @param createBaseEntry Indicate whether to automatically create the base
* entry and add it to the backend.
*
* @throws Exception If an unexpected problem occurs.
*/
public static void initializeMemoryBackend(
String backendID,
String namingContext,
boolean createBaseEntry
) throws IOException, InitializationException, ConfigException,
DirectoryException
{
startServer();
DN baseDN = DN.decode(namingContext);
// Retrieve backend. Warning: it is important to perform this each time,
// because a test may have disabled then enabled the backend (i.e a test
// performing an import task). As it is a memory backend, when the backend
// is re-enabled, a new backend object is in fact created and old reference
// to memory backend must be invalidated. So to prevent this problem, we
// retrieve the memory backend reference each time before cleaning it.
MemoryBackend memoryBackend =
(MemoryBackend)DirectoryServer.getBackend(backendID);
if (memoryBackend == null)
{
memoryBackend = new MemoryBackend();
memoryBackend.setBackendID(backendID);
memoryBackend.setBaseDNs(new DN[] {baseDN});
memoryBackend.initializeBackend();
DirectoryServer.registerBackend(memoryBackend);
}
memoryBackend.clearMemoryBackend();
if (createBaseEntry)
{
Entry e = createEntry(baseDN);
memoryBackend.addEntry(e, null);
}
}
/**
* Clears a memory-based backend.
*/
public static void clearMemoryBackend(String backendID) throws Exception
{
MemoryBackend memoryBackend =
(MemoryBackend) DirectoryServer.getBackend(backendID);
if (memoryBackend != null)
memoryBackend.clearMemoryBackend();
}
/**
* Clears all the entries from the JE backend determined by the
* be id passed into the method.
* @param createBaseEntry Indicate whether to automatically create the base
* entry and add it to the backend.
*
* @param beID The be id to clear.
*
* @param dn The suffix of the backend to create if the the createBaseEntry
* boolean is true.
*
* @throws Exception If an unexpected problem occurs.
*/
public static void clearJEBackend(boolean createBaseEntry, String beID, String dn)
throws Exception
{
BackendImpl backend = (BackendImpl)DirectoryServer.getBackend(beID);
RootContainer rootContainer = backend.getRootContainer();
if (rootContainer != null) {
for (EntryContainer ec : rootContainer.getEntryContainers())
{
ec.clear();
assertEquals(ec.getHighestEntryID().longValue(), 0L);
}
rootContainer.resetNextEntryID();
if (createBaseEntry)
{
DN baseDN = DN.decode(dn);
Entry e = createEntry(baseDN);
backend = (BackendImpl)DirectoryServer.getBackend(beID);
backend.addEntry(e, null);
}
}
}
/**
* This was used to track down which test was trashing the indexes.
* We left it here because it might be useful again.
*/
public static void printUntrustedIndexes()
{
try {
BackendImpl backend = (BackendImpl)DirectoryServer.getBackend("userRoot");
if (backend == null) {
return;
}
RootContainer rootContainer = backend.getRootContainer();
for (EntryContainer ec : rootContainer.getEntryContainers())
{
List
* Also take a look at the makeLdif method below since this makes
* expressing LDIF a little bit cleaner.
*
* @param ldif of the entries to parse.
* @return a List of EntryS parsed from the ldif string.
* @see #makeLdif
*/
public static List
* Also take a look at the makeLdif method below since this makes
* expressing LDIF a little bit cleaner.
*
* @return the first Entry parsed from the ldif String
* @see #makeLdif
*/
public static Entry entryFromLdifString(String ldif) throws Exception {
return entriesFromLdifString(ldif).get(0);
}
/**
* This method provides the minor convenience of not having to specify the
* newline character at the end of every line of LDIF in test code.
* This is an admittedly small advantage, but it does make things a little
* easier and less error prone. For example, this
*
* Note: were possible the {@link #dsconfig(String...)} method
* should be used in preference to this method in order to perform
* end-to-end testing.
*
* @return Returns the root configuration associated with the active
* server instance.
* @throws Exception
* If the management context could not be initialized
* against the active server instance.
*/
public static RootCfgClient getRootConfiguration() throws Exception
{
LDAPConnection connection = JNDIDirContextAdaptor.simpleSSLBind(
"127.0.0.1",
serverAdminPort,
"cn=Directory Manager",
"password");
ManagementContext context = LDAPManagementContext
.createFromContext(connection);
return context.getRootConfiguration();
}
/**
* Return a String representation of all of the current threads.
* @return a dump of all Threads on the server
*/
public static String threadStacksToString()
{
Map
private static final String JOHN_SMITH_LDIF = TestCaseUtils.makeLdif(
"dn: cn=John Smith,dc=example,dc=com",
"objectclass: inetorgperson",
"cn: John Smith",
"sn: Smith",
"givenname: John");
is a
private static final String JOHN_SMITH_LDIF =
"dn: cn=John Smith,dc=example,dc=com\n" +
"objectclass: inetorgperson\n" +
"cn: John Smith\n" +
"sn: Smith\n" +
"givenname: John\n";
*
* @return the concatenation of each line followed by a newline character
*/
public static String makeLdif(String... lines) {
StringBuilder buffer = new StringBuilder();
for (String line : lines) {
buffer.append(line).append(EOL);
}
// Append an extra line so we can append LDIF Strings.
buffer.append(EOL);
return buffer.toString();
}
/**
* This is a convenience method that constructs an Entry from the specified
* lines of LDIF. Here's a sample usage
*
Entry john = TestCaseUtils.makeEntry(
"dn: cn=John Smith,dc=example,dc=com",
"objectclass: inetorgperson",
"cn: John Smith",
"sn: Smith",
"givenname: John");
* @see #makeLdif
*/
public static Entry makeEntry(String... lines) throws Exception {
return entryFromLdifString(makeLdif(lines));
}
/**
* This is a convenience method that constructs an List of EntryS from the
* specified lines of LDIF. Here's a sample usage
*
List
* @see #makeLdif
*/
public static List
* An assertion will be used to ensure that the dsconfig invocation is
* successful. If running dsconfig returns a non-zero result, then an
* assertion error will be thrown.
*
* @param args The set of arguments that should be provided when invoking
* the dsconfig tool
*/
public static void dsconfig(String... args)
{
String hostName;
try {
hostName = InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
hostName="Unknown (" + e + ")";
}
String[] fullArgs = new String[args.length + 11];
fullArgs[0] = "-h";
fullArgs[1] = hostName;
fullArgs[2] = "-p";
fullArgs[3] = String.valueOf(serverAdminPort);
fullArgs[4] = "-D";
fullArgs[5] = "cn=Directory Manager";
fullArgs[6] = "-w";
fullArgs[7] = "password";
fullArgs[8] = "-n";
fullArgs[9] = "--noPropertiesFile";
fullArgs[10] = "-X";
System.arraycopy(args, 0, fullArgs, 11, args.length);
assertEquals(DSConfig.main(fullArgs, false, System.out, System.err), 0);
}
/**
* Gets the root configuration associated with the active server
* instance. This root configuration can then be used to access and
* modify the server's configuration using that administration
* framework's strongly typed API.
*