fitnesse.slim.SlimServiceTestBase.java Source code

Java tutorial

Introduction

Here is the source code for fitnesse.slim.SlimServiceTestBase.java

Source

// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.slim;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import fitnesse.slim.instructions.CallInstruction;
import fitnesse.slim.instructions.ImportInstruction;
import fitnesse.slim.instructions.Instruction;
import fitnesse.slim.instructions.MakeInstruction;
import fitnesse.socketservice.*;
import fitnesse.testsystems.CompositeExecutionLogListener;
import fitnesse.testsystems.MockCommandRunner;
import fitnesse.testsystems.slim.SlimCommandRunningClient;
import org.apache.commons.lang.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

// Extracted Test class to be implemented by all Java based Slim ports
// The tests for PhpSlim and JsSlim implement this class

public abstract class SlimServiceTestBase {
    static Thread service;
    protected List<Instruction> statements;
    protected SlimCommandRunningClient slimClient;

    public static synchronized void startWithFactoryAsync(final SlimFactory slimFactory,
            final SlimService.Options options) throws IOException {
        if (service != null && service.isAlive()) {
            service.interrupt();
            throw new SlimError("Already an in-process server running: " + service.getName() + " (alive="
                    + service.isAlive() + ")");
        }
        ServerSocketFactory serverSocketFactory = options.useSSL
                ? new SslServerSocketFactory(true, SslParameters.createSslParameters(options.sslParameterClassName))
                : new PlainServerSocketFactory();
        final SlimService slimservice = new SlimService(slimFactory.getSlimServer(),
                serverSocketFactory.createServerSocket(options.port), options.daemon);
        service = new Thread() {
            @Override
            public void run() {
                try {
                    slimservice.accept();
                } catch (IOException e) {
                    throw new SlimError(e);
                }
            }
        };
        service.start();
    }

    public static void waitForServiceToStopAsync() throws InterruptedException {
        // wait for service to close.
        for (int i = 0; i < 1000; i++) {
            if (!service.isAlive())
                break;
            Thread.sleep(50);
        }
    }

    protected abstract void startSlimService() throws Exception;

    protected abstract void closeSlimService() throws Exception;

    protected abstract String getImport();

    protected abstract String expectedExceptionMessage();

    protected abstract String expectedStopTestExceptionMessage();

    @Before
    public void setUp() throws InterruptedException, IOException {
        createSlimService();
        slimClient = new SlimCommandRunningClient(new MockCommandRunner(new CompositeExecutionLogListener()),
                "localhost", 8099, 10, SlimCommandRunningClient.MINIMUM_REQUIRED_SLIM_VERSION,
                new PlainClientSocketFactory());
        statements = new ArrayList<>();
        slimClient.connect();
    }

    protected void createSlimService() throws InterruptedException {
        while (!tryCreateSlimService())
            Thread.sleep(10);
    }

