hu.bme.mit.sette.tools.jpet.JPetParser.java Source code

Java tutorial

Introduction

Here is the source code for hu.bme.mit.sette.tools.jpet.JPetParser.java

Source

/*
 * SETTE - Symbolic Execution based Test Tool Evaluator
 *
 * SETTE is a tool to help the evaluation and comparison of symbolic execution
 * based test input generator tools.
 *
 * Budapest University of Technology and Economics (BME)
 *
 * Authors: Lajos Cseppent <lajos.cseppento@inf.mit.bme.hu>, Zoltn Micskei
 * <micskeiz@mit.bme.hu>
 *
 * Copyright 2014
 *
 * 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 hu.bme.mit.sette.tools.jpet;

import hu.bme.mit.sette.common.model.runner.ResultType;
import hu.bme.mit.sette.common.model.runner.RunnerProjectUtils;
import hu.bme.mit.sette.common.model.runner.xml.SnippetInputsXml;
import hu.bme.mit.sette.common.model.snippet.Snippet;
import hu.bme.mit.sette.common.model.snippet.SnippetProject;
import hu.bme.mit.sette.common.tasks.RunResultParser;
import hu.bme.mit.sette.common.validator.FileType;
import hu.bme.mit.sette.common.validator.FileValidator;
import hu.bme.mit.sette.tools.jpet.xmlparser.JPetTestCaseXmlParser;
import hu.bme.mit.sette.tools.jpet.xmlparser.JPetTestCasesConverter;

import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.io.FileUtils;

public class JPetParser extends RunResultParser<JPetTool> {
    public JPetParser(SnippetProject snippetProject, File outputDirectory, JPetTool tool) {
        super(snippetProject, outputDirectory, tool);
    }

    private static final Pattern PATTERN_FULL_CODE = Pattern
            .compile("^Full Code Coverage of '.*': (\\d+(.\\d+)?)% \\(.*\\)$");
    private static final Pattern PATTERN_TOP_CODE = Pattern
            .compile("^Top Code Coverage of '.*': (\\d+(.\\d+)?)% \\(.*\\)$");

    @Override
    protected void parseSnippet(Snippet snippet, SnippetInputsXml inputsXml) throws Exception {
        File outputFile = RunnerProjectUtils.getSnippetOutputFile(getRunnerProjectSettings(), snippet);
        File errorFile = RunnerProjectUtils.getSnippetErrorFile(getRunnerProjectSettings(), snippet);

        if (errorFile.exists()) {
            // TODO enhance this section and make it clear
            List<String> lines = FileUtils.readLines(errorFile);

            String firstLine = lines.get(0);

            if (firstLine.startsWith("ERROR: test_data_generator:unfold_bck/6: Undefined procedure:")) {
                inputsXml.setResultType(ResultType.NA);
            } else if (firstLine.startsWith("ERROR: Domain error: `clpfd_expression' expected, found")) {
                inputsXml.setResultType(ResultType.NA);
            } else if (firstLine.startsWith("ERROR: Unknown message: error(resolve_classfile/")) {
                inputsXml.setResultType(ResultType.NA);
            } else if (firstLine.startsWith("ERROR: local_control:unfold/3: Undefined procedure:")) {
                inputsXml.setResultType(ResultType.NA);
            } else {
                // TODO enhance error handling

                // this is debug (only if unhandled error)
                System.err.println("=============================");
                System.err.println(snippet.getMethod());
                System.err.println("=============================");

                for (String line : lines) {
                    System.err.println(line);
                }
                System.err.println("=============================");

                // TODO enhance error handling
                throw new RuntimeException("PARSER PROBLEM, UNHANDLED ERROR");
            }
        } else {
            // TODO enhance

            // LineIterator lines = FileUtils.lineIterator(outputFile);
            List<String> lines = FileUtils.readLines(outputFile);

            if (lines.get(lines.size() - 1).startsWith("Error loading bytecode program")) {
                // System.err.println(snippet.getMethod().getName());
                // System.err.println("BYTECODE PROBLEM");
                inputsXml.setResultType(ResultType.EX);
                // throw new RuntimeException(""
            } else {
                inputsXml.setResultType(ResultType.S);

                // extract coverage
                if (lines.size() >= 8) {
                    String fullCode = lines.get(lines.size() - 3).trim();
                    String topCode = lines.get(lines.size() - 2).trim();

                    Matcher mFull = PATTERN_FULL_CODE.matcher(fullCode);
                    Matcher mTop = PATTERN_TOP_CODE.matcher(topCode);

                    // TODO should not use jPET coverage information in the
                    // future
                    if (mFull.matches() && mTop.matches()) {
                        double full = Double.parseDouble(mFull.group(1));
                        double top = Double.parseDouble(mTop.group(1));

                        if (full == 100.0 && top == 100.0) {
                            // full -> C
                            inputsXml.setResultType(ResultType.C);
                        } else if (snippet.getIncludedConstructors().isEmpty()
                                && snippet.getIncludedMethods().isEmpty()) {
                            // only consider top, no included things
                            if (top >= snippet.getRequiredStatementCoverage()) {
                                inputsXml.setResultType(ResultType.C);
                            } else {
                                inputsXml.setResultType(ResultType.NC);
                                // System.err.println(snippet.getMethod()
                                // .getName());
                                // System.err
                                // .println(String
                                // .format("No incl. no statis. - Full: %.2f Top: %.2f Req: %.2f",
                                // full,
                                // top,
                                // snippet.getRequiredStatementCoverage()));
                            }
                        } else {
                            // few cases, not very usefol top and full now...
                            // System.err.println(snippet.getMethod()
                            // .getName());
                            // System.err.println(String.format(
                            // "Has included - Full: %.2f Top: %.2f Req: %.2f",
                            // full,
                            // top,
                            // snippet.getRequiredStatementCoverage()));

                        }
                    } else {
                        // TODO error handling
                        System.err.println("Both should match");
                    }
                }

                // extract inputs
                lines = null;

                File testCasesFile = getTool().getTestCaseXmlFile(getRunnerProjectSettings(), snippet);
                new FileValidator(testCasesFile).type(FileType.REGULAR_FILE).validate();

                if (testCasesFile.length() > 10 * 10e6) {
                    // TODO enhance this section
                    System.err.println("Filesize is bigger than 10 MB: " + testCasesFile);
                }
                // TODO it was used to dump the cases where jpet cannot decide
                // coverage
                // if (inputsXml.getResultType() == ResultType.S) {
                // System.out.println("Only S");
                // }

                // now skip, only 12 cases are S

                System.out.println(
                        snippet.getContainer().getJavaClass().getName() + "." + snippet.getMethod().getName());

                SAXParserFactory factory = SAXParserFactory.newInstance();
                SAXParser saxParser = factory.newSAXParser();

                JPetTestCaseXmlParser testCasesParser = new JPetTestCaseXmlParser();

                saxParser.parse(testCasesFile, testCasesParser);

                JPetTestCasesConverter.convert(snippet, testCasesParser.getTestCases(), inputsXml);
            }

            // find input lines
            //
            // List<String> inputLines = new ArrayList<>();
            // boolean shouldCollect = false;
            // while (lines.hasNext()) {
            // String line = lines.next();
            // if (line.trim()
            // .equals("====================================================== Method Summaries"))
            // {
            // shouldCollect = true;
            // } else if (shouldCollect) {
            // if
            // (line.startsWith("======================================================"))
            // {
            // // start of next section
            // shouldCollect = false;
            // break;
            // } else {
            // if (!StringUtils.isBlank(line)) {
            // inputLines.add(line.trim());
            // }
            // }
            // }
            // }
            //
            // // close iterator
            // lines.close();
            //
            // // remove duplicates
            // inputLines = new ArrayList<>(new LinkedHashSet<>(inputLines));
            //
            // String firstLine = inputLines.get(0);
            // assert (firstLine.startsWith("Inputs: "));
            // firstLine = firstLine.substring(7).trim();
            // String[] parameterStrings = StringUtils.split(firstLine, ',');
            // ParameterType[] parameterTypes = new
            // ParameterType[parameterStrings.length];
            //
            // if (inputLines.size() == 2
            // && inputLines.get(1).startsWith("No path conditions for")) {
            // InputElement input = new InputElement();
            // for (int i = 0; i < parameterStrings.length; i++) {
            // // no path conditions, only considering the "default" inputs
            // Class<?> type = snippet.getMethod().getParameterTypes()[i];
            // parameterTypes[i] = getParameterType(type);
            // input.parameters().add(
            // new ParameterElement(parameterTypes[i],
            // getDefaultParameterString(type)));
            // }
            // inputsXml.generatedInputs().add(input);
            // } else {
            // // parse parameter types
            //
            // Class<?>[] paramsJavaClass = snippet.getMethod()
            // .getParameterTypes();
            //
            // for (int i = 0; i < parameterStrings.length; i++) {
            // String parameterString = parameterStrings[i];
            // Class<?> pjc = ClassUtils
            // .primitiveToWrapper(paramsJavaClass[i]);
            //
            // if (parameterString.endsWith("SYMINT")) {
            // if (pjc == Boolean.class) {
            // parameterTypes[i] = ParameterType.BOOLEAN;
            // } else if (pjc == Byte.class) {
            // parameterTypes[i] = ParameterType.BYTE;
            // } else if (pjc == Short.class) {
            // parameterTypes[i] = ParameterType.SHORT;
            // } else if (pjc == Integer.class) {
            // parameterTypes[i] = ParameterType.INT;
            // } else if (pjc == Long.class) {
            // parameterTypes[i] = ParameterType.LONG;
            // } else {
            // // int for something else
            // parameterTypes[i] = ParameterType.INT;
            // }
            // } else if (parameterString.endsWith("SYMREAL")) {
            // if (pjc == Float.class) {
            // parameterTypes[i] = ParameterType.FLOAT;
            // } else if (pjc == Float.class) {
            // parameterTypes[i] = ParameterType.DOUBLE;
            // } else {
            // // int for something else
            // parameterTypes[i] = ParameterType.DOUBLE;
            // }
            // } else {
            // // TODO error handling
            // // int for something else
            // throw new RuntimeException("PARSER PROBLEM");
            // }
            // }
            //
            // // example
            // // inheritsAPIGuessTwoPrimitives(11,-2147483648(don't care)) -->
            // // "java.lang.IllegalArgumentException..."
            // // inheritsAPIGuessTwoPrimitives(9,11) -->
            // // "java.lang.IllegalArgumentException..."
            // // inheritsAPIGuessTwoPrimitives(7,9) -->
            // // "java.lang.RuntimeException: Out of range..."
            // // inheritsAPIGuessTwoPrimitives(4,1) --> Return Value: 1
            // // inheritsAPIGuessTwoPrimitives(0,0) --> Return Value: 0
            // // inheritsAPIGuessTwoPrimitives(9,-88) -->
            // // "java.lang.IllegalArgumentException..."
            // // inheritsAPIGuessTwoPrimitives(-88,-2147483648(don't care))
            // // --> "java.lang.IllegalArgumentException..."
            //
            // String ps = String.format("^%s\\((.*)\\) --> (.*)$", snippet
            // .getMethod().getName());
            //
            // ps = String.format("^%s(.*) --> (.*)$", snippet.getMethod()
            // .getName());
            // Pattern p = Pattern.compile(ps);
            //
            // // parse inputs
            // int i = -1;
            // for (String line : inputLines) {
            // i++;
            //
            // if (i == 0) {
            // // first line
            // continue;
            // } else if (StringUtils.isEmpty(line)) {
            // continue;
            // }
            //
            // Matcher m = p.matcher(line);
            //
            // if (m.matches()) {
            // String paramsString = StringUtils.substring(m.group(1)
            // .trim(), 1, -1);
            // String resultString = m.group(2).trim();
            //
            // paramsString = StringUtils.replace(paramsString,
            // "(don't care)", "");
            //
            // String[] paramsStrings = StringUtils.split(
            // paramsString, ',');
            //
            // InputElement input = new InputElement();
            //
            // // if index error -> lesser inputs than parameters
            // for (int j = 0; j < parameterTypes.length; j++) {
            // if (parameterTypes[j] == ParameterType.BOOLEAN
            // && paramsStrings[j].contains("-2147483648")) {
            // // don't care -> 0
            // paramsStrings[j] = "false";
            // }
            //
            // ParameterElement pe = new ParameterElement(
            // parameterTypes[j], paramsStrings[j].trim());
            //
            // try {
            // // just check the type format
            // pe.validate();
            // } catch (Exception e) {
            // // TODO debug - remove or log
            // System.out.println(parameterTypes[j]);
            // System.out.println(paramsStrings[j]);
            // System.out.println(pe.getType());
            // System.out.println(pe.getValue());
            // e.printStackTrace();
            //
            // System.err
            // .println("=============================");
            // System.err.println(snippet.getMethod());
            // System.err
            // .println("=============================");
            // for (String lll : inputLines) {
            // System.err.println(lll);
            // }
            // System.err
            // .println("=============================");
            //
            // System.exit(-1);
            // }
            //
            // input.parameters().add(pe);
            // }
            //
            // if (resultString.startsWith("Return Value:")) {
            // // has retval, nothing to do
            // } else {
            // // exception; example (" is present inside the
            // // string!!!):
            // // "java.lang.ArithmeticException: div by 0..."
            // // "java.lang.IndexOutOfBoundsException: Index: 1, Size: 5..."
            //
            // int pos = resultString.indexOf(':');
            // if (pos < 0) {
            // // not found :, search for ...
            // pos = resultString.indexOf("...");
            // }
            //
            // String ex = resultString.substring(1, pos);
            //
            // input.setExpected((Class<? extends Throwable>) Class
            // .forName(ex));
            //
            // // System.err.println(resultString);
            // // System.err.println(ex);
            // // // input.setExpected(expected);
            // }
            //
            // inputsXml.generatedInputs().add(input);
            // } else {
            // System.err.println("NO MATCH");
            // System.err.println(ps);
            // System.err.println(line);
            // throw new Exception("NO MATCH: " + line);
            // }
            // }
            // }
            //
            // inputsXml.validate();
        }
    }
}