/** * This function performs an individual formatting test after the input and output streams have * been created. * * @param commands the input that decides which tests to perform * @return a String holding the error messages for any failed tests or null if no tests are * failed. */ private static /*@Nullable*/ String performTest(LineNumberReader commands) { StringBuffer output = new StringBuffer(); // List invariantTestCases = new Vector(); boolean noTestFailed = true; while (true) { // Create a new test case // FormatTestCase currentCase = FormatTestCase.instantiate(commands, generateGoals); // if (currentCase == null) // break; // else { // invariantTestCases.add(currentCase); String results = AddAndCheckTestCase.runTest(commands); if (results == null) break; if (!(results.length() == 0)) { // output.print(currentCase.getDiffString()); output.append(results); noTestFailed = false; } } if (noTestFailed) { return null; } else { return output.toString(); } }
private static String generateCommands(LineNumberReader input) { StringBuffer output = new StringBuffer(); while (true) { String commands = AddAndCheckTestCase.generateTest(input); if (commands == null) break; output.append(commands); } return output.toString(); }
/** Writes the body of the valid method to fileText. */ private void writeValidBody() { if (vars.length > 0) { fileText.append(" return (" + vars[0].getFieldName() + " != null)"); for (int i = 1; i < vars.length; i++) { fileText.append(" && (" + vars[0].getFieldName() + " != null)"); } add(";"); } else { add(" /* no variables were found */"); add(" return false;"); } }
/** Given a line from an input file, generates appropriate check or add command. */ private static void generateCheckOrAddCommand(String command, int lineNumber) { // remove the command String args = command.substring(command.indexOf(":") + 1); StringTokenizer tokens = new StringTokenizer(args, argDivider); if (tokens.countTokens() != types.length) { throw new RuntimeException( "Number of arguments to generate an add command on line: " + lineNumber + " is: " + tokens.countTokens() + " but should be: " + types.length); } Object[] params = getParams(tokens); assert !tokens.hasMoreTokens(); InvariantStatus goalStatus = null; if (isCheckCommand(command)) { goalStatus = getCheckStatus(params); } else { goalStatus = getAddStatus(params); } String invariantFormat = getInvariantFormat(); results.append( command + argDivider + " " + goalStatus.toString() + argDivider + " " + invariantFormat + lineSep); }
/** * Initializes the fields of this class based on the first two lines of a case which include the * class name and parameter types. * * @return true is end of file is reached. */ private static boolean initFields(LineNumberReader commands, boolean generatingCommands) { results = new StringBuffer(); String className = getNextRealLine(commands); // End of file reached if (className == null) return true; // Load the class from file Class<? extends Invariant> classToTest = asInvClass(getClass(className)); try { classToTest.getField("dkconfig_enabled"); // Enable if needs to be done InvariantAddAndCheckTester.config.apply(className + ".enabled", "true"); } catch (NoSuchFieldException e) { // Otherwise do nothing } if (generatingCommands) { results.append(className + lineSep); } // Instantiate variables to be used as the names in the // invariants, variables are labeled a,b,c and so on as they // appear String typeString = getNextRealLine(commands); types = getTypes(typeString); VarInfo[] vars = getVarInfos(classToTest, types); PptSlice sl = createSlice(vars, daikon.test.Common.makePptTopLevel("Test:::OBJECT", vars)); // Create an actual instance of the class invariantToTest = instantiateClass(classToTest, sl); addModified = getAddModified(invariantToTest.getClass()); checkModified = getCheckModified(invariantToTest.getClass()); outputProducer = getOutputProducer(invariantToTest.getClass()); assert getArity(invariantToTest.getClass()) == types.length; if (generatingCommands) { results.append(typeString + lineSep); } return false; }
static String combineDummy(String inv, String daikonStr, String esc, String simplify) { StringBuffer combined = new StringBuffer(inv); combined.append(lineSep + "\tDAIKON_FORMAT "); combined.append(daikonStr); combined.append(lineSep + "\tESC_FORMAT "); combined.append(esc); combined.append(lineSep + "\tSIMPLIFY_FORMAT "); combined.append(simplify); return combined.toString(); }
private String format_simplify() { if (intersect == null || intersect.length == 0) { return "(AND)"; } String[] name = var().simplifyNameAndBounds(); if (name == null) { return format_unimplemented(OutputFormat.SIMPLIFY); } String idx; if (!name[0].equals("|i|")) { idx = "i"; } else { idx = "j"; } StringBuffer pre_buf = new StringBuffer(""); StringBuffer end_buf = new StringBuffer(""); for (int i = 0; i < intersect.length; i++) { pre_buf.append("(EXISTS (" + idx + i + ") (AND "); pre_buf.append("(>= " + idx + i + " " + name[1] + ") "); pre_buf.append("(<= " + idx + i + " " + name[2] + ") "); // Based on the class name, I originally wrote this method as if // the invariant represented a common subsequence between two // sequences (i.e. where the match was required to be in // order). In case an invariant like that is added in the // future, use the following: // if (i == 0) // pre_buf.append("(>= "+idx+i + " 0) "); // else if (i > 0) // pre_buf.append("(> "+idx+i + " "+idx+(i-1) +") "); // if (i == intersect.length - 1) // pre_buf.append("(< "+idx+i + " (select arrayLength " + name[0] + ")) "); pre_buf.append( "(EQ (select (select elems " + name[0] + ") " + idx + i + ") " + simplify_format_double(intersect[i]) + ")"); if (i == intersect.length - 1) pre_buf.append(" "); end_buf.append("))"); } pre_buf.append(end_buf); return pre_buf.toString(); }
/** * @return a String containing the proper add and check commands for this input lines of this * test case. */ public static String generateTest(LineNumberReader commands) { boolean endOfFile = initFields(commands, true); if (endOfFile) return null; while (true) { String commandLine = getNextLine(commands).trim(); int lineNumber = commands.getLineNumber(); if (InvariantAddAndCheckTester.isComment(commandLine)) { results.append(commandLine + lineSep); } else if (isTestTerminator(commandLine)) { results.append(commandLine + lineSep + lineSep); break; } else if (isAddCommand(commandLine) || isCheckCommand(commandLine)) { generateCheckOrAddCommand(commandLine, lineNumber); } else if (isCompareCommand(commandLine)) { // generateCompareCommand(commandLine); } else { throw new RuntimeException("unrecognized command"); } } return results.toString(); }
/** Writes the body of the instantiateDummy method to fileText. */ private void writeInstantiateDummyBody() { if (vars.length >= 1 && vars.length <= 3) { for (int i = 0; i < vars.length; i++) { add( " VarInfo " + vars[i].getVarName() + " = ppt.find_var_by_name(\"" + vars[i].getNormalName() + "\");"); } fileText.append(" if ("); fileText.append(vars[0].getVarName() + " != null"); for (int i = 1; i < vars.length; i++) { fileText.append(" && " + vars[i].getVarName() + " != null"); } add(") {"); fileText.append(" dummyInv = dummyInvFactory.instantiate(ppt, new VarInfo[] {"); fileText.append(vars[0].getVarName()); for (int i = 1; i < vars.length; i++) { fileText.append(", " + vars[i].getVarName()); } add("});"); add(" }"); } }
/** * @return String containing error messages for any failed cases. In the case that there are no * failed cases, the empty string is returned. In the case where commands is empty (there * are no more test cases and the end of the file has been reached), null is returned. */ public static String runTest(LineNumberReader commands) { boolean endOfFile = initFields(commands, false); if (endOfFile) { return null; } while (true) { String commandLine = getNextRealLine(commands); int lineNumber = commands.getLineNumber(); if (InvariantAddAndCheckTester.isComment(commandLine)) { continue; } else if (isTestTerminator(commandLine)) { break; } else if (isAddCommand(commandLine) || isCheckCommand(commandLine)) { exicuteCheckOrAddCommand(commandLine, lineNumber); } else if (isCompareCommand(commandLine)) { } else { throw new RuntimeException("unrecognized command"); } } return results.toString(); }
/** * Given a line from a command file, generates executes the appropriate check or add command and * checks the results against the goal. If the results and goal do not match, a message is added * to the results string buffer. */ private static void exicuteCheckOrAddCommand(String command, int lineNumber) { // remove the command String args = command.substring(command.indexOf(":") + 1); StringTokenizer tokens = new StringTokenizer(args, argDivider); if (tokens.countTokens() != types.length + 2) { throw new RuntimeException( "Number of arguments to add command on line " + lineNumber + " is: " + tokens.countTokens() + " but should be: " + (types.length + 2)); } Object[] params = getParams(tokens); InvariantStatus goalStatus = parseStatus(tokens.nextToken().trim()); tokens.nextToken(); // executed for side effect assert !tokens.hasMoreTokens(); InvariantStatus resultStatus = null; if (isCheckCommand(command)) { resultStatus = getCheckStatus(params); } else { resultStatus = getAddStatus(params); } if (resultStatus != goalStatus) { results.append( "Error on line " + lineNumber + ":" + lineSep + "Expected InvariantStatus: " + goalStatus + lineSep + "Found InvariantStatus: " + resultStatus + lineSep); } }
public static void extract_consequent(PptMap ppts) { // Retrieve Ppt objects in sorted order. // Use a custom comparator for a specific ordering Comparator<PptTopLevel> comparator = new Ppt.NameComparator(); TreeSet<PptTopLevel> ppts_sorted = new TreeSet<PptTopLevel>(comparator); ppts_sorted.addAll(ppts.asCollection()); for (PptTopLevel ppt : ppts_sorted) { extract_consequent_maybe(ppt, ppts); } PrintWriter pw = new PrintWriter(System.out, true); // All conditions at a program point. A TreeSet to enable // deterministic output. TreeSet<String> allConds = new TreeSet<String>(); for (String pptname : pptname_to_conditions.keySet()) { Map<String, Map<String, HashedConsequent>> cluster_to_conditions = pptname_to_conditions.get(pptname); for (Map.Entry</*@KeyFor("cluster_to_conditions")*/ String, Map<String, HashedConsequent>> entry : cluster_to_conditions.entrySet()) { String predicate = entry.getKey(); Map<String, HashedConsequent> conditions = entry.getValue(); StringBuffer conjunctionJava = new StringBuffer(); StringBuffer conjunctionDaikon = new StringBuffer(); StringBuffer conjunctionESC = new StringBuffer(); StringBuffer conjunctionSimplify = new StringBuffer("(AND "); int count = 0; for (Map.Entry</*@KeyFor("conditions")*/ String, HashedConsequent> entry2 : conditions.entrySet()) { count++; String condIndex = entry2.getKey(); HashedConsequent cond = entry2.getValue(); if (cond.fakeFor != null) { count--; continue; } String javaStr = cond.inv.format_using(OutputFormat.JAVA); String daikonStr = cond.inv.format_using(OutputFormat.DAIKON); String escStr = cond.inv.format_using(OutputFormat.ESCJAVA); String simplifyStr = cond.inv.format_using(OutputFormat.SIMPLIFY); allConds.add(combineDummy(condIndex, "<dummy> " + daikonStr, escStr, simplifyStr)); // allConds.add(condIndex); if (count > 0) { conjunctionJava.append(" && "); conjunctionDaikon.append(" and "); conjunctionESC.append(" && "); conjunctionSimplify.append(" "); } conjunctionJava.append(javaStr); conjunctionDaikon.append(daikonStr); conjunctionESC.append(escStr); conjunctionSimplify.append(simplifyStr); } conjunctionSimplify.append(")"); String conj = conjunctionJava.toString(); // Avoid inserting self-contradictory conditions such as "x == 1 && // x == 2", or conjunctions of only a single condition. if (count < 2 || contradict_inv_pattern.matcher(conj).find() || useless_inv_pattern_1.matcher(conj).find() || useless_inv_pattern_2.matcher(conj).find()) { // System.out.println("Suppressing: " + conj); } else { allConds.add( combineDummy( conjunctionJava.toString(), conjunctionDaikon.toString(), conjunctionESC.toString(), conjunctionSimplify.toString())); } } if (allConds.size() > 0) { pw.println(); pw.println("PPT_NAME " + pptname); for (String s : allConds) { pw.println(s); } } allConds.clear(); } pw.flush(); }
/** Skips a line in fileText by adding a black line to fileText. */ private void skipLine() { fileText.append(lineSep); }
/** * Appends st to fileText and then ends that line with lineSep. * * @param st the string to added to fileText. */ private void add(String st) { fileText.append(st + lineSep); }