    private boolean tryCreateSlimService() {
        try {
            startSlimService();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @After
    public void after() throws Exception {
        teardown();
    }

    protected void teardown() throws Exception {
        slimClient.bye();
        slimClient.kill();
        closeSlimService();
    }

    @Test
    public void emptySession() throws Exception {
        assertTrue("Connected", slimClient.isConnected());
    }

    @Test
    public void versionNumberShouldBeDetected() throws Exception {
        double slimVersion = Double.parseDouble(SlimVersion.VERSION);
        assertEquals(slimVersion, slimClient.getServerVersion(), .0001);
    }

    @Test
    public void callOneMethod() throws Exception {
        addImportAndMake();
        addEchoInt("id", "1");
        Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
        assertEquals("1", result.get("id"));
    }

    private void addEchoInt(String id, String number) {
        statements.add(new CallInstruction(id, "testSlim", "echoInt", new Object[] { number }));
    }

    private void addImportAndMake() {
        statements.add(new ImportInstruction("i1", getImport()));
        statements.add(new MakeInstruction("m1", "testSlim", "TestSlim"));
    }

    @Test
    public void makeManyCallsInOrderToTestLongSequencesOfInstructions() throws Exception {
        addImportAndMake();
        for (int i = 0; i < 1000; i++)
            addEchoInt(String.format("id_%d", i), Integer.toString(i));
        Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
        for (int i = 0; i < 1000; i++)
            assertEquals(i, Integer.parseInt((String) result.get(String.format("id_%d", i))));
    }

    @Test
    public void callWithLineBreakInStringArgument() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "echoString", new Object[] { "hello\nworld\n" }));
        Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
        assertEquals("hello\nworld\n", result.get("id"));
    }

    @Test
    public void callWithMultiByteChar() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "echoString", new Object[] { "K\u00f6ln" }));
        Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
        assertEquals("K\u00f6ln", result.get("id"));
    }

    @Test
    public void makeManyIndividualCalls() throws Exception {
        addImportAndMake();
        slimClient.invokeAndGetResponse(statements);
        for (int i = 0; i < 100; i++) {
            statements.clear();
            addEchoInt("id", "42");
            Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
            assertEquals(1, result.size());
            assertEquals("42", result.get("id"));
        }
    }

    @Test
    public void callFunctionThatDoesntExist() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "noSuchFunction"));
        Map<String, Object> results = slimClient.invokeAndGetResponse(statements);
        assertContainsException("message:<<NO_METHOD_IN_CLASS", "id", results);
    }

    @Test
    public void callFunctionThatReturnsHugeResult() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "returnHugeString"));
        slimClient.invokeAndGetResponse(statements);
        // should not crash
    }

    @Test
    public void callFunctionWithHugeParameter() throws Exception {
        addImportAndMake();
        String hugeString = StringUtils.repeat("x", 999999 + 10);
        statements.add(new CallInstruction("id", "testSlim", "echoString", new Object[] { hugeString }));
        Map<String, Object> result = slimClient.invokeAndGetResponse(statements);
        assertEquals(hugeString, result.get("id"));
    }

    private void assertContainsException(String message, String id, Map<String, Object> results) {
        String result = (String) results.get(id);
        assertTrue(result, result.contains(SlimServer.EXCEPTION_TAG) && result.contains(message));
    }

    @Test
    public void makeClassThatDoesntExist() throws Exception {
        statements.add(new MakeInstruction("m1", "me", "NoSuchClass"));
        Map<String, Object> results = slimClient.invokeAndGetResponse(statements);
        assertContainsException("message:<<COULD_NOT_INVOKE_CONSTRUCTOR", "m1", results);
    }

    @Test
    public void useInstanceThatDoesntExist() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "noInstance", "f"));
        Map<String, Object> results = slimClient.invokeAndGetResponse(statements);
        assertContainsException("message:<<NO_INSTANCE", "id", results);
    }

    @Test
    public void verboseArgument() throws Exception {
        String args[] = { "-v", "99" };
        SlimService.Options options = SlimService.parseCommandLine(args);
        assertNotNull(options);
        assertTrue(options.verbose);
    }

    @Test
    public void notStopTestExceptionThrown() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "throwNormal"));
        statements.add(new CallInstruction("id2", "testSlim", "throwNormal"));
        Map<String, Object> results = slimClient.invokeAndGetResponse(statements);
        assertContainsException("__EXCEPTION__:" + expectedExceptionMessage(), "id", results);
        assertContainsException("__EXCEPTION__:" + expectedExceptionMessage(), "id2", results);
    }

    @Test
    public void stopTestExceptionThrown() throws Exception {
        addImportAndMake();
        statements.add(new CallInstruction("id", "testSlim", "throwStopping"));
        statements.add(new CallInstruction("id2", "testSlim", "throwNormal"));
        Map<String, Object> results = slimClient.invokeAndGetResponse(statements);
        assertContainsException("__EXCEPTION__:" + expectedStopTestExceptionMessage(), "id", results);
        assertNull(results.get("id2"));
    }

    @Test
    public void canSpecifyAnInteractionClass() {
        final SlimService.Options options = SlimService
                .parseCommandLine(new String[] { "-i", "fitnesse.slim.fixtureInteraction.DefaultInteraction" });
        assertNotNull("should parse correctly", options);
        assertEquals("fitnesse.slim.fixtureInteraction.DefaultInteraction",
                options.interaction.getClass().getName());
    }

    @Test
    public void canSpecifyAComplexCommandLine() {
        String commandLine = "-v -i fitnesse.slim.fixtureInteraction.DefaultInteraction 7890";
        String[] args = commandLine.split(" ");

        SlimService.Options options = SlimService.parseCommandLine(args);
        assertNotNull("should parse correctly", options);
        assertEquals("should have interaction class set", "fitnesse.slim.fixtureInteraction.DefaultInteraction",
                options.interaction.getClass().getName());
        assertTrue("should be verbose", options.verbose);
        assertEquals("should have set port", 7890, options.port);
    }

    @Test
    public void canSpecifyComplexArgs() {
        String commandLine = "-v -i fitnesse.slim.fixtureInteraction.DefaultInteraction 7890";
        String[] args = commandLine.split(" ");

        SlimService.Options options = SlimService.parseCommandLine(args);
        assertNotNull("should parse correctly", options);
        assertEquals("should have interaction class set", "fitnesse.slim.fixtureInteraction.DefaultInteraction",
                options.interaction.getClass().getName());
        assertTrue("should be verbose", options.verbose);
        assertEquals("should have set port", 7890, options.port);
    }

}