Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not run/Skipped test reporting #13

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@ public interface TestResultFactory {
* @return an appropriate TestResult object.
*/
TestResult error(String testName, Throwable throwable, Instant startTime, Instant endTime);

/**
* @param testName - the name of the test that did not run.
* @return an appropriate TestResult object.
*/
TestResult notExecuted(String testName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

public enum TestStatus {
PASS(0), FAIL(1), ERROR(2);
PASS(0), FAIL(1), ERROR(2), NOT_EXECUTED(3);

private int returnCode;
TestStatus(int returnCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.codice.itest.api.TestResult;
import org.codice.itest.api.TestResultFactory;
import org.codice.itest.config.ITestConfigurationProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -43,22 +42,25 @@ final class IntegrationTestService implements CommandLineRunner {

private ExecutorService executorService;

private SkipAwareExecutorService skipAwareExecutorService;

private TestResultFactory testResultFactory;

private ITestConfigurationProperties iTestConfigurationProperties;
/**
*
* @param tests - The set of all DiagnosticTest objects found in the Spring application context.
* @param testResultListenerList - A list of listeners to be notified upon test completion.
* @param executorService - Used to allow tests to be executed in parallel.
* @param tests - The set of all DiagnosticTest objects found in the Spring application context.
* @param testResultListenerList - A list of listeners to be notified upon test completion.
* @param executorService - Used to allow tests to be executed in parallel.
* @param skipAwareExecutorService - Used to allow tests to be executed in parallel while
*/
public IntegrationTestService(Stream<IntegrationTest> tests,
List<Consumer<TestResult>> testResultListenerList,
TestResultFactory testResultFactory,
SkipAwareExecutorService skipAwareExecutorService, TestResultFactory testResultFactory,
ExecutorService executorService,
ITestConfigurationProperties iTestConfigurationProperties) {
this.tests = tests;
this.testResultListenerList = testResultListenerList;
this.skipAwareExecutorService = skipAwareExecutorService;
this.testResultFactory = testResultFactory;
this.executorService = executorService;
this.iTestConfigurationProperties = iTestConfigurationProperties;
Expand All @@ -71,9 +73,9 @@ public IntegrationTestService(Stream<IntegrationTest> tests,
* @throws InterruptedException - When interrupted while waiting for a test to complete.
*/
public void run(String[] args) throws InterruptedException {
this.tests.forEach(test -> executorService.execute(new TestExecutorTask(test,
this.tests.forEach(test -> skipAwareExecutorService.execute(new TestExecutorTask(test,
testResultListenerList, testResultFactory)));
executorService.shutdown();
executorService.awaitTermination(iTestConfigurationProperties.maxExecutionMinutes(), TimeUnit.MINUTES);
skipAwareExecutorService.shutdown();
skipAwareExecutorService.awaitTermination(iTestConfigurationProperties.maxExecutionMinutes(), TimeUnit.MINUTES);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) Codice Foundation

* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the License, or any later version.

* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
* http://www.gnu.org/licenses/lgpl.html.
*/
package org.codice.itest;

import org.codice.itest.api.TestResult;
import org.codice.itest.api.TestResultFactory;
import org.codice.itest.config.ITestConfigurationProperties;
import org.codice.itest.reporter.RemainingTestsReporter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Component("SkipAwareExecutorService")
public class SkipAwareExecutorService extends ThreadPoolExecutor {
knekylen-smith marked this conversation as resolved.
Show resolved Hide resolved

@Value("${itest.tests:#{null}}")
private String tests;
knekylen-smith marked this conversation as resolved.
Show resolved Hide resolved

private List<Consumer<TestResult>> testResultListenerList;
private final ITestConfigurationProperties iTestConfigurationProperties;

private List<String> testNameList;

private RemainingTestsReporter remainingTestsReporter;

private TestResultFactory testResultFactory;

public SkipAwareExecutorService(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, List<Consumer<TestResult>> testResultListenerList, ITestConfigurationProperties iTestConfigurationProperties, RemainingTestsReporter remainingTestsReporter, TestResultFactory testResultFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
this.testResultListenerList = testResultListenerList;
this.iTestConfigurationProperties = iTestConfigurationProperties;
this.testNameList = iTestConfigurationProperties.tests();
this.remainingTestsReporter = remainingTestsReporter;
this.testResultFactory = testResultFactory;
}

@Override
public List<Runnable> shutdownNow() {
remainingTestsReporter.getRemainingList().forEach(testName -> {
TestResult testResult = testResultFactory.notExecuted(testName);
testResultListenerList.forEach(listener -> listener.accept(testResult));
});

return super.shutdownNow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void accept(TestResult testResult) {
break;
case FAIL: logger.warn(formattedResult);
break;
case ERROR: logger.error(formattedResult);
case ERROR, NOT_EXECUTED: logger.error(formattedResult);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) Codice Foundation

* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the License, or any later version.

* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
* http://www.gnu.org/licenses/lgpl.html.
*/
package org.codice.itest.reporter;

import org.codice.itest.api.TestResult;

import java.util.List;
import java.util.function.Consumer;

public class RemainingTestsReporter implements Consumer<TestResult> {
private List<String> testNames;
private List<String> remainingTestNames;

public RemainingTestsReporter(List<String> testNames){
this.testNames = testNames;
this.remainingTestNames = testNames;
}

@Override
public void accept(TestResult testResult) {
if(testNames.contains(testResult.getTestName())){
remainingTestNames.remove(testResult.getTestName());
}
}

public List<String> getRemainingList(){return remainingTestNames;}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@
import org.codice.itest.config.ITestConfigurationProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

@Configuration
public class TestReporterConfiguration {
private final ITestConfigurationProperties iTestConfigurationProperties;
private List<String> testNameList;

public TestReporterConfiguration(ITestConfigurationProperties iTestConfigurationProperties) {
this.iTestConfigurationProperties = iTestConfigurationProperties;
this.testNameList = iTestConfigurationProperties.tests();
}

@Bean
Expand All @@ -52,4 +57,9 @@ public Consumer<TestResult> defaultLoggingDiagnosticTestReporter() {
public Consumer<TestResult> exitCodeReporterConsumer(ExitCodeReporter exitCodeReporter) {
return (tr) -> exitCodeReporter.register(tr.getTestStatus());
}

@Bean("remainingTestsConsumer")
public Consumer<TestResult> remainingTestsReporterConsumer() {
return new RemainingTestsReporter(testNameList);
knekylen-smith marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright (c) Codice Foundation

* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the License, or any later version.

* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
* http://www.gnu.org/licenses/lgpl.html.
*/
package org.codice.itest.result;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.time.Instant;
import java.util.UUID;

import static org.codice.itest.api.TestStatus.NOT_EXECUTED;

final class NotExecutedTestResultImpl extends BaseTestResult{

NotExecutedTestResultImpl(UUID runId, String testName) {
super(runId, testName, NOT_EXECUTED, Instant.now(), Instant.now());
}

@Override
public String toString() {
return toStringCreator.append(super.getRunId())
.append(super.getTestStatus())
.append(super.getTestName())
.append(NOT_EXECUTED)
.toString();
}

@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}

if (other == this) {
return true;
}

if (!(other instanceof NotExecutedTestResultImpl testResult)) {
return false;
}

return new EqualsBuilder().append(super.getRunId(), testResult.getRunId())
.append(super.getTestName(), testResult.getTestName())
.append(super.getTestStatus(), testResult.getTestStatus())
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(1313, 4137).append(super.getRunId())
.append(super.getTestName())
.append(super.getTestStatus())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ public TestResult error(String testName, Throwable throwable, Instant startTime,
return new ErrorTestResultImpl(runId, testName, throwable, startTime, endTime);
}

@Override
public TestResult notExecuted(String testName) {
MDC.put(TEST_STATUS, TestStatus.NOT_EXECUTED.name());
return new NotExecutedTestResultImpl(runId, testName);
}

private void logTestResultCommonFields(String testName, Instant startTime, Instant endTime) {
MDC.clear();
MDC.put(TEST_NAME, testName);
Expand Down