diff src/main/gov/nasa/jpf/report/ConsolePublisher.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children 6774e2e08d37
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/gov/nasa/jpf/report/ConsolePublisher.java	Fri Jan 23 10:14:01 2015 -0800
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2014, United States Government, as represented by the
+ * Administrator of the National Aeronautics and Space Administration.
+ * All rights reserved.
+ *
+ * The Java Pathfinder core (jpf-core) platform is 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 gov.nasa.jpf.report;
+
+import gov.nasa.jpf.Config;
+import gov.nasa.jpf.Error;
+import gov.nasa.jpf.util.Left;
+import gov.nasa.jpf.vm.ClassInfo;
+import gov.nasa.jpf.vm.ClassLoaderInfo;
+import gov.nasa.jpf.vm.Instruction;
+import gov.nasa.jpf.vm.VM;
+import gov.nasa.jpf.vm.MethodInfo;
+import gov.nasa.jpf.vm.Path;
+import gov.nasa.jpf.vm.Step;
+import gov.nasa.jpf.vm.Transition;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+public class ConsolePublisher extends Publisher {
+
+  // output destinations
+  String fileName;
+  FileOutputStream fos;
+
+  String port;
+
+  // the various degrees of information for program traces
+  protected boolean showCG;
+  protected boolean showSteps;
+  protected boolean showLocation;
+  protected boolean showSource;
+  protected boolean showMethod;
+  protected boolean showCode;
+
+  public ConsolePublisher(Config conf, Reporter reporter) {
+    super(conf, reporter);
+
+    // options controlling the output destination
+    fileName = conf.getString("report.console.file");
+    port = conf.getString("report.console.port");
+
+    // options controlling what info should be included in a trace
+    showCG = conf.getBoolean("report.console.show_cg", true);
+    showSteps = conf.getBoolean("report.console.show_steps", true);
+    showLocation = conf.getBoolean("report.console.show_location", true);
+    showSource = conf.getBoolean("report.console.show_source", true);
+    showMethod = conf.getBoolean("report.console.show_method", false);
+    showCode = conf.getBoolean("report.console.show_code", false);
+  }
+
+  @Override
+  public String getName() {
+    return "console";
+  }
+
+  @Override
+  protected void openChannel(){
+
+    if (fileName != null) {
+      try {
+        fos = new FileOutputStream(fileName);
+        out = new PrintWriter( fos);
+      } catch (FileNotFoundException x) {
+        // fall back to System.out
+      }
+    } else if (port != null) {
+      // <2do>
+    }
+
+    if (out == null){
+      out = new PrintWriter(System.out, true);
+    }
+  }
+
+  @Override
+  protected void closeChannel() {
+    if (fos != null){
+      out.close();
+    }
+  }
+
+  @Override
+  public void publishTopicStart (String topic) {
+    out.println();
+    out.print("====================================================== ");
+    out.println(topic);
+  }
+
+  @Override
+  public void publishTopicEnd (String topic) {
+    // nothing here
+  }
+
+  @Override
+  public void publishStart() {
+    super.publishStart();
+
+    if (startItems.length > 0){ // only report if we have output for this phase
+      publishTopicStart("search started: " + formatDTG(reporter.getStartDate()));
+    }
+  }
+
+  @Override
+  public void publishFinished() {
+    super.publishFinished();
+
+    if (finishedItems.length > 0){ // only report if we have output for this phase
+      publishTopicStart("search finished: " + formatDTG(reporter.getFinishedDate()));
+    }
+  }
+
+  @Override
+  protected void publishJPF() {
+    out.println(reporter.getJPFBanner());
+    out.println();
+  }
+
+  @Override
+  protected void publishDTG() {
+    out.println("started: " + reporter.getStartDate());
+  }
+
+  @Override
+  protected void publishUser() {
+    out.println("user: " + reporter.getUser());
+  }
+
+  @Override
+  protected void publishJPFConfig() {
+    publishTopicStart("JPF configuration");
+
+    TreeMap<Object,Object> map = conf.asOrderedMap();
+    Set<Map.Entry<Object,Object>> eSet = map.entrySet();
+
+    for (Object src : conf.getSources()){
+      out.print("property source: ");
+      out.println(conf.getSourceName(src));
+    }    
+    
+    out.println("properties:");
+    for (Map.Entry<Object,Object> e : eSet) {
+      out.println("  " + e.getKey() + "=" + e.getValue());
+    }
+  }
+
+  @Override
+  protected void publishPlatform() {
+    publishTopicStart("platform");
+    out.println("hostname: " + reporter.getHostName());
+    out.println("arch: " + reporter.getArch());
+    out.println("os: " + reporter.getOS());
+    out.println("java: " + reporter.getJava());
+  }
+
+
+  @Override
+  protected void publishSuT() {
+    publishTopicStart("system under test");
+    out.println( reporter.getSuT());
+  }
+
+  @Override
+  protected void publishError() {
+    Error e = reporter.getCurrentError();
+
+    publishTopicStart("error " + e.getId());
+    out.println(e.getDescription());
+
+    String s = e.getDetails();
+    if (s != null) {
+      out.println(s);
+    }
+
+  }
+
+  @Override
+  protected void publishConstraint() {
+    String constraint = reporter.getLastSearchConstraint();
+    publishTopicStart("search constraint");
+    out.println(constraint);  // not much info here yet
+  }
+
+  @Override
+  protected void publishResult() {
+    List<Error> errors = reporter.getErrors();
+
+    publishTopicStart("results");
+
+    if (errors.isEmpty()) {
+      out.println("no errors detected");
+    } else {
+      for (Error e : errors) {
+        out.print("error #");
+        out.print(e.getId());
+        out.print(": ");
+        out.print(e.getDescription());
+
+        String s = e.getDetails();
+        if (s != null) {
+          s = s.replace('\n', ' ');
+          s = s.replace('\t', ' ');
+          s = s.replace('\r', ' ');
+          out.print(" \"");
+          if (s.length() > 50){
+            out.print(s.substring(0,50));
+            out.print("...");
+          } else {
+            out.print(s);
+          }
+          out.print('"');
+        }
+
+        out.println();
+      }
+    }
+  }
+
+  /**
+   * this is done as part of the property violation reporting, i.e.
+   * we have an error
+   */
+  @Override
+  protected void publishTrace() {
+    Path path = reporter.getPath();
+    int i=0;
+
+    if (path.size() == 0) {
+      return; // nothing to publish
+    }
+
+    publishTopicStart("trace " + reporter.getCurrentErrorId());
+
+    for (Transition t : path) {
+      out.print("------------------------------------------------------ ");
+      out.println("transition #" + i++ + " thread: " + t.getThreadIndex());
+
+      if (showCG){
+        out.println(t.getChoiceGenerator());
+      }
+
+      if (showSteps) {
+        String lastLine = null;
+        MethodInfo lastMi = null;
+        int nNoSrc=0;
+
+        for (Step s : t) {
+          if (showSource) {
+            String line = s.getLineString();
+            if (line != null) {
+              if (!line.equals(lastLine)) {
+                if (nNoSrc > 0){
+                  out.println("      [" + nNoSrc + " insn w/o sources]");
+                }
+
+                out.print("  ");
+                if (showLocation) {
+                  out.print(Left.format(s.getLocationString(),30));
+                  out.print(" : ");
+                }
+                out.println(line.trim());
+                nNoSrc = 0;
+
+              }
+            } else { // no source
+              nNoSrc++;
+            }
+            
+            lastLine = line;
+          }
+
+          if (showCode) {
+            Instruction insn = s.getInstruction();
+            if (showMethod){
+              MethodInfo mi = insn.getMethodInfo();
+              if (mi != lastMi) {
+                ClassInfo mci = mi.getClassInfo();
+                out.print("    ");
+                if (mci != null) {
+                  out.print(mci.getName());
+                  out.print(".");
+                }
+                out.println(mi.getUniqueName());
+                lastMi = mi;
+              }
+            }
+            out.print("      ");
+            out.println(insn);
+          }
+        }
+
+        if (showSource && !showCode && (nNoSrc > 0)) {
+          out.println("      [" + nNoSrc + " insn w/o sources]");
+        }
+      }
+    }
+  }
+
+  @Override
+  protected void publishOutput() {
+    Path path = reporter.getPath();
+
+    if (path.size() == 0) {
+      return; // nothing to publish
+    }
+
+    publishTopicStart("output " + reporter.getCurrentErrorId());
+
+    if (path.hasOutput()) {
+      for (Transition t : path) {
+        String s = t.getOutput();
+        if (s != null){
+          out.print(s);
+        }
+      }
+    } else {
+      out.println("no output");
+    }
+  }
+
+  @Override
+  protected void publishSnapshot() {
+    VM vm = reporter.getVM();
+
+    // not so nice - we have to delegate this since it's using a lot of internals, and is also
+    // used in debugging
+    publishTopicStart("snapshot " + reporter.getCurrentErrorId());
+
+    if (vm.getPathLength() > 0) {
+      vm.printLiveThreadStatus(out);
+    } else {
+      out.println("initial program state");
+    }
+  }
+
+  public static final String STATISTICS_TOPIC = "statistics";
+  
+  // this is useful if somebody wants to monitor progress from a specialized ConsolePublisher
+  public synchronized void printStatistics (PrintWriter pw){
+    publishTopicStart( STATISTICS_TOPIC);
+    printStatistics( pw, reporter);
+  }
+  
+  // this can be used outside a publisher, to show the same info
+  public static void printStatistics (PrintWriter pw, Reporter reporter){
+    Statistics stat = reporter.getStatistics();
+    
+    pw.println("elapsed time:       " + formatHMS(reporter.getElapsedTime()));
+    pw.println("states:             new=" + stat.newStates + ",visited=" + stat.visitedStates
+            + ",backtracked=" + stat.backtracked + ",end=" + stat.endStates);
+    pw.println("search:             maxDepth=" + stat.maxDepth + ",constraints=" + stat.constraints);
+    pw.println("choice generators:  thread=" + stat.threadCGs
+            + " (signal=" + stat.signalCGs + ",lock=" + stat.monitorCGs + ",sharedRef=" + stat.sharedAccessCGs
+            + ",threadApi=" + stat.threadApiCGs + ",reschedule=" + stat.breakTransitionCGs
+            + "), data=" + stat.dataCGs);
+    pw.println("heap:               " + "new=" + stat.nNewObjects
+            + ",released=" + stat.nReleasedObjects
+            + ",maxLive=" + stat.maxLiveObjects
+            + ",gcCycles=" + stat.gcCycles);
+    pw.println("instructions:       " + stat.insns);
+    pw.println("max memory:         " + (stat.maxUsed >> 20) + "MB");
+
+    pw.println("loaded code:        classes=" + ClassLoaderInfo.getNumberOfLoadedClasses() + ",methods="
+            + MethodInfo.getNumberOfLoadedMethods());
+  }
+  
+  @Override
+  public void publishStatistics() {
+    printStatistics(out);
+  }
+
+}