/** * */ package jayhorn.test.soundness; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import com.google.gson.Gson; /** * @author schaef * */ public class BigSoundnessUtil { private static final int MAX_ELEMENTS = 3; public static void storeNewTestRun(Map<String, TestOutcome> testResults) { TestHistory results = getPreviousResults(SOUNDNESS_TEST_RESULTS); String commit_hash = "unknown_"+LocalDateTime.now(); try { commit_hash = new String(Files.readAllBytes(Paths.get(COMMIT_HASH_PATH)), Charset.forName("UTF-8")); } catch (IOException e) { e.printStackTrace(); } TestRun test = new TestRun(); test.commitHash = commit_hash; test.timeStamp = LocalDateTime.now(); test.testResults = testResults; for (Entry<String, TestOutcome> entry : testResults.entrySet()) { if (entry.getValue().equals(TestOutcome.CORRECT)) { test.correct++; } else if (entry.getValue().equals(TestOutcome.IMPRECISE)) { test.imprecise++; } else if (entry.getValue().equals(TestOutcome.UNSOUND)) { test.unsound++; } else if (entry.getValue().equals(TestOutcome.EXCEPTION)) { test.exception++; } } //print the diff if we have a history. if (!results.testRuns.isEmpty()) { printDiff(results.testRuns.getLast(), test); } results.testRuns.add(test); while (results.testRuns.size()>MAX_ELEMENTS) { results.testRuns.remove(0); } writeResults(SOUNDNESS_TEST_RESULTS, results); } private static boolean appendNumDiff(StringBuilder sb, int oldNum, int newNum) { if (oldNum!=newNum) { sb.append("("); sb.append(((newNum-oldNum)>0)?"+":"-"); sb.append(Math.abs(newNum-oldNum)); sb.append(")"); return true; } return false; } private static void printDiff(TestRun oldRun, TestRun newRun) { StringBuilder sb = new StringBuilder(); boolean change = false; sb.append(String.format("Correct: %1$3d", newRun.correct)); change = appendNumDiff(sb, oldRun.correct, newRun.correct) ? true : change; sb.append(String.format("\tImprecise: %1$3d", newRun.imprecise)); change = appendNumDiff(sb, oldRun.imprecise, newRun.imprecise) ? true : change; sb.append(String.format("\tUnsound: %1$3d", newRun.unsound)); change = appendNumDiff(sb, oldRun.unsound, newRun.unsound) ? true : change; sb.append(String.format("\tException: %1$3d", newRun.exception)); change = appendNumDiff(sb, oldRun.exception, newRun.exception) ? true : change; sb.append("\n"); if (change) { sb.append("*** Changes *** \n"); for (Entry<String, TestOutcome> entry : newRun.testResults.entrySet()) { if (!oldRun.testResults.containsKey(entry.getKey())) { sb.append(entry.getKey()); sb.append(" has been added.\n"); } else if (!entry.getValue().equals(oldRun.testResults.get(entry.getKey()))){ sb.append(entry.getKey()); sb.append(String.format(" changed from %1s to %2s.", oldRun.testResults.get(entry.getKey()), entry.getValue())); sb.append("\n"); } } } sb.append("*** End of Report *** \n"); System.out.println(sb.toString()); } private static String COMMIT_HASH_PATH = "../.git/ORIG_HEAD"; private static String SOUNDNESS_TEST_RESULTS = "../bigSoundnessHistory.json"; public static enum TestOutcome { CORRECT("Correct"), IMPRECISE("Imprecise"), UNSOUND("Unsound"), EXCEPTION("Exception"); private final String text; private TestOutcome(final String text) { this.text = text; } @Override public String toString() { return text; } } public static class TestHistory { public LinkedList<TestRun> testRuns; } public static class TestRun { public String commitHash; public LocalDateTime timeStamp; public Map<String, TestOutcome> testResults; public int correct, imprecise, unsound, exception; @Override public String toString() { StringBuilder s = new StringBuilder(); s.append(commitHash); s.append("\t" + timeStamp); s.append("\n"); s.append("Correct " + correct); s.append("\timprecise " + imprecise); s.append("\tunsound " + unsound); s.append("\texception" + exception); s.append("\n"); s.append(testResults); return s.toString(); } } private static TestHistory getPreviousResults(final String fileName) { Gson g = new Gson(); String jsonString = ""; try { jsonString = new String(Files.readAllBytes(Paths.get(fileName)), Charset.forName("UTF-8")); } catch (IOException e) { } TestHistory testHistory = g.fromJson(jsonString, TestHistory.class); if (testHistory==null) { testHistory = new TestHistory(); testHistory.testRuns = new LinkedList<TestRun>(); } return testHistory; } private static void writeResults(final String fileName, TestHistory results) { Gson g = new Gson(); final String jsonString = g.toJson(results); try ( OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(fileName), Charset.forName("UTF-8")); PrintWriter out = new PrintWriter(outputStreamWriter) ) { out.println(jsonString); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Map<String, TestOutcome> testResults = new LinkedHashMap<>(); testResults.put("test01", TestOutcome.EXCEPTION); testResults.put("test02", TestOutcome.CORRECT); testResults.put("test03", TestOutcome.CORRECT); storeNewTestRun(testResults); } }