mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
means of creating diff
This commit is contained in:
parent
023f975455
commit
0673969304
26
Core/ivy.xml
26
Core/ivy.xml
@ -3,30 +3,30 @@
|
|||||||
<configurations >
|
<configurations >
|
||||||
<!-- module dependencies -->
|
<!-- module dependencies -->
|
||||||
<conf name="core"/>
|
<conf name="core"/>
|
||||||
|
|
||||||
</configurations>
|
</configurations>
|
||||||
<dependencies >
|
<dependencies >
|
||||||
<dependency conf="core->default" org="com.github.vlsi.mxgraph" name="jgraphx" rev="4.1.0" />
|
<dependency conf="core->default" org="com.github.vlsi.mxgraph" name="jgraphx" rev="4.1.0" />
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.11.1"/>
|
<dependency conf="core->default" org="org.apache.activemq" name="activemq-all" rev="5.11.1"/>
|
||||||
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="2.8.0"/>
|
<dependency conf="core->default" org="org.apache.curator" name="curator-client" rev="2.8.0"/>
|
||||||
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="2.8.0"/>
|
<dependency conf="core->default" org="org.apache.curator" name="curator-framework" rev="2.8.0"/>
|
||||||
<dependency conf="core->default" org="org.apache.curator" name="curator-recipes" rev="2.8.0"/>
|
<dependency conf="core->default" org="org.apache.curator" name="curator-recipes" rev="2.8.0"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.python" name="jython-standalone" rev="2.7.0" />
|
<dependency conf="core->default" org="org.python" name="jython-standalone" rev="2.7.0" />
|
||||||
|
|
||||||
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
<dependency conf="core->default" org="com.adobe.xmp" name="xmpcore" rev="5.1.2"/>
|
||||||
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
<dependency conf="core->default" org="org.apache.zookeeper" name="zookeeper" rev="3.4.6"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess" rev="2.2.0"/>
|
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess" rev="2.2.0"/>
|
||||||
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess-encrypt" rev="2.1.4"/>
|
<dependency conf="core->default" org="com.healthmarketscience.jackcess" name="jackcess-encrypt" rev="2.1.4"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
|
<dependency conf="core->default" org="org.apache.commons" name="commons-dbcp2" rev="2.1.1"/>
|
||||||
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
|
<dependency conf="core->default" org="org.apache.commons" name="commons-pool2" rev="2.4.2"/>
|
||||||
<dependency conf="core->default" org="commons-codec" name="commons-codec" rev="1.11"/>
|
<dependency conf="core->default" org="commons-codec" name="commons-codec" rev="1.11"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
<dependency conf="core->default" org="org.jsoup" name="jsoup" rev="1.10.3"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.9.7"/>
|
<dependency conf="core->default" org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.9.7"/>
|
||||||
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.11.0"/>
|
<dependency conf="core->default" org="com.drewnoakes" name="metadata-extractor" rev="2.11.0"/>
|
||||||
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<dependency conf="core->default" org="org.apache.opennlp" name="opennlp-tools" rev="1.9.1"/>
|
<dependency conf="core->default" org="org.apache.opennlp" name="opennlp-tools" rev="1.9.1"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="com.ethteck.decodetect" name="decodetect-core" rev="0.3"/>
|
<dependency conf="core->default" org="com.ethteck.decodetect" name="decodetect-core" rev="0.3"/>
|
||||||
|
|
||||||
<dependency conf="core->default" org="org.sejda.webp-imageio" name="webp-imageio-sejda" rev="0.1.0"/>
|
<dependency conf="core->default" org="org.sejda.webp-imageio" name="webp-imageio-sejda" rev="0.1.0"/>
|
||||||
<dependency conf="core->default" org="com.googlecode.libphonenumber" name="libphonenumber" rev="3.5" />
|
<dependency conf="core->default" org="com.googlecode.libphonenumber" name="libphonenumber" rev="3.5" />
|
||||||
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
<dependency conf="core->default" org="commons-validator" name="commons-validator" rev="1.6"/>
|
||||||
@ -45,13 +45,17 @@
|
|||||||
|
|
||||||
<!-- for yaml reading/writing -->
|
<!-- for yaml reading/writing -->
|
||||||
<dependency org="org.yaml" name="snakeyaml" rev="1.27"/>
|
<dependency org="org.yaml" name="snakeyaml" rev="1.27"/>
|
||||||
|
|
||||||
<!-- map support for geolocation -->
|
<!-- map support for geolocation -->
|
||||||
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
|
<dependency conf="core->default" org="org.jxmapviewer" name="jxmapviewer2" rev="2.4"/>
|
||||||
|
|
||||||
<!-- For Discovery testing -->
|
<!-- For Discovery testing -->
|
||||||
<dependency conf="core->default" org="org.mockito" name="mockito-core" rev="3.5.7"/>
|
<dependency conf="core->default" org="org.mockito" name="mockito-core" rev="3.5.7"/>
|
||||||
|
|
||||||
|
<!-- for handling diffs -->
|
||||||
|
<dependency org="io.github.java-diff-utils" name="java-diff-utils" rev="4.8"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
||||||
<dependency conf="core->default" org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
|
<dependency conf="core->default" org="javax.ws.rs" name="javax.ws.rs-api" rev="2.0"/>
|
||||||
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
|
<override org="jakarta.ws.rs" module="jakarta.ws.rs-api" rev="2.1.5"/>
|
||||||
|
@ -21,6 +21,7 @@ file.reference.commons-dbcp2-2.1.1.jar=release\\modules\\ext\\commons-dbcp2-2.1.
|
|||||||
file.reference.commons-digester-1.8.1.jar=release\\modules\\ext\\commons-digester-1.8.1.jar
|
file.reference.commons-digester-1.8.1.jar=release\\modules\\ext\\commons-digester-1.8.1.jar
|
||||||
file.reference.commons-logging-1.2.jar=release\\modules\\ext\\commons-logging-1.2.jar
|
file.reference.commons-logging-1.2.jar=release\\modules\\ext\\commons-logging-1.2.jar
|
||||||
file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
|
file.reference.commons-pool2-2.4.2.jar=release\\modules\\ext\\commons-pool2-2.4.2.jar
|
||||||
|
file.reference.java-diff-utils-4.8.jar=release\\modules\\ext\\java-diff-utils-4.8.jar
|
||||||
file.reference.commons-validator-1.6.jar=release\\modules\\ext\\commons-validator-1.6.jar
|
file.reference.commons-validator-1.6.jar=release\\modules\\ext\\commons-validator-1.6.jar
|
||||||
file.reference.curator-client-2.8.0.jar=release\\modules\\ext\\curator-client-2.8.0.jar
|
file.reference.curator-client-2.8.0.jar=release\\modules\\ext\\curator-client-2.8.0.jar
|
||||||
file.reference.curator-framework-2.8.0.jar=release\\modules\\ext\\curator-framework-2.8.0.jar
|
file.reference.curator-framework-2.8.0.jar=release\\modules\\ext\\curator-framework-2.8.0.jar
|
||||||
|
@ -643,6 +643,10 @@
|
|||||||
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
|
<runtime-relative-path>ext/commons-collections-3.2.2.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\commons-collections-3.2.2.jar</binary-origin>
|
<binary-origin>release\modules\ext\commons-collections-3.2.2.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/java-diff-utils-4.8.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release\modules\ext\java-diff-utils-4.8.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
|
<runtime-relative-path>ext/SparseBitSet-1.1.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\SparseBitSet-1.1.jar</binary-origin>
|
<binary-origin>release\modules\ext\SparseBitSet-1.1.jar</binary-origin>
|
||||||
@ -811,7 +815,7 @@
|
|||||||
<runtime-relative-path>ext/grpc-netty-shaded-1.19.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/grpc-netty-shaded-1.19.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\grpc-netty-shaded-1.19.0.jar</binary-origin>
|
<binary-origin>release\modules\ext\grpc-netty-shaded-1.19.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/snakeyaml-1.27.jar</runtime-relative-path>
|
<runtime-relative-path>ext/snakeyaml-1.27.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\snakeyaml-1.27.jar</binary-origin>
|
<binary-origin>release\modules\ext\snakeyaml-1.27.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.github.difflib.DiffUtils;
|
||||||
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
|
import com.github.difflib.patch.Chunk;
|
||||||
|
import com.github.difflib.patch.Patch;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles creating diffs with files.
|
||||||
|
*/
|
||||||
|
public class DiffService {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DiffUtils.class.getName());
|
||||||
|
private static final String ORIG_LINE_PREFIX = "< ";
|
||||||
|
private static final String CUR_LINE_PREFIX = "> ";
|
||||||
|
private static final String[] DIFF_BREAK = new String[]{"", "", ""};
|
||||||
|
private static final String[] FILE_DIFF_BREAK = new String[]{"", "", "", ""};
|
||||||
|
private static final String NEW_LINE = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a diff of all the files found in the directories provided or
|
||||||
|
* between two files.
|
||||||
|
*
|
||||||
|
* @param prevResult The previous file or directory. Must be of same type as
|
||||||
|
* curResult (file/directory).
|
||||||
|
* @param curResult The current file or directory. Must be of same type as
|
||||||
|
* prevResult (file/directory).
|
||||||
|
* @return The string contents of the diff.
|
||||||
|
*/
|
||||||
|
String diffFilesOrDirs(File prevResult, File curResult) {
|
||||||
|
if (prevResult.isDirectory() && curResult.isDirectory()) {
|
||||||
|
final Map<String, File> prevFiles = FileUtils.listFiles(prevResult, null, true).stream()
|
||||||
|
.collect(Collectors.toMap(f -> getRelative(prevResult, f), f -> f, (f1, f2) -> f1));
|
||||||
|
|
||||||
|
final Map<String, File> curFiles = FileUtils.listFiles(curResult, null, true).stream()
|
||||||
|
.collect(Collectors.toMap(f -> getRelative(curResult, f), f -> f, (f1, f2) -> f1));
|
||||||
|
|
||||||
|
Map<String, Pair<File, File>> prevCurMapping = Stream.of(prevFiles, curFiles)
|
||||||
|
.flatMap((map) -> map.keySet().stream())
|
||||||
|
.collect(Collectors.toMap(k -> k, k -> Pair.of(prevFiles.get(k), curFiles.get(k)), (v1, v2) -> v1));
|
||||||
|
|
||||||
|
String fullDiff = prevCurMapping.entrySet().stream()
|
||||||
|
.map((entry) -> getFileDiffs(entry.getValue().getLeft(), entry.getValue().getRight(), entry.getKey()))
|
||||||
|
.filter((val) -> val != null)
|
||||||
|
.collect(Collectors.joining(String.join(NEW_LINE, FILE_DIFF_BREAK)));
|
||||||
|
|
||||||
|
return fullDiff;
|
||||||
|
|
||||||
|
} else if (prevResult.isFile() && curResult.isFile()) {
|
||||||
|
return getFileDiffs(prevResult, curResult, prevResult.toString() + " / " + curResult.toString());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, String.format("%s and %s must be of same type (directory/file).", prevResult.toString(), curResult.toString()));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles creating a diff between files noting if one of them is not
|
||||||
|
* present. If both are not present or both are the same, null is returned.
|
||||||
|
*
|
||||||
|
* @param orig The original file.
|
||||||
|
* @param cur The current file.
|
||||||
|
* @param identifier The identifier for the header.
|
||||||
|
* @return The String representing the differences.
|
||||||
|
*/
|
||||||
|
private String getFileDiffs(File orig, File cur, String identifier) {
|
||||||
|
boolean hasOrig = (orig != null && orig.exists());
|
||||||
|
boolean hasCur = (cur != null && cur.exists());
|
||||||
|
if (!hasOrig && !hasCur) {
|
||||||
|
return null;
|
||||||
|
} else if (!hasOrig && hasCur) {
|
||||||
|
return getHeaderWithDivider("MISSING FILE IN CURRENT: " + identifier);
|
||||||
|
} else if (hasOrig && !hasCur) {
|
||||||
|
return getHeaderWithDivider("ADDITIONAL FILE IN CURRENT: " + identifier);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return diffLines(Files.readAllLines(orig.toPath()), Files.readAllLines(cur.toPath()), getHeaderWithDivider(identifier + ":"));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return getHeaderWithDivider(String.format("ERROR reading files at %s / %s %s%s",
|
||||||
|
orig.toString(), cur.toString(), NEW_LINE, ExceptionUtils.getStackTrace(ex)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getChunkLineNumString(Chunk<?> chunk) {
|
||||||
|
return String.format("%d,%d", chunk.getPosition() + 1, chunk.getLines().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a github-like line difference (i.e. -88,3 +90,3) of the form
|
||||||
|
* -orig_line_num,orig_lines, +new_line_num,new_lines.
|
||||||
|
*
|
||||||
|
* @param orig The previous chunk.
|
||||||
|
* @param cur The current chunk.
|
||||||
|
* @return The line number difference.
|
||||||
|
*/
|
||||||
|
private String getDiffLineNumString(Chunk<?> orig, Chunk<?> cur) {
|
||||||
|
return String.format("-%s +%s", getChunkLineNumString(orig), getChunkLineNumString(cur));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a line by line difference similar to integration tests like:
|
||||||
|
* < original
|
||||||
|
* > new
|
||||||
|
*
|
||||||
|
* @param orig The original chunk.
|
||||||
|
* @param cur The new chunk.
|
||||||
|
* @return The lines representing the diff.
|
||||||
|
*/
|
||||||
|
private List<String> getLinesDiff(Chunk<String> orig, Chunk<String> cur) {
|
||||||
|
Stream<String> origPrefixed = orig.getLines().stream()
|
||||||
|
.map((line) -> ORIG_LINE_PREFIX + line);
|
||||||
|
|
||||||
|
Stream<String> curPrefixed = cur.getLines().stream()
|
||||||
|
.map((line) -> CUR_LINE_PREFIX + line);
|
||||||
|
|
||||||
|
return Stream.concat(origPrefixed, curPrefixed)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLinesDiffString(AbstractDelta<String> delta) {
|
||||||
|
String lineNums = getDiffLineNumString(delta.getSource(), delta.getTarget());
|
||||||
|
List<String> linesDiff = getLinesDiff(delta.getSource(), delta.getTarget());
|
||||||
|
|
||||||
|
return Stream.concat(Stream.of(lineNums), linesDiff.stream())
|
||||||
|
.collect(Collectors.joining(NEW_LINE)) + NEW_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a line difference String with a header if non-null. Null is
|
||||||
|
* returned if there is no diff.
|
||||||
|
*
|
||||||
|
* @param orig The original lines.
|
||||||
|
* @param cur The current lines.
|
||||||
|
* @param header The header to be used if non-null diff. If header is null,
|
||||||
|
* no header included.
|
||||||
|
* @return The pretty-printed diff.
|
||||||
|
*/
|
||||||
|
private String diffLines(List<String> orig, List<String> cur, String header) {
|
||||||
|
//compute the patch: this is the diffutils part
|
||||||
|
Patch<String> patch = DiffUtils.diff(orig, cur);
|
||||||
|
|
||||||
|
String diff = patch.getDeltas().stream()
|
||||||
|
.map(delta -> getLinesDiffString(delta))
|
||||||
|
.collect(Collectors.joining(String.join(NEW_LINE, DIFF_BREAK)));
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(diff)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (header != null)
|
||||||
|
? header + NEW_LINE + diff
|
||||||
|
: diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getHeaderWithDivider(String remark) {
|
||||||
|
String divider = "-----------------------------------------------------------";
|
||||||
|
return String.join(NEW_LINE, divider, remark, divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRelative(File rootDirectory, File file) {
|
||||||
|
return rootDirectory.toURI().relativize(file.toURI()).getPath();
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,8 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.cxf.common.util.CollectionUtils;
|
import org.apache.cxf.common.util.CollectionUtils;
|
||||||
import org.netbeans.junit.NbModuleSuite;
|
import org.netbeans.junit.NbModuleSuite;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
@ -65,6 +67,7 @@ public class MainTestRunner extends TestCase {
|
|||||||
private static final Logger logger = Logger.getLogger(MainTestRunner.class.getName());
|
private static final Logger logger = Logger.getLogger(MainTestRunner.class.getName());
|
||||||
private static final String CONFIG_FILE_KEY = "integrationConfigFile";
|
private static final String CONFIG_FILE_KEY = "integrationConfigFile";
|
||||||
private static final ConfigDeserializer configDeserializer = new ConfigDeserializer();
|
private static final ConfigDeserializer configDeserializer = new ConfigDeserializer();
|
||||||
|
private static final DiffService diffService = new DiffService();
|
||||||
private static final ConfigurationModuleManager configurationModuleManager = new ConfigurationModuleManager();
|
private static final ConfigurationModuleManager configurationModuleManager = new ConfigurationModuleManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,63 +110,67 @@ public class MainTestRunner extends TestCase {
|
|||||||
|
|
||||||
if (!CollectionUtils.isEmpty(config.getTestSuites())) {
|
if (!CollectionUtils.isEmpty(config.getTestSuites())) {
|
||||||
for (TestSuiteConfig testSuiteConfig : config.getTestSuites()) {
|
for (TestSuiteConfig testSuiteConfig : config.getTestSuites()) {
|
||||||
String caseName = testSuiteConfig.getName();
|
|
||||||
|
|
||||||
for (CaseType caseType : IntegrationCaseType.getCaseTypes(testSuiteConfig.getCaseTypes())) {
|
for (CaseType caseType : IntegrationCaseType.getCaseTypes(testSuiteConfig.getCaseTypes())) {
|
||||||
// create an autopsy case for each case in the config and for each case type for the specified case.
|
|
||||||
// then run ingest for the case.
|
|
||||||
Case autopsyCase = createCaseWithDataSources(
|
|
||||||
envConfig.getWorkingDirectory(),
|
|
||||||
envConfig.getRootCaseOutputPath(),
|
|
||||||
caseName,
|
|
||||||
caseType,
|
|
||||||
testSuiteConfig.getDataSources());
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// run configuration modules and get result
|
|
||||||
Pair<IngestJobSettings, List<ConfigurationModule<?>>> configurationResult
|
|
||||||
= configurationModuleManager.runConfigurationModules(caseName, testSuiteConfig.getConfigurationModules());
|
|
||||||
|
|
||||||
IngestJobSettings ingestSettings = configurationResult.first();
|
|
||||||
List<ConfigurationModule<?>> configModules = configurationResult.second();
|
|
||||||
|
|
||||||
// run ingest with ingest settings derived from configuration modules.
|
|
||||||
runIngest(autopsyCase, ingestSettings, caseName);
|
|
||||||
|
|
||||||
// once ingested, run integration tests to produce output.
|
|
||||||
OutputResults results = runIntegrationTests(testSuiteConfig.getIntegrationTests());
|
|
||||||
|
|
||||||
// revert any autopsy environment changes made by configuration modules.
|
|
||||||
configurationModuleManager.revertConfigurationModules(configModules);
|
|
||||||
|
|
||||||
String outputFolder = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootTestOutputPath());
|
|
||||||
|
|
||||||
// write the results for the case to a file
|
|
||||||
results.serializeToFile(
|
|
||||||
envConfig.getUseRelativeOutput() == true ?
|
|
||||||
Paths.get(outputFolder, testSuiteConfig.getRelativeOutputPath()).toString() :
|
|
||||||
outputFolder,
|
|
||||||
testSuiteConfig.getName(),
|
|
||||||
caseType
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Case.closeCurrentCase();
|
runIntegrationTestSuite(envConfig, caseType, testSuiteConfig);
|
||||||
} catch (CaseActionException ex) {
|
} catch (CaseActionException | IllegalStateException ex) {
|
||||||
logger.log(Level.WARNING, "There was an error while trying to close current case: {0}", caseName);
|
logger.log(Level.WARNING, "There was an error working with current case: " + testSuiteConfig.getName(), ex);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write diff to file if requested
|
||||||
|
writeDiff(envConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a single test suite.
|
||||||
|
*
|
||||||
|
* @param envConfig The integrationt test environment config.
|
||||||
|
* @param caseType The type of case (single user, multi user).
|
||||||
|
* @param testSuiteConfig The configuration for the case.
|
||||||
|
*/
|
||||||
|
private void runIntegrationTestSuite(EnvConfig envConfig, CaseType caseType, TestSuiteConfig testSuiteConfig) throws CaseActionException, IllegalStateException {
|
||||||
|
|
||||||
|
String caseName = testSuiteConfig.getName();
|
||||||
|
|
||||||
|
// create an autopsy case for each case in the config and for each case type for the specified case.
|
||||||
|
// then run ingest for the case.
|
||||||
|
Case autopsyCase = createCaseWithDataSources(
|
||||||
|
envConfig.getWorkingDirectory(),
|
||||||
|
envConfig.getRootCaseOutputPath(),
|
||||||
|
caseName,
|
||||||
|
caseType,
|
||||||
|
testSuiteConfig.getDataSources());
|
||||||
|
if (autopsyCase == null || autopsyCase != Case.getCurrentCase()) {
|
||||||
|
throw new IllegalStateException(String.format("Case was not properly ingested or setup correctly for environment. Case is %s and current case is %s.",
|
||||||
|
autopsyCase, Case.getCurrentCase()));
|
||||||
|
}
|
||||||
|
// run configuration modules and get result
|
||||||
|
Pair<IngestJobSettings, List<ConfigurationModule<?>>> configurationResult
|
||||||
|
= configurationModuleManager.runConfigurationModules(caseName, testSuiteConfig.getConfigurationModules());
|
||||||
|
IngestJobSettings ingestSettings = configurationResult.first();
|
||||||
|
List<ConfigurationModule<?>> configModules = configurationResult.second();
|
||||||
|
// run ingest with ingest settings derived from configuration modules.
|
||||||
|
runIngest(autopsyCase, ingestSettings, caseName);
|
||||||
|
// once ingested, run integration tests to produce output.
|
||||||
|
OutputResults results = runIntegrationTests(testSuiteConfig.getIntegrationTests());
|
||||||
|
// revert any autopsy environment changes made by configuration modules.
|
||||||
|
configurationModuleManager.revertConfigurationModules(configModules);
|
||||||
|
String outputFolder = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootTestOutputPath());
|
||||||
|
// write the results for the case to a file
|
||||||
|
results.serializeToFile(
|
||||||
|
envConfig.getUseRelativeOutput() == true
|
||||||
|
? Paths.get(outputFolder, testSuiteConfig.getRelativeOutputPath()).toString()
|
||||||
|
: outputFolder,
|
||||||
|
testSuiteConfig.getName(),
|
||||||
|
caseType
|
||||||
|
);
|
||||||
|
|
||||||
|
Case.closeCurrentCase();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a case with the given data sources.
|
* Creates a case with the given data sources.
|
||||||
*
|
*
|
||||||
@ -241,6 +248,7 @@ public class MainTestRunner extends TestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs ingest on the current case.
|
* Runs ingest on the current case.
|
||||||
|
*
|
||||||
* @param openCase The currently open case.
|
* @param openCase The currently open case.
|
||||||
* @param ingestJobSettings The ingest job settings to be used.
|
* @param ingestJobSettings The ingest job settings to be used.
|
||||||
* @param caseName The name of the case to be used for error messages.
|
* @param caseName The name of the case to be used for error messages.
|
||||||
@ -291,7 +299,7 @@ public class MainTestRunner extends TestCase {
|
|||||||
if (testMethod.getParameters().length > 1) {
|
if (testMethod.getParameters().length > 1) {
|
||||||
throw new IllegalArgumentException(String.format("Could not call method %s in class %s. Multiple parameters cannot be handled.",
|
throw new IllegalArgumentException(String.format("Could not call method %s in class %s. Multiple parameters cannot be handled.",
|
||||||
testMethod.getName(), testGroup.getClass().getCanonicalName()));
|
testMethod.getName(), testGroup.getClass().getCanonicalName()));
|
||||||
// if there is a parameter, deserialize parameters to the specified type.
|
// if there is a parameter, deserialize parameters to the specified type.
|
||||||
} else if (testMethod.getParameters().length > 0) {
|
} else if (testMethod.getParameters().length > 0) {
|
||||||
parameters = new Object[]{configDeserializer.convertToObj(parametersMap, testMethod.getParameterTypes()[0])};
|
parameters = new Object[]{configDeserializer.convertToObj(parametersMap, testMethod.getParameterTypes()[0])};
|
||||||
}
|
}
|
||||||
@ -312,12 +320,13 @@ public class MainTestRunner extends TestCase {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a test method in a test suite on the current case.
|
* Runs a test method in a test suite on the current case.
|
||||||
|
*
|
||||||
* @param testGroup The test suite to which the method belongs.
|
* @param testGroup The test suite to which the method belongs.
|
||||||
* @param testMethod The java reflection method to run.
|
* @param testMethod The java reflection method to run.
|
||||||
* @param parameters The parameters to use with this method or none/empty array.
|
* @param parameters The parameters to use with this method or none/empty
|
||||||
|
* array.
|
||||||
* @return The results of running the method.
|
* @return The results of running the method.
|
||||||
*/
|
*/
|
||||||
private Object runIntegrationTestMethod(IntegrationTestGroup testGroup, Method testMethod, Object[] parameters) {
|
private Object runIntegrationTestMethod(IntegrationTestGroup testGroup, Method testMethod, Object[] parameters) {
|
||||||
@ -343,4 +352,39 @@ public class MainTestRunner extends TestCase {
|
|||||||
|
|
||||||
return serializableResult;
|
return serializableResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes any differences found between gold and output to a diff file. Only
|
||||||
|
* works if a gold and diff location are specified in the EnvConfig.
|
||||||
|
*
|
||||||
|
* @param envConfig The env config.
|
||||||
|
*/
|
||||||
|
private void writeDiff(EnvConfig envConfig) {
|
||||||
|
if (StringUtils.isBlank(envConfig.getRootGoldPath()) || StringUtils.isBlank(envConfig.getDiffOutputPath())) {
|
||||||
|
logger.log(Level.INFO, "gold path or diff output path not specified. Not creating diff.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String goldPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootGoldPath());
|
||||||
|
File goldDir = new File(goldPath);
|
||||||
|
if (!goldDir.exists()) {
|
||||||
|
logger.log(Level.WARNING, String.format("Gold does not exist at location: %s. Not creating diff.", goldDir.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
String outputPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getRootCaseOutputPath());
|
||||||
|
File outputDir = new File(outputPath);
|
||||||
|
if (!outputDir.exists()) {
|
||||||
|
logger.log(Level.WARNING, String.format("Output path does not exist at location: %s. Not creating diff.", outputDir.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
String diffPath = PathUtil.getAbsolutePath(envConfig.getWorkingDirectory(), envConfig.getDiffOutputPath());
|
||||||
|
String diff = diffService.diffFilesOrDirs(goldDir, outputDir);
|
||||||
|
if (StringUtils.isNotBlank(diff)) {
|
||||||
|
try {
|
||||||
|
FileUtils.writeStringToFile(new File(diffPath), diff, "UTF-8");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Unable to write diff file to " + diffPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,15 @@ public class EnvConfig {
|
|||||||
private final String rootCaseOutputPath;
|
private final String rootCaseOutputPath;
|
||||||
private final String rootTestOutputPath;
|
private final String rootTestOutputPath;
|
||||||
private final String rootTestSuitesPath;
|
private final String rootTestSuitesPath;
|
||||||
|
private final String rootGoldPath;
|
||||||
|
private final String diffOutputPath;
|
||||||
|
|
||||||
private final ConnectionConfig connectionInfo;
|
private final ConnectionConfig connectionInfo;
|
||||||
|
|
||||||
private String workingDirectory;
|
private String workingDirectory;
|
||||||
private Boolean useRelativeOutput;
|
private Boolean useRelativeOutput;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main constructor.
|
* Main constructor.
|
||||||
*
|
*
|
||||||
@ -50,6 +53,8 @@ public class EnvConfig {
|
|||||||
* the same relative path structure as the file (i.e. if file was found at
|
* the same relative path structure as the file (i.e. if file was found at
|
||||||
* /rootTestSuitesPath/folderX/fileY.json then it will now be outputted in
|
* /rootTestSuitesPath/folderX/fileY.json then it will now be outputted in
|
||||||
* /rootTestOutputPath/folderX/fileY/)
|
* /rootTestOutputPath/folderX/fileY/)
|
||||||
|
* @param rootGoldPath The path to the gold data for diff comparison.
|
||||||
|
* @param diffOutputPath The file location for diff output.
|
||||||
*/
|
*/
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public EnvConfig(
|
public EnvConfig(
|
||||||
@ -58,11 +63,15 @@ public class EnvConfig {
|
|||||||
@JsonProperty("rootTestOutputPath") String rootTestOutputPath,
|
@JsonProperty("rootTestOutputPath") String rootTestOutputPath,
|
||||||
@JsonProperty("connectionInfo") ConnectionConfig connectionInfo,
|
@JsonProperty("connectionInfo") ConnectionConfig connectionInfo,
|
||||||
@JsonProperty("workingDirectory") String workingDirectory,
|
@JsonProperty("workingDirectory") String workingDirectory,
|
||||||
@JsonProperty("useRelativeOutput") Boolean useRelativeOutput) {
|
@JsonProperty("useRelativeOutput") Boolean useRelativeOutput,
|
||||||
|
@JsonProperty("rootGoldPath") String rootGoldPath,
|
||||||
|
@JsonProperty("diffOutputPath") String diffOutputPath) {
|
||||||
|
|
||||||
this.rootCaseOutputPath = rootCaseOutputPath;
|
this.rootCaseOutputPath = rootCaseOutputPath;
|
||||||
this.rootTestOutputPath = rootTestOutputPath;
|
this.rootTestOutputPath = rootTestOutputPath;
|
||||||
this.rootTestSuitesPath = rootTestSuitesPath;
|
this.rootTestSuitesPath = rootTestSuitesPath;
|
||||||
|
this.rootGoldPath = rootGoldPath;
|
||||||
|
this.diffOutputPath = diffOutputPath;
|
||||||
this.connectionInfo = connectionInfo;
|
this.connectionInfo = connectionInfo;
|
||||||
|
|
||||||
this.workingDirectory = workingDirectory;
|
this.workingDirectory = workingDirectory;
|
||||||
@ -139,4 +148,20 @@ public class EnvConfig {
|
|||||||
public void setUseRelativeOutput(boolean useRelativeOutput) {
|
public void setUseRelativeOutput(boolean useRelativeOutput) {
|
||||||
this.useRelativeOutput = useRelativeOutput;
|
this.useRelativeOutput = useRelativeOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path to the gold data for diff comparison.
|
||||||
|
*/
|
||||||
|
public String getRootGoldPath() {
|
||||||
|
return rootGoldPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The file location for diff output.
|
||||||
|
*/
|
||||||
|
public String getDiffOutputPath() {
|
||||||
|
return diffOutputPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user