Package fit

Source Code of fit.FitServerTest

// Modified or written by Object Mentor, Inc. for inclusion with FitNesse.
// Copyright (c) 2002 Cunningham & Cunningham, Inc.
// Released under the terms of the GNU General Public License version 2 or later.
package fit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static util.RegexTestCase.assertSubString;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

import fitnesse.socketservice.SocketFactory;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import util.FileUtil;
import util.StreamReader;

public class FitServerTest {
  private static final int PORT_NUMBER = 1634;
  private Process process;
  private Socket socket;
  private ServerSocket serverSocket;
  private InputStream socketInput;
  private OutputStream socketOutput;
  private byte[] httpRequest;
  private ByteArrayOutputStream stdoutBytes;
  private String connectionStatusSize = "0000000000";

  @Before
  public void setup() {
    String sentinelName = FitServer.sentinelName(PORT_NUMBER);
    FileUtil.deleteFile(sentinelName);
  }

  @After
  public void tearDown() throws Exception {
    if (process != null)
      process.destroy();
    if (socket != null)
      socket.close();
    if (serverSocket != null)
      serverSocket.close();
  }

  @Test
  public void testSimpleStartUp() throws Exception {
    String junkMessage = "x";
    connectionStatusSize = "0000000001";
    prepareSessionProcess();
    assertTrue(new String(httpRequest)
        .startsWith("GET /?responder=socketCatcher&ticket=23"));
    socketOutput.write(junkMessage.getBytes());
    process.waitFor();
  }

  @Test
  public void testBadConnection() throws Exception {
    String errorMessage = "FAILURE";
    connectionStatusSize = "0000000007";
    prepareSessionProcess();
    socketOutput.write(errorMessage.getBytes());

    int exitValue = process.waitFor();
    String stdoutString = new String(stdoutBytes.toByteArray());

    assertTrue(exitValue != 0);
    // TODO This started to fail with Java 5.0... why does -1 turn into 255?
    // assertEquals("stdOut: " + stdoutString, -1, exitValue);
    assertTrue(stdoutString.contains(errorMessage));
  }

  @Test
  public void testNonTestInput() throws Exception {
    prepareSessionProcess();
    socketOutput.write("0000000020".getBytes());
    socketOutput.write("some untestable text".getBytes());
    socketOutput.flush();
    String sizeString = read(10);
    int size = Integer.parseInt(sizeString);
    String output = read(size);
    assertTrue(output.contains("Exception"));
    assertTrue(output.contains("Can't find tag: table"));
  }

  @Test
  public void testOneSimpleRun_Fail() throws Exception {
    String table = simpleTable("FailFixture");
    prepareSessionProcess();
    checkDocumentExecution(table);
    checkDocumentResults(0, 1, 0, 0);
    terminateSessionProcess();

    assertEquals(1, process.exitValue());
  }

  @Test
  public void testOneSimpleRun_Pass() throws Exception {
    String table = simpleTable("PassFixture");
    prepareSessionProcess();
    checkDocumentExecution(table);
    checkDocumentResults(1, 0, 0, 0);
    terminateSessionProcess();

    assertEquals(0, process.exitValue());
  }

  @Test
  public void testTwoSimpleRuns() throws Exception {
    String table = simpleTable("FailFixture");
    prepareSessionProcess();
    checkDocumentExecution(table);
    checkDocumentResults(0, 1, 0, 0);
    checkDocumentExecution(table);
    checkDocumentResults(0, 1, 0, 0);
    terminateSessionProcess();

    assertEquals(2, process.exitValue());
  }

  @Test
  public void testOneMulitiTableRun() throws Exception {
    String document = simpleTable("FailFixture") + simpleTable("FailFixture");
    prepareSessionProcess();

    FitProtocol.writeData(document, socketOutput);

    checkForTwoClassAttributesInResponse();

    checkDocumentResults(0, 2, 0, 0);
    terminateSessionProcess();
    assertEquals(2, process.exitValue());
  }

  @Test
  public void testUnicodeCharacters() throws Exception {
    String table = "\uba80\uba81\uba82\uba83" + simpleTable("PassFixture");
    prepareSessionProcess();
    FitProtocol.writeData(table, socketOutput);
    String response = readWholeResponse();

    assertSubString("\uba80\uba81\uba82\uba83", response);
    terminateSessionProcess();
  }

  @Test
  public void testExtraTextIdPrinted() throws Exception {
    String document = "<html>" + simpleTable("PassFixture") + "monkey"
        + simpleTable("PassFixture") + "</html>";
    prepareSessionProcess();

    FitProtocol.writeData(document, socketOutput);

    String response = readWholeResponse();

    assertTrue(response.startsWith("<html>"));
    assertTrue(response.contains("monkey"));
    assertTrue(response.endsWith("</html>"));
    terminateSessionProcess();
  }

