blob: 42639907fb5e441cbd1b952fa1880bd927183331 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2019 Boeing.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.ote.simple.test.environment.outfile;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.eclipse.osee.framework.jdk.core.persistence.XmlizableStream;
import org.eclipse.osee.ote.core.environment.interfaces.ITestPoint;
import org.eclipse.osee.ote.core.log.record.ScriptResultRecord;
import org.eclipse.osee.ote.core.log.record.TestPointRecord;
import org.eclipse.osee.ote.core.log.record.json.LogRecordModule;
import org.eclipse.osee.ote.core.testPoint.CheckGroup;
import org.eclipse.osee.ote.core.testPoint.CheckPoint;
import org.eclipse.osee.ote.core.testPoint.Operation;
import org.eclipse.ote.simple.test.environment.outfile.xml.TestPointResults;
import org.eclipse.ote.simple.test.environment.outfile.xml.TimeSummary;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
/**
* @author Andy Jury
*/
public class ScriptJsonOutLogHandler extends Handler {
private Map<String, Object> minimum = new HashMap<String, Object>();
private final ObjectMapper mapper = new ObjectMapper();
private File outfile;
private ZipOutputStream zip;
private String distrStatement;
public ScriptJsonOutLogHandler(final File outFile, final String distributionStatement) {
super();
outfile = outFile;
distrStatement = distributionStatement;
}
public ScriptJsonOutLogHandler(File outFile) {
this(outFile, "DISTRO_STATEMENT_HERE");
}
@Override
public synchronized void publish(final LogRecord logRecord) {
if (isLoggable(logRecord)) {
try {
publisihMinimum(logRecord);
} catch (Exception ex) {
logError(ex);
}
}
}
private void publisihMinimum(LogRecord logRecord) {
try {
minimum.put("machineName", InetAddress.getLocalHost().getHostName());
} catch (UnknownHostException ex) {
logError(ex, "Unable to determine machine name");
}
if (logRecord instanceof ScriptResultRecord) {
ScriptResultRecord srr = (ScriptResultRecord) logRecord;
minimum.put("ScriptName", logRecord.getMessage());
for (XmlizableStream rec : srr.getResults()) {
if (rec instanceof TimeSummary) {
TimeSummary ts = (TimeSummary) rec;
minimum.put("elapsedTime", ts.getElapsedTime());
minimum.put("startTime", ts.getStartTime());
minimum.put("endTime", ts.getEndTime());
} else if (rec instanceof TestPointResults) {
Map<String, Object> results = new HashMap<String, Object>();
results.put("passes", ((TestPointResults) rec).getPasses());
results.put("fails", ((TestPointResults) rec).getFails());
results.put("aborted", ((TestPointResults) rec).isAborted());
results.put("total", ((TestPointResults) rec).getTotal());
minimum.put("results", results);
}
}
} else if (logRecord instanceof TestPointRecord) {
@SuppressWarnings("unchecked")
List<Object> testPoints = (List<Object>) minimum.get("testPoints");
if (testPoints == null) {
testPoints = new ArrayList<Object>();
minimum.put("testPoints", testPoints);
}
ITestPoint testPoint = ((TestPointRecord) logRecord).getTestPoint();
int number = ((TestPointRecord) logRecord).getNumber();
boolean overall = testPoint.isPass();
handleTestPoint(testPoint, testPoints, number, "", overall, String.valueOf(number));
}
}
private void handleTestPoint(ITestPoint testPoint, List<Object> testPoints, int number, String groupName, boolean overallPass, String levelNum) {
if (testPoint instanceof CheckPoint) {
Map<String, Object> point = convertCheckPoint((CheckPoint) testPoint, number, groupName, overallPass, levelNum);
testPoints.add(point);
} else if (testPoint instanceof CheckGroup) {
CheckGroup group = (CheckGroup) testPoint;
ArrayList<ITestPoint> groupPoints = group.getTestPoints();
Operation op = group.getOperation();
String curGroupName = group.getGroupName() + " [" + op.getName() + "]";
for (int i = 0; i < groupPoints.size(); i++) {
ITestPoint tp = groupPoints.get(i);
handleTestPoint(tp, testPoints, number, curGroupName, overallPass, levelNum + "." + (i + 1));
}
}
}
private Map<String, Object> convertCheckPoint(CheckPoint checkPoint, int number, String groupName, boolean overallPass, String levelNum) {
Map<String, Object> tpMap = new HashMap<String, Object>();
tpMap.put("name", checkPoint.getTestPointName());
tpMap.put("expected", checkPoint.getExpected());
tpMap.put("actual", checkPoint.getActual());
tpMap.put("pass", checkPoint.isPass());
tpMap.put("number", number);
tpMap.put("overall", overallPass);
if (!groupName.isEmpty()) {
tpMap.put("groupName", groupName);
}
tpMap.put("tpLevel", levelNum);
return tpMap;
}
private boolean prepareToFlush() {
setupJson();
return setupOutputFile();
}
private void setupJson() {
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure(MapperFeature.AUTO_DETECT_FIELDS, false);
mapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
mapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false);
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.registerModule(new LogRecordModule());
TypeResolverBuilder<?> typeResolver = new TmoTypeResolverBuilder();
typeResolver.init(JsonTypeInfo.Id.CLASS, null);
typeResolver.inclusion(JsonTypeInfo.As.PROPERTY);
typeResolver.typeProperty("@CLASS");
mapper.setDefaultTyping(typeResolver);
}
private boolean setupOutputFile() {
boolean result = true;
String path;
try {
path = outfile.getCanonicalPath();
path = path.substring(0, path.length() - 1) + 'z';
File file = new File(path);
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
zip = new ZipOutputStream(bos);
} catch (FileNotFoundException ex) {
logError(ex, "Zip file creation failed");
result = false;
}
} catch (IOException ex) {
logError(ex, "Failed to get canaonical path from outFile");
result = false;
}
return result;
}
public synchronized void flushRecords() {
if (prepareToFlush()) {
writeZipEntry("Minimum", minimum);
writeZipEntry("DistributionStatement", distrStatement);
}
}
private void writeZipEntry(final String basename, final Object object) {
try {
byte[] buffer = new byte[1024];
File temp = File.createTempFile(basename, "json");
mapper.writeValue(temp, object);
FileInputStream input = new FileInputStream(temp);
ZipEntry entry = new ZipEntry(basename + ".json");
zip.putNextEntry(entry);
int len;
while ((len = input.read(buffer)) > 0) {
zip.write(buffer, 0, len);
}
input.close();
temp.delete();
} catch (JsonGenerationException ex) {
logError(ex);
} catch (JsonMappingException ex) {
logError(ex);
} catch (IOException ex) {
logError(ex);
}
}
@Override
public void close() throws SecurityException {
try {
zip.close();
} catch (Exception ex) {
logError(ex);
}
}
@Override
public void flush() {
// don't call this method
}
private void logError(final Exception ex) {
logError(ex);
}
private void logError(final Exception ex, final String message) {
if (message != null && message.trim().length() > 0) {
System.err.println(message);
}
if (ex != null) {
ex.printStackTrace();
} else {
Throwable throwable = new Throwable();
throwable.printStackTrace();
}
}
}