com.googlecode.promnetpp.research.main.CoverageMain.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.promnetpp.research.main.CoverageMain.java

Source

/*
 * Copyright (c) 2013, Miguel Martins
 * Use is subject to license terms.
 *
 * This source code file is provided under the MIT License. Full licensing
 * terms should be available in the form of text files. The standard source code
 * distribution provides a LICENSE.txt file which can be consulted for licensing
 * details.
 */
package com.googlecode.promnetpp.research.main;

import com.googlecode.promnetpp.research.data.GeneralData;
import com.googlecode.promnetpp.research.data.Protocol;
import com.googlecode.promnetpp.research.data.PANOptions;
import com.googlecode.promnetpp.research.other.Utilities;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;

/**
 *
 * @author Miguel Martins
 */
public class CoverageMain {
    private static String sourceCode;
    private static String fileName;
    private static File CSVFile = new File("results.csv");
    private static int currentSeed;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            System.out.println(GeneralData.seeds.length + " seeds available.");
            prepareCSVFile();
            for (String _fileName : GeneralData.fileNames) {
                fileName = _fileName;
                sourceCode = FileUtils.readFileToString(new File(fileName));
                System.out.println("Running seeds for file " + fileName);
                for (int seed : GeneralData.seeds) {
                    doSeedRun(seed);
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(CoverageMain.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            Logger.getLogger(CoverageMain.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            cleanup();
        }
    }

    private static void doSeedRun(int seed) throws IOException, InterruptedException {
        currentSeed = seed;
        System.out.println("Running with seed " + seed);
        String pattern = "int random = <INSERT_SEED_HERE>;";
        int start = sourceCode.indexOf(pattern);
        int end = start + pattern.length();
        String line = sourceCode.substring(start, end);
        line = line.replace("<INSERT_SEED_HERE>", Integer.toString(seed));
        String sourceCodeWithSeed = sourceCode.replace(pattern, line);
        FileUtils.writeStringToFile(new File("temp.pml"), sourceCodeWithSeed);
        //Run Spin first
        List<String> spinCommand = new ArrayList<String>();
        spinCommand.add(GeneralData.spinHome + "/spin");
        spinCommand.add("-a");
        spinCommand.add("temp.pml");
        ProcessBuilder processBuilder = new ProcessBuilder(spinCommand);
        Process process = processBuilder.start();
        process.waitFor();
        //Compile PAN next
        List<String> compilePANCommand = new ArrayList<String>();
        compilePANCommand.add("gcc");
        compilePANCommand.add("-o");
        compilePANCommand.add("pan");
        compilePANCommand.add("pan.c");
        processBuilder = new ProcessBuilder(compilePANCommand);
        process = processBuilder.start();
        process.waitFor();
        //Finally, run PAN
        List<String> runPANCommand = new ArrayList<String>();
        runPANCommand.add("./pan");
        String runtimeOptions = PANOptions.getRuntimeOptionsFor(fileName);
        if (!runtimeOptions.isEmpty()) {
            runPANCommand.add(runtimeOptions);
        }
        processBuilder = new ProcessBuilder(runPANCommand);
        process = processBuilder.start();
        process.waitFor();
        String PANOutput = Utilities.getStreamAsString(process.getInputStream());
        if (PANOutputContainsErrors(PANOutput)) {
            throw new RuntimeException("PAN reported errors.");
        }
        processPANOutput(PANOutput);
    }

    private static void processPANOutput(String output) throws IOException {
        //Have a truncated version of the output
        int start = output.indexOf("unreached in");
        if (start == -1) {
            FileUtils.writeStringToFile(CSVFile,
                    fileName + "," + "\"none\"," + "\"none\"," + "\"none\"," + "\"none\"\n", true);
        } else {
            String partialOutput = output.substring(start);
            String endPattern = "states)";
            int end = partialOutput.lastIndexOf(endPattern) + endPattern.length();
            partialOutput = partialOutput.substring(0, end);
            //Search for unreached lines
            Pattern pattern = Pattern.compile("temp[.]pml[:]\\d+?,");
            Matcher matcher = pattern.matcher(partialOutput);
            String lineNumbers = "";
            while (matcher.find()) {
                String line = matcher.group();
                line = line.substring(line.indexOf(":") + 1);
                line = line.replace(",", "");
                int lineNumber = Integer.parseInt(line);
                lineNumbers += lineNumber + ",";
            }
            //Remove trailing comma
            lineNumbers = lineNumbers.substring(0, lineNumbers.length() - 1);
            String relevantLineNumbers = Protocol.excludeIrrelevantLineNumbers(fileName, lineNumbers);
            FileUtils.writeStringToFile(CSVFile,
                    fileName + "," + Integer.toString(currentSeed) + "," + "\""
                            + partialOutput.replace("\"", "\"\"") + "\"," + "\"" + lineNumbers + "\"," + "\""
                            + relevantLineNumbers + "\"\n",
                    true);
        }

    }

    private static void prepareCSVFile() throws IOException {
        if (CSVFile.exists()) {
            CSVFile.delete();
        }
        CSVFile.createNewFile();
        FileUtils.writeStringToFile(CSVFile, "\"File name\"," + "\"Seed\"," + "\"Output\","
                + "\"Unreachable lines\"," + "\"Unreachable lines (excluding irrelevant)\"\n");
    }

    private static void cleanup() {
        List<String> filesToDelete = new ArrayList<String>();
        filesToDelete.add("pan.b");
        filesToDelete.add("pan.c");
        filesToDelete.add("pan.exe"); //Windows
        filesToDelete.add("pan"); //Linux/OS X
        filesToDelete.add("pan.h");
        filesToDelete.add("pan.m");
        filesToDelete.add("pan.p");
        filesToDelete.add("pan.t");
        filesToDelete.add("temp.pml");
        filesToDelete.add("temp.pml.trail");
        for (String file : filesToDelete) {
            new File(file).deleteOnExit();
        }
    }

    private static boolean PANOutputContainsErrors(String output) {
        String errorReport = output.substring(output.indexOf("errors: "));
        errorReport = errorReport.substring(0, errorReport.indexOf("\n") - 1);
        String errorCountAsString = errorReport.substring(errorReport.indexOf(": "));
        errorCountAsString = errorCountAsString.substring(": ".length());
        int errorCount = Integer.parseInt(errorCountAsString);
        if (errorCount > 0) {
            System.err.println(output);
            return true;
        }
        return false;
    }
}