package sandbox; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; /* This class contains three parts: * * -The WrapperT2 object which will instantiate a T2 process * -A public main which is the T2 process * -A few private static common fields * */ public class WrapperT2 { // ======================================= // ======== Common fields ======== // ======================================= private static final String PREFIX = "...[PREFIX]..."; private static final int PREFIX_length = PREFIX.length(); private static final String PREFIX_READY = PREFIX+"...[READY]..."; private static final String CLOSE = "...[CLOSE]..."; //Returns a short description of the likely cause, or null if none can be identified public static String commonCause(final String t2result){ if(t2result.contains("The set of constructor-IPs is empty")) return " No Constructors==="; if(t2result.contains("[t2proc] No error or violation thrown")) return " No errors or violation==="; for(String x : new String[]{ "java.security" ,"CUT constructor failure" ,"Fail to create object via constructor" }){ final int pos = t2result.indexOf(x); if(-1!=pos) return t2result.substring(pos,Math.min(pos+1000, t2result.length())) +"\n=================="; } return null;//"NOT A COMMON CASE==="; } // ======================================= // ======== WrapperT2 Object ======== // ======================================= private final Process proc; private final BufferedReader fromT2; private final PrintWriter toT2; private PrintStream out; private boolean captureAll; public WrapperT2(final String classpath, File working_directory) throws IOException{ ProcessBuilder pb = new ProcessBuilder("java", "-ea", "-Djava.security.manager", "-Djava.security.policy==t2policy", "-cp", classpath+":"+System.getProperty("java.class.path"), this.getClass().getName()); // for(String s : pb.command()) // System.out.print(s+" "); // System.out.println(); pb.redirectErrorStream(true); pb.directory(working_directory); proc = pb.start(); fromT2 = new BufferedReader(new InputStreamReader(proc.getInputStream())); toT2 = new PrintWriter(proc.getOutputStream(), true); out = System.out; } public void redirectOutput(PrintStream out){ this.out = out; } public int close(){ toT2.println(CLOSE); toT2.flush(); final String result = getResult().intern(); if(!result.equals(PREFIX_READY+CLOSE)) throw new Error("T2proc unexpectedly returned: "+result); try { return proc.waitFor(); } catch (InterruptedException e) { throw new Error("InterruptedException while trying to close.",e); } } public void test(final String line){ if(line.equals(CLOSE)){ throw new IllegalArgumentException("Can't test the protocol message'"+CLOSE+"'"); } toT2.println(line); toT2.flush(); final String result = getResult().intern(); if(!result.equals(PREFIX_READY)) throw new Error("T2proc unexpectedly returned: "+result); } public ByteArrayOutputStream testComplete(final String line){ PrintStream old = out; ByteArrayOutputStream captured_output = new ByteArrayOutputStream(); out = new PrintStream(captured_output); try{ test(line); } catch(Error e){ out.flush(); System.out.println(captured_output.toByteArray()); throw e; } out.close(); out = old; return captured_output; } private String getResult(){ captureAll = false; try { while(true){ final String line = fromT2.readLine(); if(line==null){ throw new Error("UNEXPECTED ERROR: T2proc EndOfLine reached"); } if(isReady(line)){ return line; } } } catch (IOException e) { throw new Error("UNEXPECTED IOERROR when reading from T2proc.", e); } } private boolean isReady(final String line){ if(line.startsWith(PREFIX)){ if(line.startsWith(PREFIX_READY)){ return true; } out.println(line.substring(PREFIX_length)); } else { if(!captureAll && line.contains("BEGIN TEST SET")){ captureAll = true; } if(captureAll || line.contains("##"))//(Pattern.matches(".*[#].*", line)) { out.print(">\t"); out.println(line); } else{ out.print(".\t"); out.println(line); } } return false; } // ======================================= // ======== The T2 process ======== // ======================================= public static void main(String[] args){ t2procOut("Hello"); System.out.flush(); BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); t2process_loop(input); try { input.close(); } catch (IOException e) { e.printStackTrace(System.out); t2procOut("ERROR: could not close input:"); t2procOut(e.toString()); t2procOut(e.getMessage()); } System.out.print(PREFIX_READY); System.out.println(CLOSE); System.out.flush(); } public static void t2process_loop(BufferedReader in) { int waited_ms = 0; while(waited_ms<10000) { String line; try { if(!in.ready()){ waited_ms +=10; try { Thread.sleep(10); } catch (InterruptedException e) {} continue; } waited_ms=0; line = in.readLine(); if(CLOSE.equals(line)){ t2procOut("Close command received"); return; } } catch (IOException e) { e.printStackTrace(System.out); t2procOut("ERROR: IOException when reading input!!!"); return; } if(line==null){ t2procOut("ERROR: Input EOL reached!"); return; } //line is a classname. t2procOut("testing "+line); invokeT2(line); System.out.println(PREFIX_READY); System.out.flush(); } t2procOut("Waiting "+waited_ms+"ms for input..."); } private static void invokeT2(final String classname){ try { Sequenic.T2.Main.Junit(classname); t2procOut("No error or violation thrown"); } catch (Throwable e) { t2procOut("Exception: "+e.toString()); e.printStackTrace(); } File tr = new File(classname+".tr"); if(tr.exists()){ if(tr.delete()) t2procOut(classname +".tr deleted"); else t2procOut(classname +".tr exists, but could not be deleted"); } } //Note that the used System.out is the callers System.out //If a WrapperT2 were to call this, it's system out would be used! private static void t2procOut(String message){ String flag = "[t2proc] "; for(String s : message.split("\r\n|\r|\n")){ System.out.print(PREFIX); System.out.print(flag); System.out.println(s); flag = "...[cont.] "; } } }