  @Test
  public void testFitParseExceptionDontCrashSuite() throws Exception {
    String input = "no table";
    prepareSessionProcess();
    checkDocumentExecution(input);
    checkDocumentResults(0, 0, 0, 1);
    checkDocumentExecution(simpleTable("PassFixture"));
    checkDocumentResults(1, 0, 0, 0);
    terminateSessionProcess();

    assertEquals(1, process.exitValue());
  }

  private String read(int n) throws Exception {
    return new StreamReader(socketInput).read(n);
  }

  private void prepareSessionProcess() throws Exception {
    checkSentinelToMakeSureThatFitServerIsNotRunning();
    String commandWithArguments = command() + " -s -v localhost " + PORT_NUMBER
        + " 23";
    process = Runtime.getRuntime().exec(commandWithArguments);

    stdoutBytes = new ByteArrayOutputStream();

    watchForOutput(process.getInputStream(), new PrintStream(stdoutBytes));
    watchForOutput(process.getErrorStream(), System.err);

    establishConnection();
  }

  private void checkSentinelToMakeSureThatFitServerIsNotRunning()
      throws Exception {
    String sentinelName = FitServer.sentinelName(PORT_NUMBER);
    File sentinel = new File(sentinelName);
    assertFalse(sentinel.exists());
  }

  private void establishConnection() throws Exception {
    serverSocket = SocketFactory.tryCreateServerSocket(PORT_NUMBER);
    socket = null;

    listenForConnectionSocket();
    waitForConnectionSocket();

    assertNotNull(socket);
    assertNotNull(socketInput);
    assertNotNull(socketOutput);

    httpRequest = new byte[52]; // the precise length
    socketInput.read(httpRequest);

    socketOutput.write(connectionStatusSize.getBytes());
  }

  private void waitForConnectionSocket() throws InterruptedException {
    synchronized (serverSocket) {
      if (socket == null)
        serverSocket.wait();
    }
  }

  private void listenForConnectionSocket() {
    new Thread() {
      @Override
      public void run() {
        try {
          synchronized (serverSocket) {
            socket = serverSocket.accept();
            socketInput = socket.getInputStream();
            socketOutput = socket.getOutputStream();
            serverSocket.notify();
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }.start();
  }

  private void terminateSessionProcess() throws IOException,
      InterruptedException {
    try {
      socketOutput.write("0000000000".getBytes());
      process.waitFor();
    } finally {
      socketInput.close();
    }
  }

  private void watchForOutput(final InputStream processOutput,
      final PrintStream consoleOutput) {
    new Thread() {
      @Override
      public void run() {
        try {
          int b = 0;
          while ((b = processOutput.read()) != -1)
            consoleOutput.print((char) b);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }.start();
  }

  private void checkDocumentResults(int right, int wrong, int ignored,
      int exceptions) throws Exception {
    Counts actual = FitProtocol.readCounts(new StreamReader(socketInput));

    assertEquals(right, actual.right);
    assertEquals(wrong, actual.wrong);
    assertEquals(ignored, actual.ignores);
    assertEquals(exceptions, actual.exceptions);
  }

  private void checkDocumentExecution(String table) throws Exception {
    FitProtocol.writeData(table, socketOutput);
    checkForAttribute_class();
    checkSize("0000000000");
  }

  private void checkForAttribute_class() throws Exception {
    String output = readFromFitServer();
    assertTrue("'class' attribute was not found",
      output.contains("class="));
  }

  private String readFromFitServer() throws Exception {
    String readSize = read(10);
    int size = Integer.parseInt(readSize);
    String output = read(size);
    return output;
  }

  private void checkSize(String sizeString) throws Exception {
    assertEquals(sizeString, read(10));
  }

  private void checkForTwoClassAttributesInResponse() throws Exception {
    String response = readWholeResponse();
    int first = response.indexOf("class");
    int second = response.indexOf("class", first + 1);
    assertTrue((first >= 0) && (second > first));
  }

  private String readWholeResponse() throws Exception {
    StringBuffer buffer = new StringBuffer();
    String block = readFromFitServer();
    while (block.length() > 0) {
      buffer.append(block);
      block = readFromFitServer();
    }
    String response = buffer.toString();
    return response;
  }

  protected String command() {
    return "java -cp classes fit.FitServer";
  }

  protected String simpleTable(String fixtureName) {
    return "<table>" + "<tr><td>fitnesse.testutil." + fixtureName
        + "</td></tr>" + "</table>";
  }
}
TOP

Related Classes of fit.FitServerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.