Skip to content

Commit

Permalink
Update Visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
DaGeRe committed Aug 27, 2019
1 parent f046c19 commit b92e892
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 151 deletions.
150 changes: 36 additions & 114 deletions analysis/src/main/java/de/peass/visualization/GenerateRCAHTML.java
Original file line number Diff line number Diff line change
@@ -1,144 +1,66 @@
package de.peass.visualization;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import de.peass.measurement.searchcause.data.CauseSearchData;
import de.peass.measurement.searchcause.data.MeasuredNode;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

public class GenerateRCAHTML {
@Command(description = "Visualizes the root-cause-analysis-tree as HTML page", name = "visualizerca")
public class GenerateRCAHTML implements Callable<Void> {

private static final Logger LOG = LogManager.getLogger(GenerateRCAHTML.class);

private static final ObjectMapper MAPPER = new ObjectMapper();

public static void main(final String[] args) throws JsonParseException, JsonMappingException, IOException {
static {
MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
final File source = new File(args[0]);
if (source.isDirectory()) {
for (final File file : source.listFiles()) {
createVisualization(file);
}
} else {
createVisualization(source);
}
}

private static void createVisualization(final File source) throws IOException, JsonParseException, JsonMappingException, JsonProcessingException, FileNotFoundException {
final CauseSearchData data = MAPPER.readValue(source, CauseSearchData.class);

final MeasuredNode parent = data.getNodes();
final String longestPrefix = getLongestPrefix(parent);
setPrefix(parent, longestPrefix);
LOG.info("Prefix: {}", longestPrefix);

final MeasuredNode measured = data.getNodes();
final Node root = new Node();
System.out.println(measured.getCall());
root.setName(measured.getCall());
setNodeColor(measured, root);

processNode(measured, root);

writeHTML(MAPPER, root, data);
}

private static void setPrefix(final MeasuredNode parent, final String longestPrefix) {
parent.setCall(parent.getCall().substring(longestPrefix.length()));
for (final MeasuredNode node : parent.getChilds()) {
setPrefix(node, longestPrefix);
}
}

private static String getLongestPrefix(final MeasuredNode parent) {
String longestPrefix = parent.getCall();
for (final MeasuredNode node : parent.getChilds()) {
final String clazz = node.getCall().substring(0, node.getCall().lastIndexOf('.') + 1);
longestPrefix = StringUtils.getCommonPrefix(longestPrefix, getLongestPrefix(node), clazz);
}
return longestPrefix;
}

private static void writeHTML(final ObjectMapper MAPPER, final Node root, final CauseSearchData data) throws IOException, JsonProcessingException, FileNotFoundException {
final File output = new File(data.getTestcase() + ".html");
final BufferedWriter fileWriter = new BufferedWriter(new FileWriter(output));

fileWriter.write("<!DOCTYPE html>\n" +
"<script>\n" +
"var treeData = [\n");
fileWriter.write(MAPPER.writeValueAsString(root));
fileWriter.write("];\n");

int nodeHeight = 0;
for (final Node child : root.getChildren()) {
nodeHeight += child.getChildren().size();
}
final int nodeDepth = getDepth(root);

final int width = 400 * nodeDepth;
final int height = 100 * nodeHeight;
final int left = 10 * root.getName().length();
fileWriter.write("// ************** Generate the tree diagram *****************\n" +
"var margin = {top: 20, right: 120, bottom: 20, left: "+left+"},\n" +
" width = " + width + "- margin.right - margin.left,\n" +
" height = 300 - margin.top - margin.bottom;");
fileWriter.write("</script>\n");
LOG.info("Width: {} Height: {} Left: {}", width, height, left);
final InputStream htmlStream = GenerateRCAHTML.class.getClassLoader().getResourceAsStream("visualization/RestOfHTML.html");
final BufferedReader reader = new BufferedReader(new InputStreamReader(htmlStream));

String line;
while ((line = reader.readLine()) != null) {
fileWriter.write(line + "\n");
}
fileWriter.flush();
fileWriter.close();
}
@Option(names = { "-data", "--data" }, description = "Path to datafolder")
protected File data[];

private File resultFolder = new File("results");

private static int getDepth(final Node root) {
int depth = 0;
for (final Node child : root.getChildren()) {
depth = Math.max(depth, getDepth(child)) + 1;
}
return depth;
}
public static void main(final String[] args) throws JsonParseException, JsonMappingException, IOException {
final CommandLine commandLine = new CommandLine(new GenerateRCAHTML());
commandLine.execute(args);

private static void processNode(final MeasuredNode measuredParent, final Node parent) {
for (final MeasuredNode measuredChild : measuredParent.getChilds()) {
final Node newChild = new Node();
newChild.setName(measuredChild.getCall());
newChild.setParent(measuredParent.getCall());
setNodeColor(measuredChild, newChild);
parent.getChildren().add(newChild);
processNode(measuredChild, newChild);
}
}

private static void setNodeColor(final MeasuredNode measuredNode, final Node graphNode) {
if (measuredNode.getStatistic().isChange()) {
if (measuredNode.getStatistic().getTvalue() < 0) {
graphNode.setColor("#FF0000");
@Override
public Void call() throws Exception {
for (final File source : data) {
if (source.isDirectory()) {
if (source.getName().endsWith("_peass")) {
final File rcaFolder = new File(source, "rootCauseAnalysisTree");
for (final File versionFolder : rcaFolder.listFiles()) {
for (final File testcaseFlder : versionFolder.listFiles()) {
for (final File treeFile : testcaseFlder.listFiles()) {
new RCAGenerator(treeFile, resultFolder).createVisualization();
}
}
}
} else {
for (final File treeFile : source.listFiles()) {
new RCAGenerator(treeFile, resultFolder).createVisualization();
}
}
} else {
graphNode.setColor("#00FF00");
new RCAGenerator(source, resultFolder).createVisualization();
}
} else {
graphNode.setColor("#FFFFFF");
}
return null;
}


}
138 changes: 138 additions & 0 deletions analysis/src/main/java/de/peass/visualization/RCAGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package de.peass.visualization;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;

import de.peass.measurement.searchcause.data.CauseSearchData;
import de.peass.measurement.searchcause.data.MeasuredNode;
import de.peass.utils.Constants;

public class RCAGenerator {

private static final Logger LOG = LogManager.getLogger(RCAGenerator.class);

private final File source, destFolder;


public RCAGenerator(final File source, final File destFolder) {
super();
this.source = source;
this.destFolder = destFolder;
}

public void createVisualization() throws IOException, JsonParseException, JsonMappingException, JsonProcessingException, FileNotFoundException {
final CauseSearchData data = Constants.OBJECTMAPPER.readValue(source, CauseSearchData.class);

final MeasuredNode parent = data.getNodes();
final String longestPrefix = getLongestPrefix(parent);
setPrefix(parent, longestPrefix);
LOG.info("Prefix: {}", longestPrefix);

final MeasuredNode measured = data.getNodes();
final Node root = new Node();
System.out.println(measured.getCall());
root.setName(measured.getCall());
setNodeColor(measured, root);

processNode(measured, root);

writeHTML(root, data);
}

private void setPrefix(final MeasuredNode parent, final String longestPrefix) {
parent.setCall(parent.getCall().substring(longestPrefix.length()));
for (final MeasuredNode node : parent.getChilds()) {
setPrefix(node, longestPrefix);
}
}

private String getLongestPrefix(final MeasuredNode parent) {
String longestPrefix = parent.getCall();
for (final MeasuredNode node : parent.getChilds()) {
final String clazz = node.getCall().substring(0, node.getCall().lastIndexOf('.') + 1);
longestPrefix = StringUtils.getCommonPrefix(longestPrefix, getLongestPrefix(node), clazz);
}
return longestPrefix;
}

private void writeHTML(final Node root, final CauseSearchData data) throws IOException, JsonProcessingException, FileNotFoundException {
final File output = new File(destFolder, data.getTestcase() + ".html");
final BufferedWriter fileWriter = new BufferedWriter(new FileWriter(output));

fileWriter.write("<!DOCTYPE html>\n" +
"<script>\n" +
"var treeData = [\n");
fileWriter.write(Constants.OBJECTMAPPER.writeValueAsString(root));
fileWriter.write("];\n");

int nodeHeight = 0;
for (final Node child : root.getChildren()) {
nodeHeight += child.getChildren().size();
}
final int nodeDepth = getDepth(root);

final int width = 400 * nodeDepth;
final int height = 100 * nodeHeight;
final int left = 10 * root.getName().length();
fileWriter.write("// ************** Generate the tree diagram *****************\n" +
"var margin = {top: 20, right: 120, bottom: 20, left: " + left + "},\n" +
" width = " + width + "- margin.right - margin.left,\n" +
" height = 300 - margin.top - margin.bottom;");
fileWriter.write("</script>\n");
LOG.info("Width: {} Height: {} Left: {}", width, height, left);
final InputStream htmlStream = GenerateRCAHTML.class.getClassLoader().getResourceAsStream("visualization/RestOfHTML.html");
final BufferedReader reader = new BufferedReader(new InputStreamReader(htmlStream));

String line;
while ((line = reader.readLine()) != null) {
fileWriter.write(line + "\n");
}
fileWriter.flush();
fileWriter.close();
}

private int getDepth(final Node root) {
int depth = 0;
for (final Node child : root.getChildren()) {
depth = Math.max(depth, getDepth(child)) + 1;
}
return depth;
}

private void processNode(final MeasuredNode measuredParent, final Node parent) {
for (final MeasuredNode measuredChild : measuredParent.getChilds()) {
final Node newChild = new Node();
newChild.setName(measuredChild.getCall());
newChild.setParent(measuredParent.getCall());
setNodeColor(measuredChild, newChild);
parent.getChildren().add(newChild);
processNode(measuredChild, newChild);
}
}

private void setNodeColor(final MeasuredNode measuredNode, final Node graphNode) {
if (measuredNode.getStatistic().isChange()) {
if (measuredNode.getStatistic().getTvalue() < 0) {
graphNode.setColor("#FF0000");
} else {
graphNode.setColor("#00FF00");
}
} else {
graphNode.setColor("#FFFFFF");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@
public class CauseSearchFolders extends PeASSFolders{

private final File causeSearchmeasurementsFolder;
private final File rcaFolder;

public CauseSearchFolders(final File folder) {
super(folder);
causeSearchmeasurementsFolder = new File(fullResultFolder, "causeSearchMeasurements");
causeSearchmeasurementsFolder.mkdir();
rcaFolder = new File(peassFolder, "rootCauseAnalysisTree");
rcaFolder.mkdir();
}

@Override
public File getDetailResultFolder() {
return causeSearchmeasurementsFolder;
}

public File getRcaFolder() {
return rcaFolder;
}

}
11 changes: 9 additions & 2 deletions distribution/src/main/java/de/peass/PeASSMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
import java.util.concurrent.Callable;

import de.peass.clean.TestCleaner;
import de.peass.visualization.GenerateRCAHTML;
import picocli.CommandLine;
import picocli.CommandLine.Command;

@Command(name = "peass", mixinStandardHelpOptions = true, subcommands = { DependencyExecutionReader.class, AdaptiveTestStarter.class,
GetChanges.class, ReadProperties.class, TestCleaner.class, IsChange.class, SearchChangeCause.class }, synopsisSubcommandLabel = "COMMAND")
@Command(name = "peass", mixinStandardHelpOptions = true, subcommands = { DependencyExecutionReader.class,
AdaptiveTestStarter.class,
GetChanges.class,
ReadProperties.class,
TestCleaner.class,
IsChange.class,
SearchChangeCause.class,
GenerateRCAHTML.class }, synopsisSubcommandLabel = "COMMAND")
public class PeASSMain implements Callable<Void> {
public static void main(final String[] args) {
final CommandLine line = new CommandLine(new PeASSMain());
Expand Down
5 changes: 5 additions & 0 deletions measurement/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>1.3.1</version>
</dependency>

<dependency>
<groupId>de.peass</groupId>
Expand Down
4 changes: 2 additions & 2 deletions measurement/src/main/java/de/peass/SearchChangeCause.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import javax.xml.bind.JAXBException;

import de.dagere.kopeme.datacollection.DataCollectorList;
import de.peass.dependency.PeASSFolders;
import de.peass.dependency.CauseSearchFolders;
import de.peass.dependency.analysis.data.TestCase;
import de.peass.measurement.MeasurementConfiguration;
import de.peass.measurement.searchcause.CauseSearcher;
Expand Down Expand Up @@ -45,7 +45,7 @@ public Void call() throws Exception {
final CauseSearcherConfig causeSearcherConfig = new CauseSearcherConfig(version, predecessor, test);
final BothTreeReader reader = new BothTreeReader(causeSearcherConfig, measurementConfiguration, folders);
final boolean complete = false;
final PeASSFolders alternateFolders = new PeASSFolders(folders.getProjectFolder());
final CauseSearchFolders alternateFolders = new CauseSearchFolders(folders.getProjectFolder());
if (complete) {
final LevelMeasurer measurer = new LevelMeasurer(alternateFolders, causeSearcherConfig, testtransformer, measurementConfiguration);
final CauseSearcher tester = new CauseSearcherComplete(reader, causeSearcherConfig, measurer, measurementConfiguration, alternateFolders);
Expand Down
Loading

0 comments on commit b92e892

Please sign in to comment.