io.split.qos.server.QOSServerState Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qosrunner Show documentation
Show all versions of qosrunner Show documentation
Framework for running JUnit Tests as a Continous Service (QoS)
package io.split.qos.server;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.split.qos.server.util.TestId;
import org.joda.time.DateTime;
import org.junit.runner.Description;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
/**
* Maintains the state of the server that is shared accross the app.
*
*
* HOW LAST GREEN IS CALCULATED:
*
* The idea is to know when was the last time all the tests were green, so you can compare it with when you deployed.
* if lastGreen > whenYouDeployed, then means that all your tests have passed since you deployed and you are good to go.
*
* Roughly the algorithm is:
*
* - succeededInARow is a Map indexed by the testId and has as value when it succeeded.
* - if a test fails, then lastGreen is reset and succeededInARow is cleared
* - if a test succeeded, it adds itself to the succeededInARow map.
*
-
* if totalTests == succeededInARow.size(), means all the tests have passed. To find when was it green
* we check the earliest of all the succeeded tests.
*
*
*
*/
@Singleton
public class QOSServerState {
private Long lastGreen;
private Status status;
private Long activeSince;
private Long lastTestFinished;
private Long pausedSince;
private Map succeededInARow;
private Map tests;
private String who;
@Inject
public QOSServerState() {
this.status = Status.PAUSED;
this.activeSince = null;
this.pausedSince = DateTime.now().getMillis();
this.lastTestFinished = null;
this.lastGreen = null;
this.succeededInARow = Maps.newConcurrentMap();
this.tests = Maps.newConcurrentMap();
}
public void resume(String who) {
this.status = Status.ACTIVE;
this.who = who;
this.activeSince = DateTime.now().getMillis();
this.pausedSince = null;
}
public void pause(String who) {
this.status = Status.PAUSED;
this.who = who;
this.pausedSince = DateTime.now().getMillis();
this.activeSince = null;
}
public void registerTest(Description description) {
this.tests.put(TestId.fromDescription(description), TestStatus.get(null, null));
}
public void registerTest(Method method) {
this.tests.put(TestId.fromMethod(method), TestStatus.get(null, null));
}
public void testSucceeded(TestId testId) {
this.lastTestFinished = DateTime.now().getMillis();
this.tests.put(testId, TestStatus.get(lastTestFinished, true));
this.succeededInARow.put(testId, lastTestFinished);
if (succeededInARow.size() == tests.size()) {
lastGreen = Collections.min(succeededInARow.values());
}
}
public void testSucceeded(Description description) {
testSucceeded(TestId.fromDescription(description));;
}
public void testFailed(Description description) {
testFailed(TestId.fromDescription(description));
}
public void testFailed(TestId testId) {
this.lastTestFinished = DateTime.now().getMillis();
this.tests.put(testId, TestStatus.get(lastTestFinished, false));
this.succeededInARow.clear();
this.lastGreen = null;
}
public enum Status {
ACTIVE,
PAUSED,
;
}
public Status status() {
return status;
}
public Map tests() {
return tests;
}
public Map tests(String fuzzyClassOrName) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(fuzzyClassOrName));
return Maps.filterKeys(tests, input -> input.contains(fuzzyClassOrName));
}
public Map tests(String fuzzyClass, String fuzzyName) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(fuzzyClass));
Preconditions.checkArgument(!Strings.isNullOrEmpty(fuzzyName));
return Maps.filterKeys(tests, input -> input.contains(fuzzyClass, fuzzyName));
}
public TestStatus test(Method method) {
return test(TestId.fromMethod(Preconditions.checkNotNull(method)));
}
public TestStatus test(Description description) {
return test(TestId.fromDescription(Preconditions.checkNotNull(description)));
}
private TestStatus test(TestId id) {
return tests.get(Preconditions.checkNotNull(id));
}
public Map failedTests() {
return Maps.filterValues(tests, input -> input.succeeded() != null && !input.succeeded());
}
public Map missingTests() {
return Maps.filterValues(tests, input -> input.succeeded() == null);
}
public Map succeededTests() {
return Maps.filterValues(tests, input -> input.succeeded() != null && input.succeeded());
}
public boolean isActive() {
return Status.ACTIVE.equals(status());
}
public boolean isPaused() {
return Status.PAUSED.equals(status());
}
public String who() {
return who;
}
public Long activeSince() {
return activeSince;
}
public Long pausedSince() {
return pausedSince;
}
public Long lastTestFinished() {
return lastTestFinished;
}
public Long lastGreen() {
return lastGreen;
}
public static class TestStatus {
private final Long when;
private final Boolean succeeded;
private TestStatus(Long when, Boolean succeeded) {
this.when = when;
this.succeeded = succeeded;
}
public static TestStatus get(Long when, Boolean succeeded) {
return new TestStatus(when, succeeded);
}
public Long when() {
return when;
}
public boolean hasFinished() {
return when() != null;
}
public Boolean succeeded() {
return succeeded;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy