001: // Modified or written by Object Mentor, Inc. for inclusion with FitNesse.
002: // Copyright (c) 2002 Cunningham & Cunningham, Inc.
003: // Released under the terms of the GNU General Public License version 2 or later.
004: package fit;
005:
006: import java.io.*;
007: import java.net.*;
008: import fitnesse.util.StreamReader;
009: import fitnesse.testutil.RegexTest;
010: import fitnesse.components.FitProtocol;
011:
012: public class FitServerTest extends RegexTest {
013: private Process process;
014: private Socket socket;
015: private ServerSocket serverSocket;
016: private InputStream socketInput;
017: private OutputStream socketOutput;
018: private byte[] httpRequest;
019: private ByteArrayOutputStream stdoutBytes;
020: private String connectionStatusSize = "0000000000";
021:
022: public void tearDown() throws Exception {
023: if (process != null)
024: process.destroy();
025: if (socket != null)
026: socket.close();
027: if (serverSocket != null)
028: serverSocket.close();
029: }
030:
031: public void testSimpleStartUp() throws Exception {
032: prepareSessionProcess();
033: assertTrue(new String(httpRequest)
034: .startsWith("GET /?responder=socketCatcher&ticket=23"));
035: }
036:
037: public void testBadConnection() throws Exception {
038: String errorMessage = "FAILURE";
039: connectionStatusSize = "0000000007";
040: prepareSessionProcess();
041: socketOutput.write(errorMessage.getBytes());
042:
043: int exitValue = process.waitFor();
044: String stdoutString = new String(stdoutBytes.toByteArray());
045:
046: assertTrue(exitValue != 0);
047: // This started to fail with Java 5.0... why does -1 turn into 255?
048: // assertEquals("stdout: " + stdoutString, -1, exitValue);
049: assertTrue(stdoutString.indexOf(errorMessage) != -1);
050: }
051:
052: public void testNonTestInput() throws Exception {
053: prepareSessionProcess();
054: socketOutput.write("0000000020".getBytes());
055: socketOutput.write("some untestable text".getBytes());
056: socketOutput.flush();
057: String sizeString = read(10);
058: int size = Integer.parseInt(sizeString);
059: String output = read(size);
060: assertTrue(output.indexOf("Exception") != -1);
061: assertTrue(output.indexOf("Can't find tag: table") != -1);
062: }
063:
064: public void testOneSimpleRun_Fail() throws Exception {
065: String table = simpleTable("FailFixture");
066: prepareSessionProcess();
067: checkDocumentExecution(table);
068: checkDocumentResults(0, 1, 0, 0);
069: terminateSessionProcess();
070:
071: assertEquals(1, process.exitValue());
072: }
073:
074: public void testOneSimpleRun_Pass() throws Exception {
075: String table = simpleTable("PassFixture");
076: prepareSessionProcess();
077: checkDocumentExecution(table);
078: checkDocumentResults(1, 0, 0, 0);
079: terminateSessionProcess();
080:
081: assertEquals(0, process.exitValue());
082: }
083:
084: public void testTwoSimpleRuns() throws Exception {
085: String table = simpleTable("FailFixture");
086: prepareSessionProcess();
087: checkDocumentExecution(table);
088: checkDocumentResults(0, 1, 0, 0);
089: checkDocumentExecution(table);
090: checkDocumentResults(0, 1, 0, 0);
091: terminateSessionProcess();
092:
093: assertEquals(2, process.exitValue());
094: }
095:
096: public void testOneMulitiTableRun() throws Exception {
097: String document = simpleTable("FailFixture")
098: + simpleTable("FailFixture");
099: prepareSessionProcess();
100:
101: FitProtocol.writeData(document, socketOutput);
102:
103: checkForTwoClassAttributesInResponse();
104:
105: checkDocumentResults(0, 2, 0, 0);
106: terminateSessionProcess();
107: assertEquals(2, process.exitValue());
108: }
109:
110: public void testUnicodeCharacters() throws Exception {
111: String table = "\uba80\uba81\uba82\uba83"
112: + simpleTable("PassFixture");
113: prepareSessionProcess();
114: FitProtocol.writeData(table, socketOutput);
115: String response = readWholeResponse();
116:
117: assertSubString("\uba80\uba81\uba82\uba83", response);
118: terminateSessionProcess();
119: }
120:
121: public void testExtraTextIdPrinted() throws Exception {
122: String document = "<html>" + simpleTable("PassFixture")
123: + "monkey" + simpleTable("PassFixture") + "</html>";
124: prepareSessionProcess();
125:
126: FitProtocol.writeData(document, socketOutput);
127:
128: String response = readWholeResponse();
129:
130: assertTrue(response.startsWith("<html>"));
131: assertTrue(response.indexOf("monkey") != -1);
132: assertTrue(response.endsWith("</html>"));
133: terminateSessionProcess();
134: }
135:
136: public void testFitParseExceptionDontCrashSuite() throws Exception {
137: String input = "no table";
138: prepareSessionProcess();
139: checkDocumentExecution(input);
140: checkDocumentResults(0, 0, 0, 1);
141: checkDocumentExecution(simpleTable("PassFixture"));
142: checkDocumentResults(1, 0, 0, 0);
143: terminateSessionProcess();
144:
145: assertEquals(1, process.exitValue());
146: }
147:
148: private String read(int n) throws Exception {
149: return new StreamReader(socketInput).read(n);
150: }
151:
152: private void prepareSessionProcess() throws Exception {
153: String commandWithArguments = command()
154: + " -v localhost 1234 23";
155: process = Runtime.getRuntime().exec(commandWithArguments);
156:
157: stdoutBytes = new ByteArrayOutputStream();
158:
159: watchForOutput(process.getInputStream(), new PrintStream(
160: stdoutBytes));
161: watchForOutput(process.getErrorStream(), System.err);
162:
163: establishConnection();
164: }
165:
166: private void establishConnection() throws Exception {
167: serverSocket = new ServerSocket(1234);
168: socket = null;
169:
170: listenForConnectionSocket();
171: waitForConnectionSocket();
172:
173: assertNotNull(socket);
174: assertNotNull(socketInput);
175: assertNotNull(socketOutput);
176:
177: httpRequest = new byte[52]; // the precise length
178: socketInput.read(httpRequest);
179:
180: socketOutput.write(connectionStatusSize.getBytes());
181: }
182:
183: private void waitForConnectionSocket() throws InterruptedException {
184: synchronized (serverSocket) {
185: if (socket == null)
186: serverSocket.wait();
187: }
188: }
189:
190: private void listenForConnectionSocket() {
191: new Thread() {
192: public void run() {
193: try {
194: synchronized (serverSocket) {
195: socket = serverSocket.accept();
196: socketInput = socket.getInputStream();
197: socketOutput = socket.getOutputStream();
198: serverSocket.notify();
199: }
200: } catch (IOException e) {
201: e.printStackTrace();
202: }
203: }
204: }.start();
205: }
206:
207: private void terminateSessionProcess() throws IOException,
208: InterruptedException {
209: socketOutput.write("0000000000".getBytes());
210: process.waitFor();
211: socketInput.close();
212: }
213:
214: private void watchForOutput(final InputStream processOutput,
215: final PrintStream consoleOutput) {
216: new Thread() {
217: public void run() {
218: try {
219: int b = 0;
220: while ((b = processOutput.read()) != -1)
221: consoleOutput.print((char) b);
222: } catch (IOException e) {
223: e.printStackTrace();
224: }
225: }
226: }.start();
227: }
228:
229: private void checkDocumentResults(int right, int wrong,
230: int ignored, int exceptions) throws Exception {
231: Counts actual = FitProtocol.readCounts(new StreamReader(
232: socketInput));
233:
234: assertEquals(right, actual.right);
235: assertEquals(wrong, actual.wrong);
236: assertEquals(ignored, actual.ignores);
237: assertEquals(exceptions, actual.exceptions);
238: }
239:
240: private void checkDocumentExecution(String table) throws Exception {
241: FitProtocol.writeData(table, socketOutput);
242: checkForAttribute_class();
243: checkSize("0000000000");
244: }
245:
246: private void checkForAttribute_class() throws Exception {
247: String output = readFromFitServer();
248: assertTrue("'class' attribute was not found", output
249: .indexOf("class=") != -1);
250: }
251:
252: private String readFromFitServer() throws Exception {
253: String readSize = read(10);
254: int size = Integer.parseInt(readSize);
255: String output = read(size);
256: return output;
257: }
258:
259: private void checkSize(String sizeString) throws Exception {
260: assertEquals(sizeString, read(10));
261: }
262:
263: private void checkForTwoClassAttributesInResponse()
264: throws Exception {
265: String response = readWholeResponse();
266: int first = response.indexOf("class");
267: int second = response.indexOf("class", first + 1);
268: assertTrue((first >= 0) && (second > first));
269: }
270:
271: private String readWholeResponse() throws Exception {
272: StringBuffer buffer = new StringBuffer();
273: String block = readFromFitServer();
274: ;
275: while (block.length() > 0) {
276: buffer.append(block);
277: block = readFromFitServer();
278: }
279: String response = buffer.toString();
280: return response;
281: }
282:
283: protected String command() {
284: return "java -cp classes fit.FitServer";
285: }
286:
287: protected String simpleTable(String fixtureName) {
288: return "<table>" + "<tr><td>fitnesse.testutil." + fixtureName
289: + "</td></tr>" + "</table>";
290: }
291: }
|