You are viewing a plain text version of this content. The canonical link for it is here.
Posted to awf-commits@incubator.apache.org by jm...@apache.org on 2012/02/12 20:24:36 UTC
svn commit: r1243316 [7/8] - in /incubator/deft/sandbox/jmeehan: ./
awf-core/ awf-core/.settings/ awf-core/src/ awf-core/src/main/
awf-core/src/main/assembly/ awf-core/src/main/java/
awf-core/src/main/java/org/ awf-core/src/main/java/org/apache/ awf-co...
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpBufferedLexerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpBufferedLexerTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpBufferedLexerTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpBufferedLexerTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+
+import java.nio.ByteBuffer;
+
+import junit.framework.Assert;
+
+import org.apache.awf.web.http.HttpBufferedLexer;
+import org.apache.awf.web.http.HttpParsingContext;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.awf.web.http.HttpBufferedLexer.*;
+import static org.apache.awf.web.http.HttpParsingContext.TokenType;
+
+/**
+ * Unit tests suite for HttpBufferedLexer
+ */
+public class HttpBufferedLexerTest {
+
+ HttpBufferedLexer lexer;
+ HttpParsingContext context;
+
+ @Before
+ public void init() {
+ lexer = new HttpBufferedLexer();
+ context = new HttpParsingContext();
+ }
+
+ @Test
+ public void testNextTokenSimpleGet() throws Exception {
+ String request = "GET /path/script.cgi HTTP/1.1\r\n\r\n";
+
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals("Token GET should be found with no errors", 1, res);
+ Assert.assertEquals("GET", context.getTokenValue());
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals("Token uri should be found with no errors", 1, res);
+ Assert.assertEquals("/path/script.cgi", context.getTokenValue());
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals("Token protocol version should be found with no errors", 1, res);
+ Assert.assertEquals("HTTP/1.1", context.getTokenValue());
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals("Token body should be found with no errors", 1, res);
+ Assert.assertEquals(TokenType.BODY, context.currentType);
+ Assert.assertEquals("TokenValue should be null for body", "", context.getTokenValue());
+
+ }
+
+ @Test
+ public void requestLineContainingCRLF() {
+ String request = "GET\r\n /path/script.cgi HTTP/1.1\r\n\r\n";
+
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals("Token GET should be found with error", -1, res);
+ }
+
+ @Test
+ public void requestWithHeadersParsing() {
+
+ String request = "POST /path/script.cgi HTTP/1.0\r\n"
+ + "Host: localhost\r\n"
+ + "From: frog@jmarshall.com\r\n"
+ + "User-Agent: HTTPTool/1.0\r\n"
+ + "Content-Type: application/x-www-form-urlencoded\r\n"
+ + "Content-Length: 32\r\n\r\n";
+
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+ String[][] headers = new String[][]{{"Host", " localhost"},
+ {"From", " frog@jmarshall.com"},
+ {"User-Agent", " HTTPTool/1.0"},
+ {"Content-Type", " application/x-www-form-urlencoded"},
+ {"Content-Length", " 32"}};
+
+ int res = lexer.nextToken(context);
+ String method = context.getTokenValue();
+ res = lexer.nextToken(context);
+ String path = context.getTokenValue();
+ res = lexer.nextToken(context);
+ String protocol = context.getTokenValue();
+
+ Assert.assertEquals("POST", method);
+ Assert.assertEquals("/path/script.cgi", path);
+ Assert.assertEquals("HTTP/1.0", protocol);
+
+ for (String[] header : headers) {
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(header[0], context.getTokenValue());
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(header[1], context.getTokenValue());
+ }
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals("Token body should be found with no errors", 1, res);
+ Assert.assertEquals(TokenType.BODY, context.currentType);
+ Assert.assertEquals("TokenValue should be null for body", "", context.getTokenValue());
+
+ }
+
+ @Test
+ public void requestLineWithTrailingHeaders() {
+ String request = " \r\n \r\nPOST ";
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+ Assert.assertEquals("POST", context.getTokenValue());
+ }
+
+ @Test
+ public void incompleteHeaderAfterRequestLine() {
+ String requestPart1 = "Content-";
+ String requestPart2 = "Type: application";
+ String requestPart3 = "/x-www-form-";
+ String requestPart4 = "urlencoded\r\n";
+ context.currentType = TokenType.HTTP_VERSION;
+ context.setBuffer(ByteBuffer.wrap(requestPart1.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+ Assert.assertEquals("Content-", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart2.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals("Content-Type", context.getTokenValue());
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(" application", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart3.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(" application/x-www-form-", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart4.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(" application/x-www-form-urlencoded", context.getTokenValue());
+ }
+
+ @Test
+ public void incompleteHeaderAfterHeader() {
+ String requestPart1 = "Content-";
+ String requestPart2 = "Type: application";
+ String requestPart3 = "/x-www-form-";
+ String requestPart4 = "urlencoded\r\n";
+ context.currentType = TokenType.HEADER_VALUE;
+ context.setBuffer(ByteBuffer.wrap(requestPart1.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("Content-", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart2.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals("Content-Type", context.getTokenValue());
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(" application", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart3.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(0, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(" application/x-www-form-", context.getTokenValue());
+
+ context.setBuffer(ByteBuffer.wrap(requestPart4.getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(" application/x-www-form-urlencoded", context.getTokenValue());
+ }
+
+ @Test
+ public void parseMultiLineHeaders() {
+ String request = "my headervalue\r\n and so on\r\n\tand so on\r\n";
+ context.currentType = TokenType.HEADER_NAME;
+ context.setBuffer(ByteBuffer.wrap(request.getBytes()));
+
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("my headervalue", context.getTokenValue());
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("and so on", context.getTokenValue());
+
+ res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals("and so on", context.getTokenValue());
+ }
+
+ @Test
+ public void failOnMethodAboveMaxSize() {
+ StringBuilder request = getRandomString(METHOD_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_LINE, context.currentType);
+
+ request = getRandomString(METHOD_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_LINE, context.currentType);
+
+ }
+
+
+ @Test
+ public void successOnMethodAtMaxSize() {
+ StringBuilder request = getRandomString(METHOD_LENGTH).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(METHOD_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void successOnUriAtMaxSize() {
+ StringBuilder request = getRandomString(URI_LENGTH).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_METHOD;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(URI_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnUriAboveMaxSize() {
+ StringBuilder request = getRandomString(URI_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_METHOD;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+
+ request = getRandomString(URI_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_METHOD, context.currentType);
+ }
+
+ @Test
+ public void successOnVersionAtMaxSize() {
+ StringBuilder request = getRandomString(VERSION_LENGTH).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_URI;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(VERSION_LENGTH).toString(),
+ context.getTokenValue());
+ }
+
+ @Test
+ public void failOnVersionAboveMaxSize() {
+ StringBuilder request = getRandomString(VERSION_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.REQUEST_URI;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+
+ request = getRandomString(VERSION_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.REQUEST_URI, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderNameAtMaxSizeFromRequestLine() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH).append(':');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HTTP_VERSION;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_NAME_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderNameAboveMaxSizeFromRequestLine() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HTTP_VERSION;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HTTP_VERSION, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderNameAtMaxSizeFromHeaderValue() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH).append(':');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_NAME_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderNameAboveMaxSizeFromHeaderValue() {
+ StringBuilder request = getRandomString(HEADER_NAME_LENGTH + 1).append(' ');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderValueAtMaxSize() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_NAME;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(HEADER_VALUE_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderValueAboveMaxSize() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH + 1).append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_NAME;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+
+ request = getRandomString(HEADER_NAME_LENGTH + 1);
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_NAME, context.currentType);
+ }
+
+ @Test
+ public void successOnHeaderValueAtMaxSizeOnMultiLine() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH).insert(0, '\t').append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ Assert.assertEquals(request.deleteCharAt(0).deleteCharAt(HEADER_VALUE_LENGTH).toString(), context.getTokenValue());
+ }
+
+ @Test
+ public void failOnHeaderValueAboveMaxSizeOnMultiLine() {
+ StringBuilder request = getRandomString(HEADER_VALUE_LENGTH + 1).insert(0, ' ').append('\r');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ context.currentType = TokenType.HEADER_VALUE;
+ int res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+
+ request = getRandomString(HEADER_VALUE_LENGTH + 1).insert(0, '\t');
+ context.setBuffer(ByteBuffer.wrap(request.toString().getBytes()));
+ res = lexer.nextToken(context);
+ Assert.assertEquals(-1, res);
+ Assert.assertEquals(TokenType.HEADER_VALUE, context.currentType);
+ }
+
+ /**
+ * Generate
+ *
+ * @param length
+ * @return
+ */
+ private StringBuilder getRandomString(int length) {
+
+ StringBuilder stringBuilder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ stringBuilder.append('A');
+ }
+ return stringBuilder;
+ }
+
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpExceptionTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpExceptionTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpExceptionTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpExceptionTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.awf.web.http.HttpException;
+import org.apache.awf.web.http.protocol.HttpStatus;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link HttpException}.
+ */
+public class HttpExceptionTest {
+
+ @Test
+ public void testHttpException() {
+
+ HttpException exception = new HttpException(HttpStatus.SERVER_ERROR_INTERNAL_SERVER_ERROR);
+
+ assertEquals(HttpStatus.SERVER_ERROR_INTERNAL_SERVER_ERROR, exception.getStatus());
+ assertTrue(exception.getMessage().isEmpty());
+ }
+
+ @Test
+ public void testHttpExceptionWithMessage() {
+
+ HttpException exception = new HttpException(HttpStatus.CLIENT_ERROR_NOT_FOUND, "testMessage");
+
+ assertEquals(HttpStatus.CLIENT_ERROR_NOT_FOUND, exception.getStatus());
+ assertEquals("testMessage", exception.getMessage());
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpProtocolTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpProtocolTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpProtocolTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpProtocolTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import com.google.common.collect.Maps;
+
+import org.apache.awf.io.IOLoop;
+import org.apache.awf.util.Closeables;
+import org.apache.awf.web.Application;
+import org.apache.awf.web.handler.RequestHandler;
+import org.apache.awf.web.http.HttpProtocol;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+
+/**
+ *
+ * User: slemesle
+ * Date: 11/09/11
+ * Time: 12:35
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(value = {Closeables.class})
+@PowerMockIgnore("javax.management.*")
+public class HttpProtocolTest {
+
+ private IOLoop ioLoop;
+ private HttpProtocol protocol;
+ private SelectionKey key;
+ private SocketChannel socketChannel;
+
+
+ @Before
+ public void beforeTests(){
+
+ ioLoop = Mockito.mock(IOLoop.class);
+ socketChannel = Mockito.mock(SocketChannel.class);
+ key = new MySelectionKey(socketChannel);
+ PowerMockito.mockStatic(Closeables.class);
+ protocol = new HttpProtocol(ioLoop, new Application(Maps.<String, RequestHandler>newHashMap()));
+ }
+
+ @Test
+ public void testHandleReadReachEOF() throws Exception {
+
+ ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+ key.attach(byteBuffer);
+
+ // See what happens when read returns -1
+ Mockito.when(socketChannel.read(byteBuffer)).thenReturn(-1);
+
+ protocol.handleRead(key);
+
+ Mockito.verify(socketChannel).read(byteBuffer);
+
+ // CloseQuietly should have been called for this channel EOF
+ PowerMockito.verifyStatic(Mockito.times(1));
+ Closeables.closeQuietly(ioLoop, socketChannel);
+ }
+
+
+ /**
+ * Since did not succeed in mocking final fields
+ * here is a short mock for the SelectionKey
+ */
+ class MySelectionKey extends SelectionKey {
+
+ SelectableChannel channel;
+
+ MySelectionKey(SelectableChannel channel) {
+ super();
+ this.channel = channel;
+ }
+
+ @Override
+ public SelectableChannel channel() {
+ return channel;
+ }
+
+ @Override
+ public Selector selector() {
+ return null;
+ }
+
+ @Override
+ public boolean isValid() {
+ return false;
+ }
+
+ @Override
+ public void cancel() {
+ // Nothing Todo
+ }
+
+ @Override
+ public int interestOps() {
+ return 0;
+ }
+
+ @Override
+ public SelectionKey interestOps(int i) {
+ return this;
+ }
+
+ @Override
+ public int readyOps() {
+ return 0;
+ }
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestDispatcherTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestDispatcherTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestDispatcherTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestDispatcherTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.awf.annotation.Asynchronous;
+import org.apache.awf.web.handler.RequestHandler;
+import org.apache.awf.web.http.HttpException;
+import org.apache.awf.web.http.HttpRequest;
+import org.apache.awf.web.http.HttpRequestDispatcher;
+import org.apache.awf.web.http.HttpResponse;
+import org.apache.awf.web.http.protocol.HttpStatus;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link HttpRequestDispatcher}.
+ */
+public class HttpRequestDispatcherTest {
+
+ private class TestRequestHandler extends RequestHandler {
+
+ @Override
+ public void get(HttpRequest request, HttpResponse response) {
+ response.write("get");
+ }
+
+ @Override
+ public void post(HttpRequest request, HttpResponse response) {
+ response.write("post");
+ }
+
+ @Override
+ public void head(HttpRequest request, HttpResponse response) {
+ response.write("head");
+ }
+
+ @Override
+ public void put(HttpRequest request, HttpResponse response) {
+ response.write("put");
+ }
+
+ @Override
+ public void delete(HttpRequest request, HttpResponse response) {
+ response.write("delete");
+ }
+ }
+
+ @Test
+ public void testDispatchForGet() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.GET);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).write("get");
+ }
+
+ @Test
+ public void testDispatchForPost() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.POST);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).write("post");
+ }
+
+ @Test
+ public void testDispatchForHead() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.HEAD);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).write("head");
+ }
+
+ @Test
+ public void testDispatchForPut() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.PUT);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).write("put");
+ }
+
+ @Test
+ public void testDispatchForDelete() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.DELETE);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).write("delete");
+ }
+
+ @Test
+ public void testDispatchForOptions() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.OPTIONS);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(0)).write(anyString());
+ }
+
+ @Test
+ public void testDispatchForTrace() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.TRACE);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(0)).write(anyString());
+ }
+
+ @Test
+ public void testDispatchForConnect() {
+
+ RequestHandler handler = new TestRequestHandler();
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.CONNECT);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(0)).write(anyString());
+ }
+
+ @Test
+ public void testDispatchForHttpException() {
+
+ RequestHandler handler = new TestRequestHandler() {
+ @Override
+ @Asynchronous
+ public void get(HttpRequest request, HttpResponse response) {
+ throw new HttpException(HttpStatus.CLIENT_ERROR_BAD_REQUEST, "testMessage");
+ }
+ };
+
+ HttpRequest request = mock(HttpRequest.class);
+ HttpResponse response = mock(HttpResponse.class);
+
+ when(request.getMethod()).thenReturn(HttpVerb.GET);
+
+ HttpRequestDispatcher.dispatch(handler, request, response);
+ verify(response, times(1)).setStatus(HttpStatus.CLIENT_ERROR_BAD_REQUEST);
+ verify(response, times(1)).write("testMessage");
+ verify(response, times(1)).finish();
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestImplTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestImplTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestImplTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestImplTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import java.util.HashMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HttpRequestImplTest {
+
+ @Test
+ public void testHttpRequestNoQueryString() {
+ String requestLine = "GET /foobar HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String> ());
+ Assert.assertEquals("/foobar", request.getRequestedPath());
+ }
+
+ @Test
+ public void testHttpRequestNullQueryString() {
+ String requestLine = "GET /foobar? HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String>());
+ Assert.assertEquals("/foobar", request.getRequestedPath());
+ }
+
+ @Test
+ public void testHttpRequestNullQueryStringTrailingSlash() {
+ String requestLine = "GET /foobar/? HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String>());
+ Assert.assertEquals("/foobar/", request.getRequestedPath());
+ }
+
+ @Test
+ public void doNotExpectContinueWhenBodyNotEmptyWithExpectHeader(){
+ HttpRequestImpl request = new HttpRequestImpl();
+ request.pushToHeaders("content-length", "12");
+ request.pushToHeaders("expect", "niniin");
+ request.getContentLength();
+ request.getBodyBuffer().put("12345".getBytes());
+ Assert.assertFalse("Expect continue should be false when body is submitted", request.expectContinue());
+
+ }
+
+ @Test
+ public void expectContinueWhenBodyNotNullButEmptyWithExpectHeader(){
+ HttpRequestImpl request = new HttpRequestImpl();
+ request.pushToHeaders("content-length", "12");
+ request.pushToHeaders("expect", "niniin");
+ request.getContentLength();
+ Assert.assertTrue("Expect continue should be false when body bot submitted", request.expectContinue());
+ }
+
+ @Test
+ public void expectContinueWhenBodyNullWithExpectHeader(){
+ HttpRequestImpl request = new HttpRequestImpl();
+ request.pushToHeaders("expect", "niniin");
+ request.getContentLength();
+ Assert.assertTrue("Expect continue should be false when body is submitted", request.expectContinue());
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestParserTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestParserTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestParserTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/HttpRequestParserTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,419 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.awf.util.HttpRequestHelper;
+import org.apache.awf.util.HttpUtil;
+import org.apache.awf.web.http.HttpRequest;
+import org.apache.awf.web.http.HttpRequestImpl;
+import org.apache.awf.web.http.HttpRequestParser;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class HttpRequestParserTest {
+
+
+ private HttpRequestParser parser;
+
+ @Before
+ public void init(){
+ parser = new HttpRequestParser();
+ }
+
+ @Test
+ public void testDeserializeHttpGetRequest() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addHeader("Host", "127.0.0.1:8080");
+ helper.addHeader("User-Agent", "curl/7.19.5 (i386-apple-darwin10.0.0) libcurl/7.19.5 zlib/1.2.3");
+ helper.addHeader("Accept", "*/*");
+ ByteBuffer bb1 = helper.getRequestAsByteBuffer();
+
+ helper = new HttpRequestHelper();
+ helper.addHeader("Host", "127.0.0.1:8080");
+ helper.addHeader("User-Agent",
+ "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; sv-SE; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
+ helper.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ helper.addHeader("Accept-Language", "sv-se,sv;q=0.8,en-us;q=0.5,en;q=0.3");
+ helper.addHeader("Accept-Encoding", "gzip,deflate");
+ helper.addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
+ helper.addHeader("Keep-Alive", "115");
+ helper.addHeader("Connection", "keep-alve");
+ ByteBuffer bb2 = helper.getRequestAsByteBuffer();
+
+ HttpRequest request1 = parser.parseRequestBuffer(bb1);
+ HttpRequest request2 = parser.parseRequestBuffer(bb2);
+
+ assertEquals("GET / HTTP/1.1", request1.getRequestLine());
+ assertEquals("GET / HTTP/1.1", request2.getRequestLine());
+
+ assertEquals(4, request1.getHeaders().size());
+ assertEquals(9, request2.getHeaders().size());
+
+ List<String> expectedHeaderNamesInRequest1 = Arrays.asList(new String[] { "User-Agent", "Host", "Accept",
+ "From" });
+ for (String expectedHeaderName : expectedHeaderNamesInRequest1) {
+ assertTrue(request1.getHeaders().containsKey(expectedHeaderName.toLowerCase()));
+ }
+
+ List<String> expectedHeaderNamesInRequest2 = Arrays.asList(new String[] { "Host", "User-Agent", "Accept",
+ "From", "Accept-Language", "Accept-Encoding", "Accept-Charset", "Keep-Alive", "Connection" });
+ for (String expectedHeaderName : expectedHeaderNamesInRequest2) {
+ assertTrue(request2.getHeaders().containsKey(expectedHeaderName.toLowerCase()));
+ }
+
+ // TODO RS 100920 verify that the headers exist
+ }
+
+
+ @Test
+ public void testSingleGetParameter() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("firstname", "jim");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+
+ assertEquals(1, request.getParameters().size());
+ assertEquals("jim", request.getParameter("firstname"));
+ }
+
+ @Test
+ public void testMultipleGetParameter() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("firstname", "jim");
+ helper.addGetParameter("lastname", "petersson");
+ helper.addGetParameter("city", "stockholm");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(3, getSize(params));
+ assertEquals("jim", request.getParameter("firstname"));
+ assertEquals("petersson", request.getParameter("lastname"));
+ assertEquals("stockholm", request.getParameter("city"));
+ }
+
+ private int getSize(Map<String, Collection<String>> mmap) {
+ int size = 0;
+ for (Collection<String> values : mmap.values()) {
+ size += values.size();
+ }
+ return size;
+ }
+
+ @Test
+ public void testSingleParameterWithoutValue() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("firstname", null);
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+ assertEquals(0, getSize(params));
+ assertEquals(null, request.getParameter("firstname"));
+ }
+
+ @Test
+ public void testMultipleParametersWithoutValue() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("firstname", null);
+ helper.addGetParameter("lastName", "");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(0, getSize(params));
+ assertEquals(null, request.getParameter("firstname"));
+ assertEquals(null, request.getParameter("lastName"));
+ }
+
+ @Test
+ public void testEncodedParametersValue() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("email", "name%40server");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(1, getSize(params));
+ assertEquals("name@server", request.getParameter("email"));
+ }
+
+ @Test
+ public void testMultipleParametersWithAndWithoutValue() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("firstname", null);
+ helper.addGetParameter("lastName", "petersson");
+ helper.addGetParameter("city", "");
+ helper.addGetParameter("phoneno", "12345");
+ helper.addGetParameter("age", "30");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(3, getSize(params));
+ assertEquals(null, request.getParameter("firstname"));
+ assertEquals("petersson", request.getParameter("lastName"));
+ assertEquals(null, request.getParameter("city"));
+ assertEquals("12345", request.getParameter("phoneno"));
+ assertEquals("30", request.getParameter("age"));
+ }
+
+ @Test
+ public void testSingleGetParameterMultipleValues() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("letters", "x");
+ helper.addGetParameter("letters", "y");
+ helper.addGetParameter("letters", "z");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(3, getSize(params));
+ Collection<String> values = params.get("letters");
+ assertEquals(3, values.size());
+ assertTrue(values.contains("x"));
+ assertTrue(values.contains("y"));
+ assertTrue(values.contains("z"));
+ }
+
+ @Test
+ public void testMultipleGetParametersMultipleValues() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("letters", "x");
+ helper.addGetParameter("letters", "y");
+ helper.addGetParameter("letters", "z");
+ helper.addGetParameter("numbers", "23");
+ helper.addGetParameter("numbers", "54");
+ helper.addGetParameter("country", "swe");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(6, getSize(params));
+ Collection<String> letters = params.get("letters");
+ Collection<String> numbers = params.get("numbers");
+ Collection<String> country = params.get("country");
+
+ assertEquals(3, letters.size());
+ assertEquals(2, numbers.size());
+ assertEquals(1, country.size());
+
+ assertTrue(letters.contains("x"));
+ assertTrue(letters.contains("y"));
+ assertTrue(letters.contains("z"));
+
+ assertTrue(numbers.contains("23"));
+ assertTrue(numbers.contains("54"));
+
+ assertTrue(country.contains("swe"));
+ }
+
+ @Test
+ public void testSingleGetParameterMultipleValuesIncludingNull() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("letters", "x");
+ helper.addGetParameter("letters", "y");
+ helper.addGetParameter("letters", null);
+ helper.addGetParameter("letters", "z");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+
+ assertEquals(3, getSize(params));
+ Collection<String> values = params.get("letters");
+ assertEquals(3, values.size());
+ assertTrue(values.contains("x"));
+ assertTrue(values.contains("y"));
+ assertTrue(values.contains("z"));
+ }
+
+ @Test
+ public void testEmptyParameters() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+ assertNotNull(params);
+ assertEquals(0, getSize(params));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testImmutableParameters() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addGetParameter("letter", "x");
+
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ Map<String, Collection<String>> params = request.getParameters();
+ params.put("not", new ArrayList<String>());
+ }
+
+ @Test
+ public void testHostVerification_exists_HTTP_1_0() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.setVersion("1.0");
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ boolean requestOk = HttpUtil.verifyRequest(request);
+ assertTrue(requestOk);
+ }
+
+ @Test
+ public void testHostVerification_nonExisting_HTTP_1_0() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.setVersion("1.0");
+ helper.removeHeader("Host");
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ boolean requestOk = HttpUtil.verifyRequest(request);
+ assertTrue(requestOk);
+ }
+
+ @Test
+ public void testHostVerification_exists_HTTP_1_1() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ boolean requestOk = HttpUtil.verifyRequest(request);
+ assertTrue(requestOk);
+ }
+
+ @Test
+ public void testHostVerification_nonExisting_HTTP_1_1() {
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.removeHeader("Host");
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+ boolean requestOk = HttpUtil.verifyRequest(request);
+ assertFalse(requestOk);
+ }
+
+ @Test
+ public void testGarbageRequest() {
+ HttpRequest request = parser.parseRequestBuffer(ByteBuffer.wrap(new byte[] { 1, 1, 1, 1 } // garbage
+ ));
+ }
+
+ /**
+ * Ensure that header keys are converted to lower case, to facilitate
+ * case-insensitive retrieval through
+ * {@link org.apache.awf.web.http.HttpRequestImpl#getHeader(String)}.
+ */
+ @Test
+ public void testOfConvertsHeaderKeysToLowerCase() {
+
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addHeader("TESTKEY", "unimportant");
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+
+ assertFalse(request.getHeaders().containsKey("TESTKEY"));
+ assertTrue(request.getHeaders().containsKey("testkey"));
+ }
+
+ /**
+ * Ensure that the case of any header values is correctly maintained.
+ */
+ @Test
+ public void testOfMaintainsHeaderValueCase() {
+
+ String expected = "vAlUe";
+
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addHeader("TESTKEY", expected);
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+
+ String actual = request.getHeader("TESTKEY");
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Ensure that case for any key passed to the method is unimportant for its
+ * retrieval.
+ */
+ @Test
+ public void testGetHeader() {
+
+ String expected = "value";
+
+ HttpRequestHelper helper = new HttpRequestHelper();
+ helper.addHeader("TESTKEY", expected);
+ HttpRequest request = parser.parseRequestBuffer(helper.getRequestAsByteBuffer());
+
+ assertEquals(expected, request.getHeader("TESTKEY"));
+ assertEquals(expected, request.getHeader("testkey"));
+ }
+
+ @Test
+ public void testHttpRequestNoQueryString() {
+ String requestLine = "GET /foobar HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String>());
+ Assert.assertEquals("/foobar", request.getRequestedPath());
+ }
+
+ @Test
+ public void testHttpRequestNullQueryString() {
+ String requestLine = "GET /foobar? HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String>());
+ Assert.assertEquals("/foobar", request.getRequestedPath());
+ }
+
+ @Test
+ public void testHttpRequestNullQueryStringTrailingSlash() {
+ String requestLine = "GET /foobar/? HTTP/1.1 ";
+ HttpRequest request = new HttpRequestImpl(requestLine, new HashMap<String, String>());
+ Assert.assertEquals("/foobar/", request.getRequestedPath());
+ }
+
+ @Test
+ public void testNoCookies() {
+ HttpRequestHelper hrh = new HttpRequestHelper();
+ HttpRequest hr = parser.parseRequestBuffer(hrh.getRequestAsByteBuffer());
+ Assert.assertEquals(0, hr.getCookies().size());
+ }
+
+ @Test
+ public void testOneCookie() {
+ HttpRequestHelper hrh = new HttpRequestHelper();
+ hrh.addHeader("Cookie", "one=value");
+ HttpRequest hr = parser.parseRequestBuffer(hrh.getRequestAsByteBuffer());
+ Assert.assertEquals("value", hr.getCookie("one"));
+ }
+
+ @Test
+ public void testOneCookieWithoutValue() {
+ HttpRequestHelper hrh = new HttpRequestHelper();
+ hrh.addHeader("Cookie", "one=");
+ HttpRequest hr = parser.parseRequestBuffer(hrh.getRequestAsByteBuffer());
+ Assert.assertEquals("", hr.getCookie("one"));
+ }
+
+ @Test
+ public void testMultipleCookies() {
+ HttpRequestHelper hrh = new HttpRequestHelper();
+ hrh.addHeader("Cookie", "one=value;two=value2");
+ HttpRequest hr = parser.parseRequestBuffer(hrh.getRequestAsByteBuffer());
+ Assert.assertEquals("value", hr.getCookie("one"));
+ Assert.assertEquals("value2", hr.getCookie("two"));
+ }
+
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/AsynchronousHttpClientTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/AsynchronousHttpClientTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/AsynchronousHttpClientTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/AsynchronousHttpClientTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http.client;
+
+import static org.apache.awf.web.http.client.AsynchronousHttpClient.HTTP_VERSION;
+import static org.apache.awf.web.http.client.AsynchronousHttpClient.NEWLINE;
+import static org.apache.awf.web.http.client.AsynchronousHttpClient.USER_AGENT_HEADER;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.awf.web.AsyncResult;
+import org.apache.awf.web.http.client.AsynchronousHttpClient;
+import org.apache.awf.web.http.client.Response;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link AsynchronousHttpClient}.
+ */
+public class AsynchronousHttpClientTest {
+
+ @Test
+ public void testMakeRequestLineAndHeaders() {
+
+ AsynchronousHttpClient client = new AsynchronousHttpClient() {
+ @Override
+ protected void doFetch(AsyncResult<Response> callback, long requestStarted) {
+ // Do nothing.
+ }
+ };
+
+ client.get("http://testurl.com/path/", null);
+
+ String expected = HttpVerb.GET + " /path/ " + HTTP_VERSION;
+ expected += "Host: testurl.com" + NEWLINE + USER_AGENT_HEADER;
+ expected += NEWLINE;
+
+ String actual = client.makeRequestLineAndHeaders();
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testMakeRequestLineAndHeadersWithBody() {
+
+ AsynchronousHttpClient client = new AsynchronousHttpClient() {
+ @Override
+ protected void doFetch(AsyncResult<Response> callback, long requestStarted) {
+ // Do nothing.
+ }
+ };
+
+ client.post("http://testurl.com/path/", "name=value", null);
+
+ String expected = HttpVerb.POST + " /path/ " + HTTP_VERSION;
+ expected += "Host: testurl.com" + NEWLINE + USER_AGENT_HEADER;
+ expected += "Content-Type: application/x-www-form-urlencoded" + NEWLINE;
+ expected += "Content-Length: 10";
+ expected += NEWLINE + NEWLINE;
+ expected += "name=value";
+ expected += NEWLINE;
+
+ String actual = client.makeRequestLineAndHeaders();
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testMakeRequestLineAndHeadersWithZeroLengthBody() {
+
+ AsynchronousHttpClient client = new AsynchronousHttpClient() {
+ @Override
+ protected void doFetch(AsyncResult<Response> callback, long requestStarted) {
+ // Do nothing.
+ }
+ };
+
+ client.post("http://testurl.com/path/", "", null);
+
+ String expected = HttpVerb.POST + " /path/ " + HTTP_VERSION;
+ expected += "Host: testurl.com" + NEWLINE + USER_AGENT_HEADER;
+ expected += "Content-Type: application/x-www-form-urlencoded" + NEWLINE;
+ expected += "Content-Length: 0";
+ expected += NEWLINE + NEWLINE;
+ expected += NEWLINE;
+
+ String actual = client.makeRequestLineAndHeaders();
+
+ assertEquals(expected, actual);
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/RequestTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/RequestTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/RequestTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/client/RequestTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.apache.awf.web.http.client.Request;
+import org.apache.awf.web.http.protocol.ContentType;
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+
+/**
+ * Test cases for {@link Request}.
+ */
+public class RequestTest {
+
+ @Test
+ public void testRequest() {
+
+ final Request request = new Request("http://testurl.com:8080", HttpVerb.POST, false, 99);
+
+ assertEquals(request.getVerb(), HttpVerb.POST);
+
+ assertEquals("http", request.getURL().getProtocol());
+ assertEquals("testurl.com", request.getURL().getHost());
+ assertEquals(8080, request.getURL().getPort());
+
+ assertEquals(false, request.isFollowingRedirects());
+ assertEquals(99, request.getMaxRedirects());
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void testRequestForMalformedUrl() {
+
+ new Request("malformed", HttpVerb.POST);
+ }
+
+ @Test
+ public void testSetGetBody() {
+
+ final Request request = new Request("http://unimportant-value.com", HttpVerb.POST);
+
+ request.setBody("testContent1");
+ assertTrue(Arrays.equals("testContent1".getBytes(), request.getBody()));
+
+ request.setBody("testContent2".getBytes());
+ assertEquals("testContent2", new String(request.getBody(), Charsets.ISO_8859_1));
+ }
+
+ @Test
+ public void testSetGetContentType() {
+
+ final Request request = new Request("http://unimportant-value.com", HttpVerb.POST);
+ assertEquals(ContentType.APPLICATION_FORM_URLENCODED, request.getContentType());
+
+ request.setContentType(ContentType.MULTIPART_FORM_DATA);
+ assertEquals(ContentType.MULTIPART_FORM_DATA, request.getContentType());
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/ContentTypeTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/ContentTypeTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/ContentTypeTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/ContentTypeTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http.protocol;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.awf.web.http.protocol.ContentType;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link ContentType}.
+ */
+public class ContentTypeTest {
+
+ @Test
+ public void test() throws Exception {
+ assertTrue("No functionality in class to test.", true);
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpStatusTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpStatusTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpStatusTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpStatusTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http.protocol;
+
+import org.apache.awf.web.http.protocol.HttpStatus;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Test cases for {@link HttpStatus}.
+ */
+public class HttpStatusTest {
+
+ private static int STATUS_CODE_COUNT = 38;
+
+ @Test
+ public void testCount() {
+ assertEquals(STATUS_CODE_COUNT, HttpStatus.values().length);
+ }
+
+ @Test
+ public void testCode() {
+
+ for (final HttpStatus status : HttpStatus.values()) {
+ if (status.name().startsWith("SUCCESS")) {
+ assertTrue("Incorrect: " + status.name(), status.code() >= 100 && status.code() < 300);
+ } else if (status.name().startsWith("REDIRECTION")) {
+ assertTrue("Incorrect: " + status.name(), status.code() >= 300 && status.code() < 400);
+ } else if (status.name().startsWith("CLIENT_ERROR")) {
+ assertTrue("Incorrect: " + status.name(), status.code() >= 400 && status.code() < 500);
+ } else if (status.name().startsWith("SERVER_ERROR")) {
+ assertTrue("Incorrect: " + status.name(), status.code() >= 500 && status.code() < 600);
+ } else {
+ assertTrue("Unknown: " + status.name(), false);
+ }
+ }
+ }
+
+ @Test
+ public void testLine() {
+
+ for (final HttpStatus status : HttpStatus.values()) {
+ assertNotNull(status.line());
+ assertTrue("Incorrect: " + status.name(), status.line().startsWith("HTTP/1.1 " + status.code()));
+ }
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpVerbTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpVerbTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpVerbTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/http/protocol/HttpVerbTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.web.http.protocol;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.awf.web.http.protocol.HttpVerb;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link HttpVerb}.
+ */
+public class HttpVerbTest {
+
+ @Test
+ public void testHttpVerb() {
+
+ assertEquals(8, HttpVerb.values().length);
+ }
+}
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/f4_impact_1_original.jpg
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/f4_impact_1_original.jpg?rev=1243316&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/f4_impact_1_original.jpg
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/n792205362_2067.jpg
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/n792205362_2067.jpg?rev=1243316&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/n792205362_2067.jpg
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/test.txt
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/test.txt?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/test.txt (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/resources/test.txt Sun Feb 12 20:24:30 2012
@@ -0,0 +1 @@
+test.txt
\ No newline at end of file
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/.classpath
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/.classpath?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/.classpath (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/.classpath Sun Feb 12 20:24:30 2012
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/.project
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/.project?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/.project (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/.project Sun Feb 12 20:24:30 2012
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>awf-example-gossip</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.jdt.core.prefs?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.jdt.core.prefs (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.jdt.core.prefs Sun Feb 12 20:24:30 2012
@@ -0,0 +1,6 @@
+#Sun Feb 12 15:46:01 GMT 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.m2e.core.prefs
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.m2e.core.prefs?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.m2e.core.prefs (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/.settings/org.eclipse.m2e.core.prefs Sun Feb 12 20:24:30 2012
@@ -0,0 +1,5 @@
+#Sun Feb 12 15:42:01 GMT 2012
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/README
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/README?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/README (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/README Sun Feb 12 20:24:30 2012
@@ -0,0 +1,27 @@
+A "demo framework" for building a decentralized gossip based distributed system with accrual failure
+detection. It's also an implementation of: The Phi Accrual Failure Detector[1] and Amazon's paper on Gossip[2].
+
+[1] http://ddg.jaist.ac.jp/pub/HDY+04.pdf
+[2] http://www.cs.cornell.edu/home/rvr/papers/flowgossip.pdf
+
+External Dependencies needed for this example, not included in the AWF distribution:
+json-simple ("A simple Java toolkit for JSON") http://code.google.com/p/json-simple/ (Apache License 2.0)
+
+Usage:
+
+There are two configuration points (per node), 'seed' and 'address' you need to change before you are ready to start
+your cluster.
+They are located in the MessagingService class. The seed should be a stable node that new nodes will use for bootstrapping
+into the existing cluster. The address is you local ip and port that other nodes in the cluster will connect to.
+Your seed will have seed == address (that is how a seed is defined).
+
+Example 1.
+A two node cluster, running on the same machine
+Node A (seed node). seed = 127.0.0.1:14922, address = 127.0.0.1:14922
+Node B. seed = 127.0.0.1:14922, address = 127.0.0.1:14923
+
+Example 2
+A three node cluster, running on three different machines
+Node A (seed node). seed = 192.168.0.1:14922, address = 192.168.0.1:14922
+Node B. seed = 192.168.0.1:14922, address = 192.168.0.2:14923
+Node C. seed = 192.168.0.1:14922, address = 192.168.0.3:14924
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/pom.xml
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/pom.xml?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/pom.xml (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/pom.xml Sun Feb 12 20:24:30 2012
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the
+ License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.awf</groupId>
+ <artifactId>awf-parent</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ <relativePath>../awf-parent</relativePath>
+ </parent>
+ <artifactId>awf-example-gossip</artifactId>
+
+ <name>Apache AWF Gossip Server Example</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.awf</groupId>
+ <artifactId>awf-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
+
Added: incubator/deft/sandbox/jmeehan/awf-example-gossip/src/main/java/org/apache/awf/example/gossip/FailureDetector.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-example-gossip/src/main/java/org/apache/awf/example/gossip/FailureDetector.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-example-gossip/src/main/java/org/apache/awf/example/gossip/FailureDetector.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-example-gossip/src/main/java/org/apache/awf/example/gossip/FailureDetector.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.awf.example.gossip;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Java implementation of 'The Phi Accrual Failure Detector' by Hayashibara et al.
+ *
+ * Failure detection is the process of determining which nodes in a distributed fault-tolerant system have failed.
+ * Original Phi Accrual Failure Detection paper: http://ddg.jaist.ac.jp/pub/HDY+04.pdf
+ *
+ * A low threshold is prone to generate many wrong suspicions but ensures a quick detection in the event of a real crash.
+ * Conversely, a high threshold generates fewer mistakes but needs more time to detect actual crashes"""
+ *
+ * (Original (python) version by Brandon Williams (github.com/driftx), modified by Roger Schildmeijer
+ * (github.com/rchildmeijer))
+ */
+
+public class FailureDetector {
+
+ private static final int MAX_SAMPLE_SIZE = 1000;
+
+ /**
+ * 1 = 10% error rate, 2 = 1%, 3 = 0.1%.., (eg threshold=3. no heartbeat for >6s => node marked as dead
+ */
+ private static final int THRESHOLD = 3;
+
+ private final Map<String, List<Long>> intervals = Maps.newHashMap();
+ private final Map<String, Map<String, Long>> hosts = Maps.newHashMap();
+ private final Map<String, Long> timestamps = Maps.newHashMap();
+
+ /**
+ * Called when host has indicated being alive (aka heartbeat)
+ * @param host format = "ip:port", eg. "192.168.0.1:14922"
+ */
+ public void heartbeat(String host) {
+ if (!timestamps.containsKey(host)) {
+ timestamps.put(host, System.currentTimeMillis());
+ intervals.put(host, new LinkedList<Long>());
+ hosts.put(host, new HashMap<String, Long>());
+ } else {
+ long now = System.currentTimeMillis();
+ long interval = now - timestamps.get(host);
+ timestamps.put(host, now);
+ intervals.get(host).add(interval);
+ if (intervals.get(host).size() > MAX_SAMPLE_SIZE) {
+ int size = intervals.get(host).size();
+ intervals.get(host).remove(size - 1);
+ }
+ if (intervals.get(host).size() > 1) {
+ long numerator = sum(intervals.get(host));
+ double denominator = intervals.get(host).size();
+ hosts.get(host).put("mean", (long) (numerator / denominator));
+ }
+
+ }
+ }
+
+ private double probability(String host, long timestamp) {
+ double exponent = -1.0 * timestamp / hosts.get(host).get("mean");
+ return 1 - (1.0 - Math.pow(Math.E, exponent));
+ }
+
+ public double phi(String host) {
+ Map<String, Long> means = hosts.get(host);
+ if (/*means == null || */means.isEmpty()) {
+ return 0.0;
+ }
+ long timestamp = System.currentTimeMillis();
+ long diff = timestamp - timestamps.get(host);
+ double prob = probability(host, diff);
+ if (Double.isNaN(prob)) { // is isNaN correct? is isZero would be more correct
+ return Math.pow(1, -128);
+ }
+ return -1 * Math.log10(prob);
+ }
+
+ public boolean isAlive(String host) { return phi(host) < THRESHOLD; }
+
+ public boolean isDead(String host) { return !isAlive(host); }
+
+ private Long sum(List<Long> values) {
+ long sum = 0;
+ for (Long value : values) sum += value;
+ return sum;
+ }
+
+}