From c7c23babcc2bc1e5dd8fb7c9c5214e18b8439ee7 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 8 Oct 2020 14:09:25 -0400 Subject: [PATCH] refactor and working through components --- .../UserActivitySummaryTests.java | 68 +++++ .../integrationtesting/Bundle.properties | 1 + .../integrationtesting/IntegrationTest.java | 33 ++ .../integrationtesting/IntegrationTests.java | 45 +++ .../integrationtesting/MainTestRunner.java | 287 ++++++++++++++++++ .../integrationtesting/OutputResults.java | 78 +++++ .../integrationtesting/config/CaseConfig.java | 68 +++++ .../config/IntegrationCaseType.java | 44 +++ .../config/IntegrationTestConfig.java | 50 +++ .../config/TestingConfig.java | 77 +++++ IntegrationTesting/README.txt | 5 + IntegrationTesting/build.xml | 95 ++++++ IntegrationTesting/ivy.xml | 18 ++ IntegrationTesting/ivysettings.xml | 9 + IntegrationTesting/manifest.mf | 6 + IntegrationTesting/nbproject/build-impl.xml | 45 +++ .../nbproject/project.properties | 6 + IntegrationTesting/nbproject/project.xml | 114 +++++++ IntegrationTesting/nbproject/suite.properties | 1 + .../UserActivitySummaryTests.java | 68 +++++ .../integrationtesting/Bundle.properties | 1 + .../integrationtesting/IntegrationTest.java | 33 ++ .../integrationtesting/IntegrationTests.java | 45 +++ .../integrationtesting/MainTestRunner.java | 129 ++++++++ .../integrationtesting/config/CaseConfig.java | 68 +++++ .../config/IntegrationCaseType.java | 26 ++ .../config/IntegrationTestConfig.java | 48 +++ .../config/TestingConfig.java | 42 +++ .../autopsy/testing/RegressionTest.java | 162 ++++++++++ 29 files changed, 1672 insertions(+) create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/OutputResults.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java create mode 100644 Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java create mode 100644 IntegrationTesting/README.txt create mode 100644 IntegrationTesting/build.xml create mode 100644 IntegrationTesting/ivy.xml create mode 100644 IntegrationTesting/ivysettings.xml create mode 100644 IntegrationTesting/manifest.mf create mode 100644 IntegrationTesting/nbproject/build-impl.xml create mode 100644 IntegrationTesting/nbproject/project.properties create mode 100644 IntegrationTesting/nbproject/project.xml create mode 100644 IntegrationTesting/nbproject/suite.properties create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java create mode 100644 IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java create mode 100644 IntegrationTesting/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java new file mode 100644 index 0000000000..9bb1307412 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java @@ -0,0 +1,68 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sleuthkit.autopsy.datasourcesummary; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.UserActivitySummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.UserActivitySummary.TopDomainsResult; +import org.sleuthkit.autopsy.integrationtesting.IntegrationTest; +import org.sleuthkit.autopsy.integrationtesting.IntegrationTests; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; +import org.openide.util.lookup.ServiceProvider; + +/** + * Tests for the UserActivitySummary class. + */ +@ServiceProvider(service = IntegrationTests.class) +public class UserActivitySummaryTests implements IntegrationTests { + + /** + * Runs UserActivitySummary.getRecentDomains for all data sources found in + * the current case. + * + * @return A map where the key is the data source name and the value are the + * results of that method. + */ + @IntegrationTest + public Map> getRecentDomainsTest() + throws NoCurrentCaseException, TskCoreException, SleuthkitCaseProviderException { + + UserActivitySummary userActivitySummary = new UserActivitySummary(); + Map> toRet = new HashMap<>(); + for (Content c : Case.getCurrentCaseThrows().getDataSources()) { + if (c instanceof DataSource) { + DataSource ds = (DataSource) c; + List thisResult = userActivitySummary.getRecentDomains(ds, 10); + toRet.put(ds.getName(), thisResult); + } + } + return toRet; + + } + + //...other tests for other methods in the class... +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties new file mode 100644 index 0000000000..cd1fddd90e --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties @@ -0,0 +1 @@ +OpenIDE-Module-Name=Integration Testing diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java new file mode 100644 index 0000000000..5c43568a98 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java @@ -0,0 +1,33 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation similar to Junit's @Test for outputing results as a part of an + * integration test. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface IntegrationTest { +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java new file mode 100644 index 0000000000..59aa5ae5cd --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java @@ -0,0 +1,45 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +/** + * Basic interface for integration test suite. + */ +public interface IntegrationTests { + /** + * Allows for a test to perform any necessary setup. + */ + default void setup() {} + + /** + * Allows for a test to perform any necessary disposing of resources. + */ + default void tearDown() {} + + /** + * Allows for this suite of tests to perform any necessary setup. + */ + default void setupClass() {} + + /** + * Allows for this suite of tests to dispose of resources. + */ + default void tearDownClass() {} +} + diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java new file mode 100644 index 0000000000..21477a6180 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java @@ -0,0 +1,287 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import org.sleuthkit.autopsy.integrationtesting.config.IntegrationTestConfig; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import junit.framework.Test; +import junit.framework.TestCase; +import org.apache.cxf.common.util.CollectionUtils; +import org.netbeans.junit.NbModuleSuite; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.Case.CaseType; +import org.sleuthkit.autopsy.casemodule.CaseActionException; +import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; +import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor; +import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor.AutoIngestDataSourceProcessorException; +import org.sleuthkit.autopsy.datasourceprocessors.DataSourceProcessorUtility; +import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; +import org.sleuthkit.autopsy.ingest.IngestModuleFactory; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; +import org.sleuthkit.autopsy.integrationtesting.config.CaseConfig; +import org.sleuthkit.autopsy.integrationtesting.config.IntegrationCaseType; +import org.sleuthkit.autopsy.modules.encryptiondetection.EncryptionDetectionModuleFactory; +import org.sleuthkit.autopsy.modules.encryptiondetection.EncryptionDetectionTest; +import org.sleuthkit.autopsy.testutils.CaseUtils; +import org.sleuthkit.autopsy.testutils.IngestUtils; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Main entry point for running integration tests. Handles processing + * parameters, ingesting data sources for cases, and running items implementing + * IntegrationTests. + */ +public class MainTestRunner extends TestCase { + + private static final Logger logger = Logger.getLogger(MainTestRunner.class.getName()); // DO NOT USE AUTOPSY LOGGER + private static final String CONFIG_FILE_KEY = "CONFIG_FILE_KEY"; + + /** + * Constructor required by JUnit + */ + public MainTestRunner(String name) { + super(name); + } + + /** + * Creates suite from particular test cases. + */ + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(MainTestRunner.class). + clusters(".*"). + enableModules(".*"); + + return NbModuleSuite.create(conf.addTest("runIntegrationTests")); + } + + public void runIntegrationTests() { + String configFile = System.getProperty(CONFIG_FILE_KEY); + IntegrationTestConfig config; + try { + config = getConfigFromFile(configFile); + } catch (IOException ex) { + logger.log(Level.WARNING, "There was an error processing integration test config at " + configFile, ex); + return; + } + + if (config == null) { + logger.log(Level.WARNING, "No properly formatted config found at " + configFile); + } + + if (!CollectionUtils.isEmpty(config.getCases())) { + for (CaseConfig caseConfig : config.getCases()) { + for (CaseType caseType : IntegrationCaseType.getCaseTypes(caseConfig.getCaseTypes())) { + Case autopsyCase = runIngest(caseConfig, caseType); + if (autopsyCase == null || autopsyCase != Case.getCurrentCase()) { + logger.log(Level.WARNING, + String.format("Case was not properly ingested or setup correctly for environment. Case is %s and current case is %s.", + autopsyCase, Case.getCurrentCase())); + return; + } + + String caseName = autopsyCase.getName(); + + runIntegrationTests(config, caseConfig, caseType); + + try { + Case.closeCurrentCase(); + } catch (CaseActionException ex) { + logger.log(Level.WARNING, "There was an error while trying to close current case: {0}", caseName); + return; + } + } + } + } + } + + private Case runIngest(CaseConfig caseConfig, CaseType caseType) { + Case openCase = null; + switch (caseType) { + case SINGLE_USER_CASE: + openCase = CaseUtils.createAsCurrentCase(caseConfig.getCaseName()); + break; + case MULTI_USER_CASE: + // TODO + default: + throw new IllegalArgumentException("Unknown case type: " + caseType); + } + + if (openCase == null) { + logger.log(Level.WARNING, String.format("No case could be created for %s of type %s.", caseConfig.getCaseName(), caseType)); + return null; + } + + addDataSourcesToCase(caseConfig.getDataSourceResources(), caseConfig.getCaseName()); + try { + IngestUtils.runIngestJob(openCase.getDataSources(), getIngestSettings(caseConfig)); + } catch (TskCoreException ex) { + logger.log(Level.WARNING, String.format("There was an error while ingesting datasources for case %s", caseConfig.getCaseName()), ex); + } + + return openCase; + } + + + private void addDataSourcesToCase(List pathStrings, String caseName) { + for (String strPath : pathStrings) { + Path path = Paths.get(strPath); + List processors = null; + try { + processors = DataSourceProcessorUtility.getOrderedListOfDataSourceProcessors(path); + } catch (AutoIngestDataSourceProcessorException ex) { + logger.log(Level.WARNING, String.format("There was an error while adding data source: %s to case %s", strPath, caseName)); + } + + if (CollectionUtils.isEmpty(processors)) { + continue; + } + + IngestUtils.addDataSource(processors.get(0), path); + } + } + + private IntegrationTestConfig getConfigFromFile(String filePath) throws IOException { + ObjectMapper om = new ObjectMapper(); + try (FileInputStream jsonSrc = new FileInputStream(filePath)) { + return om.readValue(jsonSrc, IntegrationTestConfig.class); + } + } + + private IngestJobSettings getIngestSettings(CaseConfig caseConfig) { + // TODO + ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); + IngestUtils.addDataSource(dataSourceProcessor, BITLOCKER_DETECTION_IMAGE_PATH); + IngestModuleFactory ingestModuleFactory = new EncryptionDetectionModuleFactory(); + IngestModuleIngestJobSettings settings = ingestModuleFactory.getDefaultIngestJobSettings(); + IngestModuleTemplate template = new IngestModuleTemplate(ingestModuleFactory, settings); + template.setEnabled(true); + List templates = new ArrayList<>(); + templates.add(template); + IngestJobSettings ingestJobSettings = new IngestJobSettings(EncryptionDetectionTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates); + } + + private void runIntegrationTests(IntegrationTestConfig config, CaseConfig caseConfig, CaseType caseType) { + // this will capture output results + OutputResults results = new OutputResults(); + + // run through each ConsumerIntegrationTest + for (IntegrationTests testGroup : Lookup.getDefault().lookupAll(IntegrationTests.class)) { + + // if test should not be included in results, skip it. + if (!caseConfig.getTestConfig().hasIncludedTest(testGroup.getClass().getCanonicalName())) { + continue; + } + + List testMethods = getIntegrationTestMethods(testGroup); + if (CollectionUtils.isEmpty(testMethods)) { + continue; + } + + testGroup.setupClass(); + for (Method testMethod : testMethods) { + runIntegrationTestMethod(results, testGroup, testMethod); + } + testGroup.tearDownClass(); + } + + // write the results for the case to a file + serializeFile(results, config.getRootTestOutputPath(), caseConfig.getCaseName(), getCaseTypeId(caseType)); + } + + private String getCaseTypeId(CaseType caseType) { + if (caseType == null) { + return ""; + } + + switch (caseType) { + case SINGLE_USER_CASE: + return "singleUser"; + case MULTI_USER_CASE: + return "multiUser"; + default: + throw new IllegalArgumentException("Unknown case type: " + caseType); + } + } + + private void runIntegrationTestMethod(OutputResults results, IntegrationTests testGroup, Method testMethod) { + testGroup.setup(); + + // run the test method and get the results + Object serializableResult = null; + + try { + serializableResult = testMethod.invoke(testGroup); + } catch (IllegalAccessException | IllegalArgumentException ex) { + logger.log(Level.WARNING, + String.format("test method %s in %s could not be properly invoked", + testMethod.getName(), testGroup.getClass().getCanonicalName()), + ex); + + serializableResult = ex; + } catch (InvocationTargetException ex) { + serializableResult = ex.getCause(); + } + + testGroup.tearDown(); + + // add the results and capture the package, class, + // and method of the test for easy location of failed tests + results.addResult( + testGroup.getClass().getPackage().getName(), + testGroup.getClass().getSimpleName(), + testMethod.getName(), + serializableResult); + } + + private List getIntegrationTestMethods(IntegrationTests testGroup) { + return Stream.of(testGroup.getClass().getMethods()) + .filter((method) -> method.getAnnotation(IntegrationTest.class) != null) + .collect(Collectors.toList()); + } + + private void serializeFile(OutputResults results, String outputFolder, String caseName, String caseType) { + String outputExtension = ".yml"; + Path outputPath = Paths.get(outputFolder, String.format("%s-%s%s", caseName, caseType, outputExtension)); + ObjectMapper om = new ObjectMapper(new YAMLFactory()); + + try { + om.writeValue(outputPath.toFile(), results.getSerializableData()); + } catch (IOException ex) { + logger.log(Level.WARNING, "There was an error writing results to outputPath: " + outputPath, ex); + } + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/OutputResults.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/OutputResults.java new file mode 100644 index 0000000000..4138657354 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/OutputResults.java @@ -0,0 +1,78 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; +import org.apache.commons.lang.exception.ExceptionUtils; + +/** + * Integration Test results for a case to be written to disk in a text format. + */ +public class OutputResults { + + private static class ExceptionObject { + + private final String message; + private final String stackTrace; + private final ExceptionObject innerException; + + ExceptionObject(Throwable t) { + this.message = t.getMessage(); + this.stackTrace = ExceptionUtils.getStackTrace(t); + this.innerException = (t.getCause() == null) ? null : new ExceptionObject(t.getCause()); + } + + String getMessage() { + return message; + } + + String getStackTrace() { + return stackTrace; + } + + ExceptionObject getInnerException() { + return innerException; + } + } + + private final Map>> data = new HashMap<>(); + + private static V getOrCreate(Map map, K key, Supplier onNotPresent) { + V curValue = map.get(key); + if (curValue == null) { + curValue = onNotPresent.get(); + map.put(key, curValue); + } + return curValue; + } + + public void addResult(String pkgName, String className, String methodName, Object result) { + Map> packageClasses = getOrCreate(data, pkgName, () -> new HashMap<>()); + Map classMethods = getOrCreate(packageClasses, className, () -> new HashMap<>()); + Object toWrite = result instanceof Throwable ? new ExceptionObject((Throwable) result) : result; + classMethods.put(methodName, toWrite); + } + + public Object getSerializableData() { + return Collections.unmodifiableMap(data); + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java new file mode 100644 index 0000000000..09039a879a --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java @@ -0,0 +1,68 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import java.util.List; + +/** + * Configuration in IntegrationTests per case. + */ +public class CaseConfig { + private final String caseName; + private final List dataSourceResources; + private final String ingestProfilePath; + private final String ingestModuleSettingsPath; + private final IntegrationCaseType caseTypes; + private final TestingConfig testConfig; + + public CaseConfig(String caseName, List dataSourceResources, + String ingestProfilePath, String ingestModuleSettingsPath, + IntegrationCaseType caseTypes, TestingConfig testConfig) { + this.caseName = caseName; + this.dataSourceResources = dataSourceResources; + this.ingestProfilePath = ingestProfilePath; + this.ingestModuleSettingsPath = ingestModuleSettingsPath; + this.caseTypes = caseTypes; + this.testConfig = testConfig; + } + + public String getCaseName() { + return caseName; + } + + public List getDataSourceResources() { + return dataSourceResources; + } + + public String getIngestProfilePath() { + return ingestProfilePath; + } + + public String getIngestModuleSettingsPath() { + return ingestModuleSettingsPath; + } + + public IntegrationCaseType getCaseTypes() { + return caseTypes; + } + + public TestingConfig getTestConfig() { + return testConfig; + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java new file mode 100644 index 0000000000..d85c60d5c3 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java @@ -0,0 +1,44 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.sleuthkit.autopsy.casemodule.Case.CaseType; + +/** + * The case types to create for this case. + */ +public enum IntegrationCaseType { + multiUser, singleUser, both; + + public static List getCaseTypes(IntegrationCaseType integrationCaseType) { + if (integrationCaseType == null) { + return Collections.emptyList(); + } + + switch (integrationCaseType) { + case multiUser: return Arrays.asList(CaseType.MULTI_USER_CASE); + case singleUser: return Arrays.asList(CaseType.SINGLE_USER_CASE); + case both: return Arrays.asList(CaseType.MULTI_USER_CASE, CaseType.SINGLE_USER_CASE); + default: throw new IllegalArgumentException("Unknown integration case type: " + integrationCaseType); + } + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java new file mode 100644 index 0000000000..4547afa92a --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java @@ -0,0 +1,50 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import java.util.List; + +/** + * Configuration for running Integration Tests including things like ingest + * parameters, datasource locations, cases to create, tests to run, etc. + */ +public class IntegrationTestConfig { + private final String rootCaseOutputPath; + private final String rootTestOutputPath; + private final List cases; + + public IntegrationTestConfig(String rootCaseOutputPath, + String rootTestOutputPath, List cases) { + this.rootCaseOutputPath = rootCaseOutputPath; + this.rootTestOutputPath = rootTestOutputPath; + this.cases = cases; + } + + public String getRootCaseOutputPath() { + return rootCaseOutputPath; + } + + public String getRootTestOutputPath() { + return rootTestOutputPath; + } + + public List getCases() { + return cases; + } +} diff --git a/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java new file mode 100644 index 0000000000..d845486073 --- /dev/null +++ b/Core/test/qa-functional/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java @@ -0,0 +1,77 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; + +/** + * Configuration for which integration test suites to run. + */ +public class TestingConfig { + private final Set excludeAllExcept; + private final Set includeAllExcept; + + private static Set convert(List orig) { + if (orig == null) { + return Collections.emptySet(); + } + + return orig.stream() + .map((item) -> item.toUpperCase()) + .collect(Collectors.toSet()); + } + + @JsonCreator + public TestingConfig(@JsonProperty() List excludeAllExcept, @JsonProperty() List includeAllExcept) { + this.excludeAllExcept = convert(excludeAllExcept); + this.includeAllExcept = convert(includeAllExcept); + } + + public Set getExcludeAllExcept() { + return excludeAllExcept; + } + + public Set getIncludeAllExcept() { + return includeAllExcept; + } + + public boolean hasIncludedTest(String itemType) { + if (itemType == null) { + return false; + } + + if (!CollectionUtils.isEmpty(includeAllExcept)) { + if (includeAllExcept.contains(itemType.toUpperCase())) { + return false; + } + } + + if (!CollectionUtils.isEmpty(excludeAllExcept)) { + return excludeAllExcept.contains(itemType.toUpperCase()); + } + + return true; + } +} diff --git a/IntegrationTesting/README.txt b/IntegrationTesting/README.txt new file mode 100644 index 0000000000..a100bfd731 --- /dev/null +++ b/IntegrationTesting/README.txt @@ -0,0 +1,5 @@ +This folder contains the Test module that is used to drive Autopsy. It +relies on NetBeans libraries to drive the UI. The test folder in the +root directory contains scripts and gold standard files to compare +against. That folder is where you should run regression tests from. + diff --git a/IntegrationTesting/build.xml b/IntegrationTesting/build.xml new file mode 100644 index 0000000000..6ce6a84178 --- /dev/null +++ b/IntegrationTesting/build.xml @@ -0,0 +1,95 @@ + + + + + + Builds, tests, and runs the project org.sleuthkit.autopsy.integrationtesting. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IntegrationTesting/ivy.xml b/IntegrationTesting/ivy.xml new file mode 100644 index 0000000000..91161b855f --- /dev/null +++ b/IntegrationTesting/ivy.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/IntegrationTesting/ivysettings.xml b/IntegrationTesting/ivysettings.xml new file mode 100644 index 0000000000..8209151a1c --- /dev/null +++ b/IntegrationTesting/ivysettings.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/IntegrationTesting/manifest.mf b/IntegrationTesting/manifest.mf new file mode 100644 index 0000000000..198e3333fc --- /dev/null +++ b/IntegrationTesting/manifest.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +AutoUpdate-Show-In-Client: false +OpenIDE-Module: org.sleuthkit.autopsy.integrationtesting/3 +OpenIDE-Module-Implementation-Version: 11 +OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/integrationtesting/Bundle.properties + diff --git a/IntegrationTesting/nbproject/build-impl.xml b/IntegrationTesting/nbproject/build-impl.xml new file mode 100644 index 0000000000..ae64885425 --- /dev/null +++ b/IntegrationTesting/nbproject/build-impl.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IntegrationTesting/nbproject/project.properties b/IntegrationTesting/nbproject/project.properties new file mode 100644 index 0000000000..2b963e0724 --- /dev/null +++ b/IntegrationTesting/nbproject/project.properties @@ -0,0 +1,6 @@ +javac.source=1.8 +javac.compilerargs=-Xlint -Xlint:-serial +license.file=../LICENSE-2.0.txt +nbm.homepage=http://www.sleuthkit.org/autopsy/ +nbm.needs.restart=true +spec.version.base=1.3 diff --git a/IntegrationTesting/nbproject/project.xml b/IntegrationTesting/nbproject/project.xml new file mode 100644 index 0000000000..2ec61e0cb3 --- /dev/null +++ b/IntegrationTesting/nbproject/project.xml @@ -0,0 +1,114 @@ + + + org.netbeans.modules.apisupport.project + + + org.sleuthkit.autopsy.integrationtesting + + + + org.netbeans.libs.junit4 + + + + 1.14 + + + + org.netbeans.modules.jellytools.platform + + + + 3 + 3.28.1 + + + + org.netbeans.modules.jemmy + + + + 3 + 3.26.1 + + + + org.netbeans.modules.nbjunit + + + + 1 + 1.86.1 + + + + org.openide.util.lookup + + + + 8.40 + + + + org.sleuthkit.autopsy.core + + + + 10 + 10.22 + + + + org.sleuthkit.autopsy.keywordsearch + + + + 6 + 6.6 + + + + + + qa-functional + + org.netbeans.libs.junit4 + + + + org.netbeans.modules.jellytools.java + + + + org.netbeans.modules.jellytools.platform + + + + org.netbeans.modules.jemmy + + + + org.netbeans.modules.nbjunit + + + + + + unit + + org.netbeans.libs.junit4 + + + + org.netbeans.modules.nbjunit + + + + + + + org.sleuthkit.autopsy.integrationtesting + + + + diff --git a/IntegrationTesting/nbproject/suite.properties b/IntegrationTesting/nbproject/suite.properties new file mode 100644 index 0000000000..29d7cc9bd6 --- /dev/null +++ b/IntegrationTesting/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java b/IntegrationTesting/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java new file mode 100644 index 0000000000..9bb1307412 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/datasourcesummary/UserActivitySummaryTests.java @@ -0,0 +1,68 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sleuthkit.autopsy.datasourcesummary; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.UserActivitySummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.UserActivitySummary.TopDomainsResult; +import org.sleuthkit.autopsy.integrationtesting.IntegrationTest; +import org.sleuthkit.autopsy.integrationtesting.IntegrationTests; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; +import org.openide.util.lookup.ServiceProvider; + +/** + * Tests for the UserActivitySummary class. + */ +@ServiceProvider(service = IntegrationTests.class) +public class UserActivitySummaryTests implements IntegrationTests { + + /** + * Runs UserActivitySummary.getRecentDomains for all data sources found in + * the current case. + * + * @return A map where the key is the data source name and the value are the + * results of that method. + */ + @IntegrationTest + public Map> getRecentDomainsTest() + throws NoCurrentCaseException, TskCoreException, SleuthkitCaseProviderException { + + UserActivitySummary userActivitySummary = new UserActivitySummary(); + Map> toRet = new HashMap<>(); + for (Content c : Case.getCurrentCaseThrows().getDataSources()) { + if (c instanceof DataSource) { + DataSource ds = (DataSource) c; + List thisResult = userActivitySummary.getRecentDomains(ds, 10); + toRet.put(ds.getName(), thisResult); + } + } + return toRet; + + } + + //...other tests for other methods in the class... +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties new file mode 100644 index 0000000000..cd1fddd90e --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/Bundle.properties @@ -0,0 +1 @@ +OpenIDE-Module-Name=Integration Testing diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java new file mode 100644 index 0000000000..5c43568a98 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTest.java @@ -0,0 +1,33 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation similar to Junit's @Test for outputing results as a part of an + * integration test. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface IntegrationTest { +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java new file mode 100644 index 0000000000..d6df640772 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/IntegrationTests.java @@ -0,0 +1,45 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +/** + * Basic interface for integration test suite. + */ +public interface IntegrationTests { + /** + * Allows for a test to perform any necessary setup. + */ + default void Setup() {} + + /** + * Allows for a test to perform any necessary disposing of resources. + */ + default void TearDown() {} + + /** + * Allows for this suite of tests to perform any necessary setup. + */ + default void SetupClass() {} + + /** + * Allows for this suite of tests to dispose of resources. + */ + default void TeadDownClass() {} +} + diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java new file mode 100644 index 0000000000..e22fddc821 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/MainTestRunner.java @@ -0,0 +1,129 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import org.sleuthkit.autopsy.integrationtesting.config.IntegrationTestConfig; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; +import junit.framework.Test; +import junit.framework.TestCase; +import org.netbeans.junit.NbModuleSuite; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.ImageDSProcessor; +import org.sleuthkit.autopsy.ingest.IngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType; +import org.sleuthkit.autopsy.ingest.IngestModuleFactory; +import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; +import org.sleuthkit.autopsy.ingest.IngestModuleTemplate; +import org.sleuthkit.autopsy.modules.encryptiondetection.EncryptionDetectionModuleFactory; + +/** + * Main entry point for running integration tests. Handles processing + * parameters, ingesting data sources for cases, and running items implementing + * IntegrationTests. + */ +public class MainTestRunner extends TestCase { + + private static final Logger logger = Logger.getLogger(MainTestRunner.class.getName()); // DO NOT USE AUTOPSY LOGGER + private static final String CONFIG_FILE_KEY = "CONFIG_FILE_KEY"; + + /** + * Constructor required by JUnit + */ + public MainTestRunner(String name) { + super(name); + } + + /** + * Creates suite from particular test cases. + */ + public static Test suite() { + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(MainTestRunner.class). + clusters(".*"). + enableModules(".*"); + + return NbModuleSuite.create(conf.addTest("runIntegrationTests")); + } + +// public void runIntegrationTests() { +// String configFile = System.getProperty(CONFIG_FILE_KEY); +// IntegrationTestConfig config = getFromConfigFile(configFile); +// // Set up NetBeans environment +// Case autopsyCase = runIngest(config); +// runConsumerIntegrationTests(config); +// Case.closeCurrentCase(); +// } +// +// private Case runIngest(IntegrationTestConfig config) { +// Case openCase = CaseUtils.createAsCurrentCase(BITLOCKER_DETECTION_CASE_NAME); +// ImageDSProcessor dataSourceProcessor = new ImageDSProcessor(); +// IngestUtils.addDataSource(dataSourceProcessor, BITLOCKER_DETECTION_IMAGE_PATH); +// IngestModuleFactory ingestModuleFactory = new EncryptionDetectionModuleFactory(); +// IngestModuleIngestJobSettings settings = ingestModuleFactory.getDefaultIngestJobSettings(); +// IngestModuleTemplate template = new IngestModuleTemplate(ingestModuleFactory, settings); +// template.setEnabled(true); +// List templates = new ArrayList<>(); +// templates.add(template); +// IngestJobSettings ingestJobSettings = new IngestJobSettings(EncryptionDetectionTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates); +// IngestUtils.runIngestJob(openCase.getDataSources(), ingestJobSettings); +// return openCase; +// } +// +// private void runIntegrationTests(IntegrationTestConfig config) { +// // this will capture output results +// OutputResults results = new OutputResults(); +// +// // run through each ConsumerIntegrationTest +// for (IntegrationTests testGroup +// : Lookup.getAll(ConsumerIntegrationTests.class)) { +// +// // if test should not be included in results, skip it. +// if (!testParams.hasIncludedTest(testGroup.getClass())) { +// continue; +// } +// +// for (Method testMethod : getAllTestMethods(testGroup)) { +// +// // run the test method and get the results +// Object serializableResult = null; +// try { +// Object serializableResult = testMethod.run(); +// } catch (Exception e) { +// serializableResult = e; +// } +// +// // add the results and capture the package, class, +// // and method of the test for easy location of failed tests +// results.addResult( +// testGroup.getPackage(), +// testGroup.getSimpleName(), +// testMethod.getName(), +// serializableResult); +// } +// } +// +// // write the results for the case to a file +// serializeFile(testParams.getOutputPath(), +// skCase.getName(), +// results); +// } +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java new file mode 100644 index 0000000000..09039a879a --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/CaseConfig.java @@ -0,0 +1,68 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import java.util.List; + +/** + * Configuration in IntegrationTests per case. + */ +public class CaseConfig { + private final String caseName; + private final List dataSourceResources; + private final String ingestProfilePath; + private final String ingestModuleSettingsPath; + private final IntegrationCaseType caseTypes; + private final TestingConfig testConfig; + + public CaseConfig(String caseName, List dataSourceResources, + String ingestProfilePath, String ingestModuleSettingsPath, + IntegrationCaseType caseTypes, TestingConfig testConfig) { + this.caseName = caseName; + this.dataSourceResources = dataSourceResources; + this.ingestProfilePath = ingestProfilePath; + this.ingestModuleSettingsPath = ingestModuleSettingsPath; + this.caseTypes = caseTypes; + this.testConfig = testConfig; + } + + public String getCaseName() { + return caseName; + } + + public List getDataSourceResources() { + return dataSourceResources; + } + + public String getIngestProfilePath() { + return ingestProfilePath; + } + + public String getIngestModuleSettingsPath() { + return ingestModuleSettingsPath; + } + + public IntegrationCaseType getCaseTypes() { + return caseTypes; + } + + public TestingConfig getTestConfig() { + return testConfig; + } +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java new file mode 100644 index 0000000000..2f31c2cab6 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationCaseType.java @@ -0,0 +1,26 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +/** + * The case types to create for this case. + */ +public enum IntegrationCaseType { + multiUser, singleUser, both +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java new file mode 100644 index 0000000000..7192931cf5 --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/IntegrationTestConfig.java @@ -0,0 +1,48 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +/** + * Configuration for running Integration Tests including things like ingest + * parameters, datasource locations, cases to create, tests to run, etc. + */ +public class IntegrationTestConfig { + private final String rootCaseOutputPath; + private final String rootTestOutputPath; + private final CaseConfig cases; + + public IntegrationTestConfig(String rootCaseOutputPath, + String rootTestOutputPath, CaseConfig cases) { + this.rootCaseOutputPath = rootCaseOutputPath; + this.rootTestOutputPath = rootTestOutputPath; + this.cases = cases; + } + + public String getRootCaseOutputPath() { + return rootCaseOutputPath; + } + + public String getRootTestOutputPath() { + return rootTestOutputPath; + } + + public CaseConfig getCases() { + return cases; + } +} diff --git a/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java new file mode 100644 index 0000000000..089bea3c2a --- /dev/null +++ b/IntegrationTesting/src/org/sleuthkit/autopsy/integrationtesting/config/TestingConfig.java @@ -0,0 +1,42 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting.config; + +import java.util.List; + +/** + * Configuration for which integration test suites to run. + */ +public class TestingConfig { + private final List excludeAllExcept; + private final List includeAllExcept; + + public TestingConfig(List excludeAllExcept, List includeAllExcept) { + this.excludeAllExcept = excludeAllExcept; + this.includeAllExcept = includeAllExcept; + } + + public List getExcludeAllExcept() { + return excludeAllExcept; + } + + public List getIncludeAllExcept() { + return includeAllExcept; + } +} diff --git a/IntegrationTesting/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java b/IntegrationTesting/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java new file mode 100644 index 0000000000..b959b3516d --- /dev/null +++ b/IntegrationTesting/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java @@ -0,0 +1,162 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011-2018 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.integrationtesting; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Logger; +import junit.framework.Test; +import junit.framework.TestCase; +import org.netbeans.jemmy.Timeouts; +import org.netbeans.junit.NbModuleSuite; + +/** + * This test expects the following system properties to be set: img_path: The + * fully qualified path to the image file (if split, the first file) out_path: + * The location where the case will be stored nsrl_path: Path to the nsrl + * database known_bad_path: Path to a database of known bad hashes keyword_path: + * Path to a keyword list xml file ignore_unalloc: Boolean whether to ignore + * unallocated space or not + * + * Without these properties set, the test will fail to run correctly. To run + * this test correctly, you should use the script 'regression.py' located in the + * 'script' directory of the Testing module. + */ +public class RegressionTest extends TestCase { + + private static final Logger logger = Logger.getLogger(RegressionTest.class.getName()); // DO NOT USE AUTOPSY LOGGER + private static final AutopsyTestCases autopsyTests = new AutopsyTestCases(Boolean.parseBoolean(System.getProperty("isMultiUser"))); + + /** + * Constructor required by JUnit + */ + public RegressionTest(String name) { + super(name); + } + + /** + * Creates suite from particular test cases. + */ + public static Test suite() { + // run tests with specific configuration + File img_path = new File(AutopsyTestCases.getEscapedPath(System.getProperty("img_path"))); + NbModuleSuite.Configuration conf = NbModuleSuite.createConfiguration(RegressionTest.class). + clusters(".*"). + enableModules(".*"); + if (img_path.isFile()) { + conf = conf.addTest("testNewCaseWizardOpen", + "testNewCaseWizard", + "testStartAddImageFileDataSource", + "testConfigureIngest1", + "testConfigureHash", + "testConfigureIngest2", + "testConfigureSearch", + "testAddSourceWizard1", + "testIngest", + "testExpandDataSourcesTree", //After do ingest, before generate report, we expand Data Sources node + "testGenerateReportToolbar", + "testGenerateReportButton"); + } + + if (img_path.isDirectory()) { + conf = conf.addTest("testNewCaseWizardOpen", + "testNewCaseWizard", + "testStartAddLogicalFilesDataSource", + "testConfigureIngest1", + "testConfigureHash", + "testConfigureIngest2", + "testConfigureSearch", + "testAddSourceWizard1", + "testIngest", + "testExpandDataSourcesTree", + "testGenerateReportToolbar", + "testGenerateReportButton"); + } + + return NbModuleSuite.create(conf); + + } + + /** + * Method called before each test case. + */ + @Override + public void setUp() { + logger.info("######## " + AutopsyTestCases.getEscapedPath(System.getProperty("img_path")) + " #######"); + Timeouts.setDefault("ComponentOperator.WaitComponentTimeout", 1000000); + } + + /** + * Method called after each test case. + */ + @Override + public void tearDown() { + } + + public void testNewCaseWizardOpen() { + autopsyTests.testNewCaseWizardOpen("Welcome"); + } + + public void testNewCaseWizard() { + autopsyTests.testNewCaseWizard(); + } + + public void testStartAddImageFileDataSource() { + autopsyTests.testStartAddImageFileDataSource(); + } + + public void testStartAddLogicalFilesDataSource() { + autopsyTests.testStartAddLogicalFilesDataSource(); + } + + public void testAddSourceWizard1() { + autopsyTests.testAddSourceWizard1(); + } + + public void testConfigureIngest1() { + autopsyTests.testConfigureIngest1(); + } + + public void testConfigureHash() { + autopsyTests.testConfigureHash(); + } + + public void testConfigureIngest2() { + autopsyTests.testConfigureIngest2(); + } + + public void testConfigureSearch() { + autopsyTests.testConfigureSearch(); + } + + public void testIngest() { + autopsyTests.testIngest(); + } + + public void testExpandDataSourcesTree() { + autopsyTests.testExpandDataSourcesTree(); + } + public void testGenerateReportToolbar() { + autopsyTests.testGenerateReportToolbar(); + } + + public void testGenerateReportButton() throws IOException { + autopsyTests.testGenerateReportButton(); + } +}