org.overture.ct.ctruntime.tests.CtTestCaseBase.java Source code

Java tutorial

Introduction

Here is the source code for org.overture.ct.ctruntime.tests.CtTestCaseBase.java

Source

/*
 * #%~
 * Combinatorial Testing Runtime
 * %%
 * Copyright (C) 2008 - 2014 Overture
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #~%
 */
package org.overture.ct.ctruntime.tests;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.overture.ast.lex.Dialect;
import org.overture.ast.lex.LexLocation;
import org.overture.config.Settings;
import org.overture.ct.ctruntime.TraceRunnerMain;
import org.overture.ct.ctruntime.utils.CtHelper;
import org.overture.ct.ctruntime.utils.CtHelper.CtTestData;
import org.overture.ct.ctruntime.utils.Data;
import org.overture.ct.ctruntime.utils.TraceResult;
import org.overture.ct.ctruntime.utils.TraceResultReader;
import org.overture.test.framework.Properties;
import org.overture.test.framework.TestResourcesResultTestCase4;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

@SuppressWarnings("rawtypes")
public abstract class CtTestCaseBase extends TestResourcesResultTestCase4 {
    private static final String TESTS_CT_RUNTIME_PROPERTY_PREFIX = "tests.ctruntime.override.";

    // The socket is used to communicate with the trace interpreter
    protected ServerSocket socket;
    protected static final int SOCKET_TIMEOUT = 0;
    private static final int FROM_PORT = 10000;
    private static final int TO_PORT = 50000;

    // Used a fixed trace name for simplicity
    protected static final String TRACE_NAME = "T1";

    public static final String TRACE_OUTPUT_FOLDER = "target/trace-output/";

    private File traceFolder;
    private CtTestData testdata;

    public CtTestCaseBase() {
        super();
    }

    public CtTestCaseBase(File file, File traceFolder, CtTestData args) {
        super(file);

        this.testdata = args;
        this.traceFolder = traceFolder;
    }

    @Before
    public void internalSetup() throws Exception {
        setUp();

    }

    abstract public void setUp() throws Exception;

    @After
    public void tearDown() throws Exception {
        try {
            if (this.socket != null) {
                this.socket.close();
            }
        } catch (Exception e) {
        }
    }

    @Test
    public void test() throws Exception {
        if (file == null) {
            return;
        }

        try {
            configureResultGeneration();

            File actualResultsFile = computeActualResults(TRACE_NAME);

            if (Properties.recordTestResults) {
                try {
                    File resultFile = createResultFile(file.getAbsolutePath());
                    resultFile.getParentFile().mkdirs();

                    // Overwrite result file
                    FileUtils.copyFile(actualResultsFile, resultFile);

                } catch (Exception e) {
                    Assert.fail("The produced results could not be stored: " + e.getMessage());
                }
            } else {
                File resultFile = getResultFile(file.getAbsolutePath());

                TraceResultReader reader = new TraceResultReader();
                List<TraceResult> actualResults = reader.read(actualResultsFile);

                Assert.assertTrue("No result file found for test: " + file + "\n\n" + actualResults,
                        resultFile.exists());
                List<TraceResult> expectedResults = reader.read(resultFile);

                Assert.assertTrue(expectedResults.size() == actualResults.size());

                int size = expectedResults.size();

                for (int i = 0; i < size; i++) {
                    TraceResult expected = expectedResults.get(i);
                    TraceResult actual = actualResults.get(i);

                    Assert.assertTrue("Actual results differs from expected results for test: " + file
                            + "\nExpected: " + expectedResults + "\n\nActual: " + actualResults,
                            expected.equals(actual));
                }
            }
        } finally {
            unconfigureResultGeneration();
        }

    }

    @Override
    protected File createResultFile(String filename) {
        return new File(filename + ".result");
    }

    @Override
    protected File getResultFile(String filename) {
        return new File(filename + ".result");
    }

    public File computeActualResults(final String spec)
            throws IOException, XPathExpressionException, SAXException, ParserConfigurationException {
        int port = findAvailablePort(FROM_PORT, TO_PORT);
        socket = new ServerSocket(port);
        socket.setSoTimeout(SOCKET_TIMEOUT);
        final Data data = new Data();

        traceFolder.mkdirs();

        String traceName = "T1";

        String actualOutputFileName = (Settings.dialect == Dialect.VDM_SL ? "DEFAULT-" : "Entry-") + traceName
                + ".xml";

        final File actualOutputFile = new File(traceFolder, actualOutputFileName);

        CtHelper testHelper = new CtHelper();
        Thread t = testHelper.consCtClientThread(socket, data);
        t.setDaemon(false);
        t.start();

        TraceRunnerMain.USE_SYSTEM_EXIT = false;

        this.testdata.port = port;

        String[] args = testHelper.buildArgs(Settings.dialect, Settings.release, testdata);

        TraceRunnerMain.main(args);

        final String message = data.getMessage();

        Assert.assertTrue(
                "Test did not succed. Are you sure that it contains "
                        + (Settings.dialect == Dialect.VDM_SL ? "'DEFAULT`T1'" : "'Entry`T1'"),
                message.contains("status=\"completed\" progress=\"100\""));

        return actualOutputFile;
    }

    @Override
    public void encodeResult(Object result, Document doc, Element resultElement) {

    }

    @Override
    public Object decodeResult(Node node) {
        return null;
    }

    @Override
    protected boolean assertEqualResults(Object expected, Object actual, PrintWriter out) {
        return false;
    }

    protected void configureResultGeneration() {
        LexLocation.absoluteToStringLocation = false;
        if (System.getProperty(TESTS_CT_RUNTIME_PROPERTY_PREFIX + "all") != null || getPropertyId() != null
                && System.getProperty(TESTS_CT_RUNTIME_PROPERTY_PREFIX + getPropertyId()) != null) {
            Properties.recordTestResults = true;
        }

    }

    protected void unconfigureResultGeneration() {
        Properties.recordTestResults = false;
    }

    protected abstract String getPropertyId();

    public static int findAvailablePort(int fromPort, int toPort) {
        if (fromPort > toPort) {
            throw new IllegalArgumentException("startPortShouldBeLessThanOrEqualToEndPort");
        }

        int port = fromPort;
        ServerSocket socket = null;
        while (port <= toPort) {
            try {
                socket = new ServerSocket(port);
                return port;
            } catch (IOException e) {
                ++port;
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return -1;
    }
}