working through multiuser; need to integrate solr and activemq

This commit is contained in:
Greg DiCristofaro 2020-11-02 15:59:30 -05:00
parent 306a7f71f6
commit ba289ae59c
3 changed files with 115 additions and 75 deletions

View File

@ -10,6 +10,16 @@
<property name="thirdparty.dir" value="${basedir}/../thirdparty" /> <property name="thirdparty.dir" value="${basedir}/../thirdparty" />
<!-- import ant-contrib tools -->
<property name="ant-contrib.dir" value="${thirdparty.dir}/ant-contrib/1.0b3" />
<property name="ant.contrib.jar" value="${ant-contrib.dir}/ant-contrib.jar" />
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${ant.contrib.jar}"/>
</classpath>
</taskdef>
<property name="modules.dir" value="${basedir}/release/modules/" /> <property name="modules.dir" value="${basedir}/release/modules/" />
<property name="ext.dir" value="${modules.dir}/ext" /> <property name="ext.dir" value="${modules.dir}/ext" />
<property name="test-input" location="test/qa-functional/data"/> <property name="test-input" location="test/qa-functional/data"/>
@ -212,45 +222,34 @@
<!--map from integration-test variables to test-qa-functional-sys-prop so they will be used as system properties--> <!--map from integration-test variables to test-qa-functional-sys-prop so they will be used as system properties-->
<target name="setup-integration-props" depends="init"> <target name="setup-integration-props" depends="init">
<sequential> <propertyselector
<condition property="test-qa-functional-sys-prop.rootTestOutputPath" value="${integration-test.rootTestOutputPath}"> property="integration-test-sys-props"
<isset property="integration-test.rootTestOutputPath" /> match="^integration-test\.(.*)"
</condition> select="\1"
delimiter=","
casesensitive="true"
distinct="true"
/>
<condition property="test-qa-functional-sys-prop.diffOutputPath" value="${integration-test.diffOutputPath}"> <for list="${integration-test-sys-props}" param="integration-test-sys-prop">
<isset property="integration-test.diffOutputPath" /> <sequential>
</condition> <property
name="test-qa-functional-sys-prop.@{integration-test-sys-prop}"
<condition property="test-qa-functional-sys-prop.rootGoldPath" value="${integration-test.rootGoldPath}"> value="${integration-test.@{integration-test-sys-prop}}"
<isset property="integration-test.rootGoldPath" /> />
</condition> </sequential>
</for>
<condition property="test-qa-functional-sys-prop.workingDirectory" value="${integration-test.workingDirectory}">
<isset property="integration-test.workingDirectory" />
</condition>
<condition property="test-qa-functional-sys-prop.rootTestSuitesPath" value="${integration-test.rootTestSuitesPath}">
<isset property="integration-test.rootTestSuitesPath" />
</condition>
<condition property="test-qa-functional-sys-prop.rootCaseOutputPath" value="${integration-test.rootCaseOutputPath}">
<isset property="integration-test.rootCaseOutputPath" />
</condition>
<condition property="test-qa-functional-sys-prop.configFile" value="${integration-test.configFile}">
<isset property="integration-test.configFile" />
</condition>
</sequential>
</target> </target>
<!-- <!--
The paths specified in 'module.run.classpath' are incorporated into the manifest of a jar and then the path to the The paths specified in 'module.run.classpath' are incorporated into the manifest of a jar and then the path to the
jar is used as part of the classpath for '-do-junit' instead of 'module.run.classpath'. This was done to prevent jar is used as part of the classpath for '-do-junit' instead of 'module.run.classpath'. This was done to prevent
classpath length issues on windows. More information on this technique can be found here: classpath length issues on windows. More information on this technique can be found here:
https://stackoverflow.com/a/201969. https://stackoverflow.com/a/201969.
--> -->
<target name="integration-pathing-jar" depends="projectized-common.test-init" if="testing-pathing-jar.should-create"> <target name="integration-pathing-jar" depends="projectized-common.test-init">
<sequential> <sequential>
<!--set up pathing jar based on module.run.classpath as classpath--> <!--set up pathing jar based on module.run.classpath as classpath-->
<path id="test.qa-functional.pathing-jar.module-cp.classpath" path="${module.run.classpath}"/> <path id="test.qa-functional.pathing-jar.module-cp.classpath" path="${module.run.classpath}"/>
@ -287,7 +286,6 @@
<target name="integration-test"> <target name="integration-test">
<!--We want only integration testing to run from this--> <!--We want only integration testing to run from this-->
<sequential> <sequential>
<property name="testing-pathing-jar.should-create" value="true"/>
<property name="test.includes" value="**/org/sleuthkit/autopsy/integrationtesting/TestRunner.class"/> <property name="test.includes" value="**/org/sleuthkit/autopsy/integrationtesting/TestRunner.class"/>
<antcall target="projectized-common.test-qa-functional" /> <antcall target="projectized-common.test-qa-functional" />
</sequential> </sequential>

View File

@ -35,6 +35,7 @@ import java.util.stream.Stream;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.openide.util.Exceptions;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.Pair; import org.openide.util.Pair;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -42,6 +43,9 @@ import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.casemodule.CaseActionException; import org.sleuthkit.autopsy.casemodule.CaseActionException;
import org.sleuthkit.autopsy.casemodule.CaseDetails; import org.sleuthkit.autopsy.casemodule.CaseDetails;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresConnectionSettings;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.core.UserPreferencesException;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.TimeStampUtils; import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor; import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
@ -50,11 +54,15 @@ import org.sleuthkit.autopsy.datasourceprocessors.DataSourceProcessorUtility;
import org.sleuthkit.autopsy.ingest.IngestJobSettings; import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.integrationtesting.DiffService.DiffServiceException; import org.sleuthkit.autopsy.integrationtesting.DiffService.DiffServiceException;
import org.sleuthkit.autopsy.integrationtesting.config.ConfigDeserializer; import org.sleuthkit.autopsy.integrationtesting.config.ConfigDeserializer;
import org.sleuthkit.autopsy.integrationtesting.config.ConnectionConfig;
import org.sleuthkit.autopsy.integrationtesting.config.EnvConfig; import org.sleuthkit.autopsy.integrationtesting.config.EnvConfig;
import org.sleuthkit.autopsy.integrationtesting.config.TestingConfig; import org.sleuthkit.autopsy.integrationtesting.config.TestingConfig;
import org.sleuthkit.autopsy.testutils.IngestUtils; import org.sleuthkit.autopsy.testutils.IngestUtils;
import org.sleuthkit.autopsy.testutils.TestUtilsException; import org.sleuthkit.autopsy.testutils.TestUtilsException;
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskData.DbType;
/** /**
* Main entry point for running integration tests. Handles processing * Main entry point for running integration tests. Handles processing
@ -127,39 +135,84 @@ public class IntegrationTestService {
} }
EnvConfig envConfig = config.getEnvConfig(); EnvConfig envConfig = config.getEnvConfig();
CaseDbConnectionInfo oldSettings = null;
try {
oldSettings = pushNewMultiUserSettings(envConfig.getConnectionInfo());
} catch (UserPreferencesException ex) {
logger.log(Level.SEVERE, "There was an error while trying to set up multi user connection information.", ex);
}
// iterate through test suites if any exist try {
if (CollectionUtils.isEmpty(config.getTestSuites())) { // iterate through test suites if any exist
logger.log(Level.WARNING, "No test suites discovered. No tests will be run."); if (CollectionUtils.isEmpty(config.getTestSuites())) {
} else { logger.log(Level.WARNING, "No test suites discovered. No tests will be run.");
for (TestSuiteConfig testSuiteConfig : config.getTestSuites()) { } else {
for (CaseType caseType : IntegrationCaseType.getCaseTypes(testSuiteConfig.getCaseTypes())) { for (TestSuiteConfig testSuiteConfig : config.getTestSuites()) {
try { for (CaseType caseType : IntegrationCaseType.getCaseTypes(testSuiteConfig.getCaseTypes())) {
runIntegrationTestSuite(envConfig, caseType, testSuiteConfig); try {
} catch (CaseActionException | IllegalStateException | NoCurrentCaseException | IllegalArgumentException ex) { runIntegrationTestSuite(envConfig, caseType, testSuiteConfig);
logger.log(Level.SEVERE, "There was an error working with current case: " + testSuiteConfig.getName(), ex); } catch (CaseActionException | IllegalStateException | NoCurrentCaseException | IllegalArgumentException ex) {
logger.log(Level.SEVERE, "There was an error working with current case: " + testSuiteConfig.getName(), ex);
}
} }
} }
}
String goldPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootGoldPath()); String goldPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootGoldPath());
String outputPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootTestOutputPath()); String outputPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootTestOutputPath());
String diffPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getDiffOutputPath()); String diffPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getDiffOutputPath());
try { try {
// write diff to file if requested // write diff to file if requested
if (writeDiff(outputPath, goldPath, diffPath)) { if (writeDiff(outputPath, goldPath, diffPath)) {
// if there is a diff, throw an exception accordingly // if there is a diff, throw an exception accordingly
throw new IntegrationTestDiffException(String.format("There was a diff between the integration test gold data: %s " throw new IntegrationTestDiffException(String.format("There was a diff between the integration test gold data: %s "
+ "and the current iteration output data: %s. Diff file created at %s.", + "and the current iteration output data: %s. Diff file created at %s.",
goldPath, outputPath, diffPath)); goldPath, outputPath, diffPath));
}
} catch (DiffServiceException ex) {
throw new IntegrationTestServiceException("There was an error while trying to diff output with gold data.", ex);
}
}
} finally {
if (oldSettings != null) {
try {
UserPreferences.setDatabaseConnectionInfo(oldSettings);
} catch (Exception ex) {
logger.log(Level.WARNING, "There was an error reverting database settings", ex);
} }
} catch (DiffServiceException ex) {
throw new IntegrationTestServiceException("There was an error while trying to diff output with gold data.", ex);
} }
} }
} }
/**
* If multi user settings are present in current configuration, then set
* multi user settings to those settings. Provide the old
* CaseDbConnectionInfo object with the old values to revert when finished.
*
* @param connectionInfo The connection info to use for new values.
* @return The old connection info if present and the connection info was
* changed.
*/
private CaseDbConnectionInfo pushNewMultiUserSettings(ConnectionConfig connectionInfo) throws UserPreferencesException {
if (connectionInfo == null) {
return null;
}
String username = connectionInfo.getUserName();
String host = connectionInfo.getHostName();
String password = connectionInfo.getPassword();
int port = connectionInfo.getPort() == null ? PostgresConnectionSettings.DEFAULT_PORT : connectionInfo.getPort();
if (StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(host)) {
logger.log(Level.WARNING, "Username, password, or host are not present. Not setting multi user connection info.");
return null;
}
CaseDbConnectionInfo oldInfo = UserPreferences.getDatabaseConnectionInfo();
UserPreferences.setDatabaseConnectionInfo(new CaseDbConnectionInfo(host, Integer.toString(port), username, password, DbType.POSTGRESQL));
return oldInfo;
}
/** /**
* Runs a single test suite. * Runs a single test suite.
* *
@ -232,22 +285,11 @@ public class IntegrationTestService {
caseOutputFolderFile.mkdirs(); caseOutputFolderFile.mkdirs();
} }
// create a spe Case.createAsCurrentCase(
switch (caseType) { caseType,
case SINGLE_USER_CASE: { caseOutputFolder,
Case.createAsCurrentCase( new CaseDetails(uniqueCaseName));
Case.CaseType.SINGLE_USER_CASE, openCase = Case.getCurrentCaseThrows();
caseOutputFolder,
new CaseDetails(uniqueCaseName));
openCase = Case.getCurrentCaseThrows();
}
break;
case MULTI_USER_CASE:
throw new IllegalArgumentException("Multiuser cases are not currently supported for integration tests");
default:
throw new IllegalArgumentException("Unknown case type: " + caseType);
}
addDataSourcesToCase(PathUtil.getAbsolutePaths(workingDirectory, dataSourcePaths), caseName); addDataSourcesToCase(PathUtil.getAbsolutePaths(workingDirectory, dataSourcePaths), caseName);
return openCase; return openCase;

View File

@ -63,13 +63,13 @@ public class ConfigDeserializer {
// where the integration tests will output yml data // where the integration tests will output yml data
private static final String ROOT_TEST_OUTPUT_PATH_KEY = "rootTestOutputPath"; private static final String ROOT_TEST_OUTPUT_PATH_KEY = "rootTestOutputPath";
// the postgres connection host name // the postgres connection host name
private static final String CONNECTION_HOST_NAME_KEY = "connectionHostName"; private static final String CONNECTION_HOST_NAME_KEY = "connectionInfo.hostName";
// the postgres connection port // the postgres connection port
private static final String CONNECTION_PORT_KEY = "connectionPort"; private static final String CONNECTION_PORT_KEY = "connectionInfo.port";
// the postgres connection user name // the postgres connection user name
private static final String CONNECTION_USER_NAME_KEY = "connectionUserName"; private static final String CONNECTION_USER_NAME_KEY = "connectionInfo.userName";
// the postgres connection password // the postgres connection password
private static final String CONNECTION_PASSWORD_KEY = "connectionPassword"; private static final String CONNECTION_PASSWORD_KEY = "connectionInfo.password";
// the working directory. Paths that are relative are relative to this path. // the working directory. Paths that are relative are relative to this path.
private static final String WORKING_DIRECTORY_KEY = "workingDirectory"; private static final String WORKING_DIRECTORY_KEY = "workingDirectory";
// whether or not the output path should have the same directory structure as // whether or not the output path should have the same directory structure as