net.jqwik.engine.recording.TestRunDatabase Maven / Gradle / Ivy
package net.jqwik.engine.recording;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.logging.*;
public class TestRunDatabase {
private static final Logger LOG = Logger.getLogger(TestRunDatabase.class.getName());
private final Path databasePath;
private final TestRunData previousRunData;
private boolean stopRecording = false;
public TestRunDatabase(Path databasePath) {
this.databasePath = databasePath;
this.previousRunData = loadExistingRunData();
}
private TestRunData loadExistingRunData() {
if (!Files.exists(databasePath)) {
return new TestRunData();
}
try (ObjectInputStream ois = createObjectInputStream()) {
List data = readAllTestRuns(ois);
return new TestRunData(data);
} catch (Exception e) {
logReadException(e);
deleteDatabase();
return new TestRunData();
}
}
private void deleteDatabase() {
try {
Files.delete(databasePath);
} catch (IOException ignore) {
}
}
private List readAllTestRuns(ObjectInputStream ois) throws IOException, ClassNotFoundException {
List testRuns = new ArrayList<>();
while (true) {
try {
TestRun testRun = (TestRun) ois.readObject();
testRuns.add(testRun);
} catch (EOFException eof) {
break;
} catch (IOException eof) {
logReadException(eof);
deleteDatabase();
break;
}
}
return testRuns;
}
private void logReadException(Exception eof) {
LOG.log(Level.WARNING, eof, () -> String.format("Cannot read database [%s]", databasePath.toAbsolutePath()));
}
private void logWriteException(Exception e) {
LOG.log(Level.WARNING, e, () -> String.format("Cannot write database [%s]", databasePath.toAbsolutePath()));
}
private ObjectOutputStream createObjectOutputStream() {
try {
return new ObjectOutputStream(Files.newOutputStream(databasePath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING));
} catch (IOException e) {
stopRecording = true;
logWriteException(e);
return null;
}
}
private ObjectInputStream createObjectInputStream() throws IOException {
return new ObjectInputStream(Files.newInputStream(databasePath, StandardOpenOption.CREATE));
}
private class Recorder implements TestRunRecorder {
private final ObjectOutputStream objectOutputStream;
private Recorder(ObjectOutputStream objectOutputStream) {
this.objectOutputStream = objectOutputStream;
}
@Override
public void record(TestRun testRun) {
record(testRun, false);
}
private void record(TestRun testRun, boolean secondTry) {
if (stopRecording)
return;
try {
checkSerializability(testRun);
objectOutputStream.writeObject(testRun);
} catch (NotSerializableException e) {
if (!secondTry) {
record(testRun.withoutFalsifiedSample(), true);
} else {
logWriteException(e);
}
} catch (IOException e) {
stopRecording = true;
logWriteException(e);
}
}
private void checkSerializability(TestRun testRun) throws IOException {
ObjectOutputStream testStream = new ObjectOutputStream(new ByteArrayOutputStream());
testStream.writeObject(testRun);
}
@Override
public void close() {
try {
objectOutputStream.close();
} catch (IOException e) {
logWriteException(e);
}
}
}
public TestRunData previousRun() {
return previousRunData;
}
public TestRunRecorder recorder() {
return new Recorder(createObjectOutputStream());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy