blob: 52dfd527f8895ad7e40282b38f674c699567f8c0 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 vogar;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import vogar.commands.Mkdir;
import vogar.commands.Rm;
public final class OutcomeStore {
private static final String FILE_NAME_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssz";
private static final int PRESERVE_TOTAL = 10;
private static final Comparator<File> ORDER_BY_LAST_MODIFIED = new Comparator<File>() {
@Override public int compare(File a, File b) {
if (a.lastModified() != b.lastModified()) {
return a.lastModified() < b.lastModified() ? -1 : 1;
}
return 0;
}
};
private final Log log;
private final Mkdir mkdir;
private final Rm rm;
private final File resultsDir;
private final boolean recordResults;
private final ExpectationStore expectationStore;
private final Date date;
public OutcomeStore(Log log, Mkdir mkdir, Rm rm, File resultsDir, boolean recordResults,
ExpectationStore expectationStore, Date date) {
this.log = log;
this.mkdir = mkdir;
this.rm = rm;
this.resultsDir = resultsDir;
this.recordResults = recordResults;
this.expectationStore = expectationStore;
this.date = date;
}
public Map<String, AnnotatedOutcome> read(Map<String, Outcome> outcomes) {
Map<String, AnnotatedOutcome> result = new LinkedHashMap<String, AnnotatedOutcome>();
for (Map.Entry<String, Outcome> entry : outcomes.entrySet()) {
Outcome outcome = entry.getValue();
Expectation expectation = expectationStore.get(outcome);
result.put(entry.getKey(), new AnnotatedOutcome(outcome, expectation));
}
try {
File[] oldOutcomes = getOutcomeFiles();
log.verbose("parsing outcomes from " + oldOutcomes.length + " files");
for (File file : oldOutcomes) {
if (!file.getName().endsWith(".json")) {
continue;
}
loadOutcomes(result, file, file.lastModified());
}
} catch (IOException e) {
log.info("Failed to read outcomes from " + resultsDir, e);
}
return result;
}
private void loadOutcomes(Map<String, AnnotatedOutcome> map, File file, long fileDate)
throws IOException {
JsonReader in = new JsonReader(new FileReader(file));
in.beginObject();
while (in.hasNext()) {
String outcomeName = in.nextName();
AnnotatedOutcome annotatedOutcome = map.get(outcomeName);
if (annotatedOutcome == null) {
in.skipValue();
continue;
}
Result result = null;
in.beginObject();
while (in.hasNext()) {
String fieldName = in.nextName();
if (fieldName.equals("result")) {
result = Result.valueOf(in.nextString());
} else {
in.skipValue();
}
}
in.endObject();
annotatedOutcome.add(fileDate, new Outcome(outcomeName, result,
Collections.<String>emptyList()));
}
in.endObject();
in.close();
}
public void write(Map<String, Outcome> outcomes) {
if (!recordResults) {
return;
}
makeRoom();
File outputFile = getOutputFile();
try {
mkdir.mkdirs(outputFile.getParentFile());
JsonWriter out = new JsonWriter(new FileWriter(outputFile));
out.setIndent(" ");
out.beginObject();
for (Map.Entry<String, Outcome> entry : outcomes.entrySet()) {
out.name(entry.getKey());
out.beginObject();
out.name("result");
out.value(entry.getValue().getResult().toString());
out.endObject();
}
out.endObject();
out.close();
} catch (IOException e) {
log.info("Failed to write outcomes to " + outputFile, e);
}
}
private File[] getOutcomeFiles() {
File[] result = resultsDir.listFiles();
if (result == null) {
return new File[0];
}
Arrays.sort(result, ORDER_BY_LAST_MODIFIED);
return result;
}
private File getOutputFile() {
SimpleDateFormat dateFormat = new SimpleDateFormat(FILE_NAME_DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
dateFormat.setLenient(true);
String timestamp = dateFormat.format(date);
return new File(resultsDir, timestamp + ".json");
}
/**
* Removes the oldest result files until only (PRESERVE_TOTAL - 1) remain.
*/
private void makeRoom() {
File[] outcomeFiles = getOutcomeFiles();
for (int i = 0; i <= (outcomeFiles.length - PRESERVE_TOTAL); i++) {
rm.file(outcomeFiles[i]);
log.verbose("garbage collected results file: " + outcomeFiles[i]);
}
}
}