() {
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- for (PathMatcher matcher : matchers) {
- if (matcher.matches(file)) {
- paths.add(file);
- break;
- }
- }
-
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFileFailed(Path file, IOException exc) {
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
- return FileVisitResult.CONTINUE;
- }
- });
- } catch (IOException e) {
- LOG.warn("Could not walk tree and get all test xml files: {}", e.toString());
- }
- return paths;
- }
-
- /**
- * Unzip test results in memory and return test names and durations.
- * Assumes the input stream contains only csv files of the correct format.
- *
- * @param tests reference to the Tests object to be populated.
- * @param zippedInputStream stream containing zipped result file(s)
- */
- static void addTestsFromZippedCsv(@NotNull final Tests tests,
- @NotNull final InputStream zippedInputStream) {
- // We need this because ArchiveStream requires the `mark` functionality which is supported in buffered streams.
- final BufferedInputStream bufferedInputStream = new BufferedInputStream(zippedInputStream);
- try (ArchiveInputStream archiveInputStream = new ArchiveStreamFactory().createArchiveInputStream(bufferedInputStream)) {
- ArchiveEntry e;
- while ((e = archiveInputStream.getNextEntry()) != null) {
- if (e.isDirectory()) continue;
-
- // We seem to need to take a copy of the original input stream (as positioned by the ArchiveEntry), because
- // the XML parsing closes the stream after it has finished. This has the side effect of only parsing the first
- // entry in the archive.
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- IOUtils.copy(archiveInputStream, outputStream);
- ByteArrayInputStream byteInputStream = new ByteArrayInputStream(outputStream.toByteArray());
-
- // Read the tests from the (csv) stream
- final InputStreamReader reader = new InputStreamReader(byteInputStream);
-
- // Add the tests to the Tests object
- tests.addTests(Tests.read(reader));
- }
- } catch (ArchiveException | IOException e) {
- LOG.warn("Problem unzipping XML test results");
- }
-
- LOG.debug("Discovered {} tests", tests.size());
- }
-
- /**
- * For a given stream, return the testcase names and durations.
- *
- * NOTE: the input stream will be closed by this method.
- *
- * @param inputStream an InputStream, closed once parsed
- * @return a list of test names and their durations in nanos.
- */
- @NotNull
- static List> fromJunitXml(@NotNull final InputStream inputStream) {
- final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- final List> results = new ArrayList<>();
-
- try {
- final DocumentBuilder builder = dbFactory.newDocumentBuilder();
- final Document document = builder.parse(inputStream);
- document.getDocumentElement().normalize();
- final XPathFactory xPathfactory = XPathFactory.newInstance();
- final XPath xpath = xPathfactory.newXPath();
- final XPathExpression expression = xpath.compile("//testcase");
- final NodeList nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
-
- final BiFunction get =
- (a, k) -> a.getNamedItem(k) != null ? a.getNamedItem(k).getNodeValue() : "";
-
- for (int i = 0; i < nodeList.getLength(); i++) {
- final Node item = nodeList.item(i);
- final NamedNodeMap attributes = item.getAttributes();
- final String testName = get.apply(attributes, "name");
- final String testDuration = get.apply(attributes, "time");
- final String testClassName = get.apply(attributes, "classname");
-
- // If the test doesn't have a duration (it should), we return zero.
- if (!(testName.isEmpty() || testClassName.isEmpty())) {
- final long nanos = !testDuration.isEmpty() ? (long) (Double.parseDouble(testDuration) * 1_000_000_000.0) : 0L;
- results.add(new Tuple2<>(testClassName + "." + testName, nanos));
- } else {
- LOG.warn("Bad test in junit xml: name={} className={}", testName, testClassName);
- }
- }
- } catch (ParserConfigurationException | IOException | XPathExpressionException | SAXException e) {
- return Collections.emptyList();
- }
-
- return results;
- }
-
- /**
- * A supplier of tests.
- *
- * We get them from Artifactory and then parse the test xml files to get the duration.
- *
- * @return a supplier of test results
- */
- @NotNull
- static Supplier getTestsSupplier() {
- return TestDurationArtifacts::loadTests;
- }
-
- /**
- * we need to prepend the project type so that we have a unique tag for artifactory
- *
- * @return
- */
- static String getBranchTag() {
- return (Properties.getRootProjectType() + "-" + Properties.getGitBranch()).replace('.', '-');
- }
-
- /**
- * we need to prepend the project type so that we have a unique tag artifactory
- *
- * @return
- */
- static String getTargetBranchTag() {
- return (Properties.getRootProjectType() + "-" + Properties.getTargetGitBranch()).replace('.', '-');
- }
-
- /**
- * Load the tests from Artifactory, in-memory. No temp file used. Existing test data is cleared.
- *
- * @return a reference to the loaded tests.
- */
- static Tests loadTests() {
- LOG.warn("LOADING previous test runs from Artifactory");
- tests.clear();
- try {
- final TestDurationArtifacts testArtifacts = new TestDurationArtifacts();
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
- // Try getting artifacts for our branch, if not, try the target branch.
- if (!testArtifacts.get(getBranchTag(), outputStream)) {
- outputStream = new ByteArrayOutputStream();
- LOG.warn("Could not get tests from Artifactory for tag {}, trying {}", getBranchTag(), getTargetBranchTag());
- if (!testArtifacts.get(getTargetBranchTag(), outputStream)) {
- LOG.warn("Could not get any tests from Artifactory");
- return tests;
- }
- }
-
- ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
- addTestsFromZippedCsv(tests, inputStream);
- LOG.warn("Got {} tests from Artifactory", tests.size());
- return tests;
- } catch (Exception e) { // was IOException
- LOG.warn(e.toString());
- LOG.warn("Could not get tests from Artifactory");
- return tests;
- }
- }
-
- /**
- * Get tests for the specified tag in the outputStream
- *
- * @param theTag tag for tests
- * @param outputStream stream of zipped xml files
- * @return false if we fail to get the tests
- */
- private boolean get(@NotNull final String theTag, @NotNull final OutputStream outputStream) {
- return artifactory.get(BASE_URL, theTag, ARTIFACT, "zip", outputStream);
- }
-
- /**
- * Upload the supplied tests
- *
- * @param theTag tag for tests
- * @param inputStream stream of zipped xml files.
- * @return true if we succeed
- */
- private boolean put(@NotNull final String theTag, @NotNull final InputStream inputStream) {
- return artifactory.put(BASE_URL, theTag, ARTIFACT, EXTENSION, inputStream);
- }
-}
-
diff --git a/buildSrc/src/main/groovy/net/corda/testing/Tests.java b/buildSrc/src/main/groovy/net/corda/testing/Tests.java
deleted file mode 100644
index 26e01e1db0..0000000000
--- a/buildSrc/src/main/groovy/net/corda/testing/Tests.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package net.corda.testing;
-
-import groovy.lang.Tuple2;
-import groovy.lang.Tuple3;
-import org.apache.commons.csv.CSVFormat;
-import org.apache.commons.csv.CSVPrinter;
-import org.apache.commons.csv.CSVRecord;
-import org.jetbrains.annotations.NotNull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-public class Tests {
- final static String TEST_NAME = "Test Name";
- final static String MEAN_DURATION_NANOS = "Mean Duration Nanos";
- final static String NUMBER_OF_RUNS = "Number of runs";
- private static final Logger LOG = LoggerFactory.getLogger(Tests.class);
- // test name -> (mean duration, number of runs)
- private final Map> tests = new HashMap<>();
- // If we don't have any tests from which to get a mean, use this.
- static long DEFAULT_MEAN_NANOS = 1000L;
-
- private static Tuple2 DEFAULT_MEAN_TUPLE = new Tuple2<>(DEFAULT_MEAN_NANOS, 0L);
- // mean, count
- private Tuple2 meanForTests = DEFAULT_MEAN_TUPLE;
-
- /**
- * Read tests, mean duration and runs from a csv file.
- *
- * @param reader a reader
- * @return list of tests, or an empty list if none or we have a problem.
- */
- public static List> read(Reader reader) {
- try {
- List records = CSVFormat.DEFAULT.withHeader().parse(reader).getRecords();
- return records.stream().map(record -> {
- try {
- final String testName = record.get(TEST_NAME);
- final long testDuration = Long.parseLong(record.get(MEAN_DURATION_NANOS));
- final long testRuns = Long.parseLong(record.get(NUMBER_OF_RUNS)); // can't see how we would have zero tbh.
- return new Tuple3<>(testName, testDuration, Math.max(testRuns, 1));
- } catch (IllegalArgumentException | IllegalStateException e) {
- return null;
- }
- }).filter(Objects::nonNull).sorted(Comparator.comparing(Tuple3::getFirst)).collect(Collectors.toList());
- } catch (IOException ignored) {
-
- }
- return Collections.emptyList();
- }
-
- private static Tuple2 recalculateMean(@NotNull final Tuple2 previous, long nanos) {
- final long total = previous.getFirst() * previous.getSecond() + nanos;
- final long count = previous.getSecond() + 1;
- return new Tuple2<>(total / count, count);
- }
-
- /**
- * Write a csv file of test name, duration, runs
- *
- * @param writer a writer
- * @return true if no problems.
- */
- public boolean write(@NotNull final Writer writer) {
- boolean ok = true;
- final CSVPrinter printer;
- try {
- printer = new CSVPrinter(writer,
- CSVFormat.DEFAULT.withHeader(TEST_NAME, MEAN_DURATION_NANOS, NUMBER_OF_RUNS));
- for (String key : tests.keySet()) {
- printer.printRecord(key, tests.get(key).getFirst(), tests.get(key).getSecond());
- }
-
- printer.flush();
- } catch (IOException e) {
- ok = false;
- }
- return ok;
- }
-
- /**
- * Add tests, and also (re)calculate the mean test duration.
- * e.g. addTests(read(reader));
- *
- * @param testsCollection tests, typically from a csv file.
- */
- public void addTests(@NotNull final List> testsCollection) {
- testsCollection.forEach(t -> this.tests.put(t.getFirst(), new Tuple2<>(t.getSecond(), t.getThird())));
-
- // Calculate the mean test time.
- if (tests.size() > 0) {
- long total = 0;
- for (String testName : this.tests.keySet()) total += tests.get(testName).getFirst();
- meanForTests = new Tuple2<>(total / this.tests.size(), 1L);
- }
- }
-
- /**
- * Get the known mean duration of a test.
- *
- * @param testName the test name
- * @return duration in nanos.
- */
- public long getDuration(@NotNull final String testName) {
- return tests.getOrDefault(testName, meanForTests).getFirst();
- }
-
- /**
- * Add test information. Recalulates mean test duration if already exists.
- *
- * @param testName name of the test
- * @param durationNanos duration
- */
- public void addDuration(@NotNull final String testName, long durationNanos) {
- final Tuple2 current = tests.getOrDefault(testName, new Tuple2<>(0L, 0L));
-
- tests.put(testName, recalculateMean(current, durationNanos));
-
- LOG.debug("Recorded test '{}', mean={} ns, runs={}", testName, tests.get(testName).getFirst(), tests.get(testName).getSecond());
-
- meanForTests = recalculateMean(meanForTests, durationNanos);
- }
-
- /**
- * Do we have any test information?
- *
- * @return false if no tests info
- */
- public boolean isEmpty() {
- return tests.isEmpty();
- }
-
- /**
- * How many tests do we have?
- *
- * @return the number of tests we have information for
- */
- public int size() {
- return tests.size();
- }
-
- /**
- * Return all tests (and their durations) that being with (or are equal to) `testPrefix`
- * If not present we just return the mean test duration so that the test is fairly distributed.
- * @param testPrefix could be just the classname, or the entire classname + testname.
- * @return list of matching tests
- */
- @NotNull
- List> startsWith(@NotNull final String testPrefix) {
- List> results = this.tests.keySet().stream()
- .filter(t -> t.startsWith(testPrefix))
- .map(t -> new Tuple2<>(t, getDuration(t)))
- .collect(Collectors.toList());
- // We don't know if the testPrefix is a classname or classname.methodname (exact match).
- if (results == null || results.isEmpty()) {
- LOG.warn("In {} previously executed tests, could not find any starting with {}", tests.size(), testPrefix);
- results = Arrays.asList(new Tuple2<>(testPrefix, getMeanDurationForTests()));
- }
- return results;
- }
-
- @NotNull
- List> equals(@NotNull final String testPrefix) {
- List> results = this.tests.keySet().stream()
- .filter(t -> t.equals(testPrefix))
- .map(t -> new Tuple2<>(t, getDuration(t)))
- .collect(Collectors.toList());
- // We don't know if the testPrefix is a classname or classname.methodname (exact match).
- if (results == null || results.isEmpty()) {
- LOG.warn("In {} previously executed tests, could not find any starting with {}", tests.size(), testPrefix);
- results = Arrays.asList(new Tuple2<>(testPrefix, getMeanDurationForTests()));
- }
- return results;
- }
-
- /**
- * How many times has this function been run? Every call to addDuration increments the current value.
- *
- * @param testName the test name
- * @return the number of times the test name has been run.
- */
- public long getRunCount(@NotNull final String testName) {
- return tests.getOrDefault(testName, new Tuple2<>(0L, 0L)).getSecond();
- }
-
- /**
- * Return the mean duration for a unit to run
- *
- * @return mean duration in nanos.
- */
- public long getMeanDurationForTests() {
- return meanForTests.getFirst();
- }
-
- /**
- * Clear all tests
- */
- void clear() {
- tests.clear();
- meanForTests = DEFAULT_MEAN_TUPLE;
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/net/corda/testing/KubePodResult.java b/buildSrc/src/main/java/net/corda/testing/KubePodResult.java
deleted file mode 100644
index 76ba668c39..0000000000
--- a/buildSrc/src/main/java/net/corda/testing/KubePodResult.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.corda.testing;
-
-import java.io.File;
-import java.util.Collection;
-
-public class KubePodResult {
-
- private final int podIndex;
- private final int resultCode;
- private final File output;
- private final Collection binaryResults;
-
- public KubePodResult(int podIndex, int resultCode, File output, Collection binaryResults) {
- this.podIndex = podIndex;
- this.resultCode = resultCode;
- this.output = output;
- this.binaryResults = binaryResults;
- }
-
- public int getResultCode() {
- return resultCode;
- }
-
- public File getOutput() {
- return output;
- }
-
- public Collection getBinaryResults() {
- return binaryResults;
- }
-
- public int getPodIndex() {
- return podIndex;
- }
-}
diff --git a/buildSrc/src/main/java/net/corda/testing/KubesReporting.java b/buildSrc/src/main/java/net/corda/testing/KubesReporting.java
deleted file mode 100644
index 4f8f8aee0c..0000000000
--- a/buildSrc/src/main/java/net/corda/testing/KubesReporting.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2012 the original author or authors.
- *
- * 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 net.corda.testing;
-
-import org.apache.commons.compress.utils.IOUtils;
-import org.gradle.api.DefaultTask;
-import org.gradle.api.GradleException;
-import org.gradle.api.Transformer;
-import org.gradle.api.file.FileCollection;
-import org.gradle.api.internal.file.UnionFileCollection;
-import org.gradle.api.internal.tasks.testing.junit.result.AggregateTestResultsProvider;
-import org.gradle.api.internal.tasks.testing.junit.result.BinaryResultBackedTestResultsProvider;
-import org.gradle.api.internal.tasks.testing.junit.result.TestResultsProvider;
-import org.gradle.api.internal.tasks.testing.report.DefaultTestReport;
-import org.gradle.api.tasks.OutputDirectory;
-import org.gradle.api.tasks.TaskAction;
-import org.gradle.api.tasks.testing.Test;
-import org.gradle.internal.logging.ConsoleRenderer;
-import org.gradle.internal.operations.BuildOperationExecutor;
-
-import javax.inject.Inject;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.gradle.internal.concurrent.CompositeStoppable.stoppable;
-import static org.gradle.util.CollectionUtils.collect;
-
-/**
- * Shameful copy of org.gradle.api.tasks.testing.TestReport - modified to handle results from k8s testing.
- * see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.TestReport.html
- */
-public class KubesReporting extends DefaultTask {
- private File destinationDir = new File(getProject().getBuildDir(), "test-reporting");
- private List