incubator-awf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jmee...@apache.org
Subject svn commit: r1243316 [5/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...
Date Sun, 12 Feb 2012 20:24:36 GMT
Added: incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/release-notes.xml
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/release-notes.xml?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/release-notes.xml (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/release-notes.xml Sun Feb 12 20:24:30 2012
@@ -0,0 +1,218 @@
+<?xml-stylesheet type="text/xsl" href="./xdoc.xsl"?>
+	<!--
+		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.
+	-->
+<document>
+	<properties>
+		<title>Apache Deft - Release Notes</title>
+	</properties>
+	<body>
+		<h1>Release Notes - Deft - Version 0.4.0</h1>
+		<h2> Bug
+</h2>
+		<ul>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-98'>DEFT-98</a>
+				] - Infinite loop if client disconnects
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-131'>DEFT-131</a>]
+				- AsynchronousHttpClient.fetch(..) &quot;leaks&quot;
+				IllegalArgumentException if port is out of range
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-144'>DEFT-144</a>
+				] - Improved HTTP headers parsing
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-149'>DEFT-149</a>
+				] - IOLoop.start() may throw CancelledKeyException
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-165'>DEFT-165</a>
+				] - Not injecting the IOLoop into each HttpRequest
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-168'>DEFT-168</a>
+				] - Allow user to specify etag header
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-169'>DEFT-169</a>
+				] - Add write(bytes[] data) method to HttpResponse
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-171'>DEFT-171</a>
+				] - Deft version should be correct in headers. Currently the
+				versions returned vary between client and response; are also
+				hard-coded.
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-173'>DEFT-173</a>
+				] - setReuseAddress(true) in HttpServer
+			</li>
+		</ul>
+
+		<h2> Improvement
+</h2>
+		<ul>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-18'>DEFT-18</a>
+				] - Deft Logo
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-84'>DEFT-84</a>
+				] - Add redirect method to HttpResponse
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-105'>DEFT-105</a>
+				] - Bug fixes and buffer improvements
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-112'>DEFT-112</a>
+				] - Optimized ByteBuffer usage in AsynchronousSocket
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-128'>DEFT-128</a>
+				] - Document the news in 0.3.0 (and 0.4.0)
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-147'>DEFT-147</a>
+				] - Make the etag header creation configurable
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-151'>DEFT-151</a>
+				] - Distributed demo application (elastica)
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-157'>DEFT-157</a>
+				] - Rename package to org.apache.deft
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-158'>DEFT-158</a>
+				] - Cleanup in deft/sandbox
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-159'>DEFT-159</a>
+				] - Recreate the existing tags (from gh)
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-166'>DEFT-166</a>
+				] - Add Javadoc to classes
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-167'>DEFT-167</a>
+				] - Use CharsetDecoder to convert ByteBuffer to String
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-170'>DEFT-170</a>
+				] - Close channel if we (during read) reach EOF and there is nothing
+				to write
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-175'>DEFT-175</a>
+				] - Expand the breadth of demonstration code.
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-177'>DEFT-177</a>
+				] - Update NEWS.txt with DEFT-52 (Cookies)
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-178'>DEFT-178</a>
+				] - Create an Interface between the API user and deft internal
+				plumbing system
+			</li>
+		</ul>
+
+		<h2> New Feature
+</h2>
+		<ul>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-52'>DEFT-52</a>
+				] - Cookies
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-96'>DEFT-96</a>
+				] - RFC 1123 Header Support
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-100'>DEFT-100</a>
+				] - Annotate RequestHandlers
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-117'>DEFT-117</a>
+				] - POST/PUT support in AsynchronousHttpClient
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-138'>DEFT-138</a>
+				] - HTTPS support for AsynchronousHttpClient
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-142'>DEFT-142</a>
+				] - Dynamic creation of RequestHandlers
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-148'>DEFT-148</a>
+				] - wrap AsyncCallbacks
+			</li>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-153'>DEFT-153</a>
+				] - Problems with PUT request
+			</li>
+		</ul>
+
+		<h2> Test
+</h2>
+		<ul>
+			<li>
+				[
+				<a class='externalLink' href='https://issues.apache.org/jira/browse/DEFT-145'>DEFT-145</a>
+				] - Create UT for #139 (multi threaded web server support)
+			</li>
+		</ul>
+	</body>
+</document>

Added: incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/road-map.xml
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/road-map.xml?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/road-map.xml (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/road-map.xml Sun Feb 12 20:24:30 2012
@@ -0,0 +1,46 @@
+<?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.
+	-->
+<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
+	<properties>
+		<title>Apache Deft - Road Map</title>
+	</properties>
+	<body>
+		<section name="Road Map">
+			<p>Development is ongoing, but there are milestone features intended
+				for introduction.</p>
+
+			<subsection name="Current Focus">
+				<p>
+					The work intended for current versions can be reviewed on
+					<a
+						href="https://issues.apache.org/jira/browse/DEFT#selectedTab=com.atlassian.jira.plugin.system.project%3Aroadmap-panel">JIRA</a>
+					.
+				</p>
+			</subsection>
+
+			<subsection name="Previous Versions">
+				<p>
+					Previous versions can also be viewed on JIRA,
+					<a
+						href="https://issues.apache.org/jira/browse/DEFT#selectedTab=com.atlassian.jira.plugin.system.project%3Aversions-panel">here</a>
+					.
+				</p>
+			</subsection>
+		</section>
+	</body>
+</document>

Added: incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/xdoc.xsl
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/xdoc.xsl?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/xdoc.xsl (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/site/xdoc/xdoc.xsl Sun Feb 12 20:24:30 2012
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+	<!--
+		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.
+	-->
+
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+	<xsl:template match="/">
+		<html xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+			<head>
+				<xsl:apply-templates select="/document/properties/title" />
+				<xsl:apply-templates select="/document/meta" />
+				<style type="text/css">
+					@import url("../style/tigris.css");
+					@import
+					url("../style/maven.css");
+					@import url("../style/project.css");
+				</style>
+				<link rel="stylesheet" href="../style/print.css" type="text/css"
+					media="print" />
+			</head>
+			<xsl:apply-templates select="/document/body" />
+		</html>
+	</xsl:template>
+	<xsl:template match="body">
+		<body>
+			<div class="app">
+				<xsl:apply-templates />
+			</div>
+		</body>
+	</xsl:template>
+	<xsl:template match="section">
+		<div>
+			<h3>
+				<xsl:value-of select="@name" />
+			</h3>
+			<xsl:apply-templates />
+		</div>
+	</xsl:template>
+	<xsl:template match="subsection">
+		<div>
+			<h4>
+				<xsl:value-of select="@name" />
+			</h4>
+			<xsl:apply-templates />
+		</div>
+	</xsl:template>
+	<xsl:template match="source">
+		<div id="source">
+			<pre>
+				<xsl:apply-templates />
+			</pre>
+		</div>
+	</xsl:template>
+	<xsl:template match="node()|@*">
+		<xsl:copy>
+			<xsl:apply-templates select="@*" />
+			<xsl:apply-templates />
+		</xsl:copy>
+	</xsl:template>
+</xsl:stylesheet>

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/AnnotationsScannerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/AnnotationsScannerTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/AnnotationsScannerTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/AnnotationsScannerTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,61 @@
+/*
+ *  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.configuration;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.apache.awf.configuration.AnnotationsScanner;
+import org.apache.awf.web.handler.RequestHandler;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link AnnotationsScanner}.
+ */
+public class AnnotationsScannerTest {
+
+    @Test
+    public void testFindHandlers() {
+
+        AnnotationsScanner scanner = new AnnotationsScanner();
+        Map<String, RequestHandler> handlers = scanner.findHandlers("org.apache.awf.example.handler");
+
+        assertEquals(4, handlers.size());
+    }
+
+    @Test
+    public void testFindHandlersForBadPath() {
+
+        AnnotationsScanner scanner = new AnnotationsScanner();
+        Map<String, RequestHandler> handlers = scanner.findHandlers("org.does.not.exist");
+
+        assertEquals(0, handlers.size());
+    }
+
+    @Test
+    public void testFindHandlersForEmptyPath() {
+
+        AnnotationsScanner scanner = new AnnotationsScanner();
+        Map<String, RequestHandler> handlers = scanner.findHandlers(null);
+
+        assertEquals(0, handlers.size());
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/ConfigurationTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/ConfigurationTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/ConfigurationTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/configuration/ConfigurationTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,74 @@
+/*
+ *  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.configuration;
+
+import static org.apache.awf.configuration.Configuration.DEFAULT_STATIC_DIRECTORY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.awf.configuration.Configuration;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link Configuration}.
+ */
+public class ConfigurationTest {
+
+    @Test
+    public void testGetHandlerPackage() {
+
+        Configuration configuration = new Configuration();
+
+        assertTrue(configuration.getHandlerPackage().isEmpty());
+
+        configuration.setHandlerPackage("org.apache.awf");
+        assertEquals("org.apache.awf", configuration.getHandlerPackage());
+    }
+
+    @Test
+    public void testGetStaticDirectory() {
+
+        Configuration configuration = new Configuration();
+
+        configuration.setStaticDirectory(null);
+        assertEquals(DEFAULT_STATIC_DIRECTORY, configuration.getStaticDirectory());
+
+        configuration.setStaticDirectory("  ");
+        assertEquals(DEFAULT_STATIC_DIRECTORY, configuration.getStaticDirectory());
+
+        configuration.setStaticDirectory("");
+        assertEquals(DEFAULT_STATIC_DIRECTORY, configuration.getStaticDirectory());
+
+        configuration.setStaticDirectory("files");
+        assertEquals("files", configuration.getStaticDirectory());
+    }
+
+    @Test
+    public void testShouldCreateETags() {
+
+        Configuration configuration = new Configuration();
+
+        assertFalse(configuration.shouldCreateETags());
+
+        configuration.setCreateETags(true);
+        assertTrue(configuration.shouldCreateETags());
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/AsynchronousSocketTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/AsynchronousSocketTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/AsynchronousSocketTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/AsynchronousSocketTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,178 @@
+/*
+ *  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.io;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.awf.io.AsynchronousSocket;
+import org.apache.awf.io.IOLoop;
+import org.apache.awf.web.AsyncCallback;
+import org.apache.awf.web.AsyncResult;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class AsynchronousSocketTest {
+
+    public static final String HOST = "localhost";
+    public static final int PORT = 6228;
+
+    @Before
+    public void setup() throws InterruptedException {
+        // start the IOLoop from a new thread so we dont block this test.
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                IOLoop.INSTANCE.start();
+            }
+        }).start();
+        Thread.sleep(300); // hack to avoid SLF4J warning
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                DataInputStream is = null;
+                DataOutputStream os = null;
+                try {
+                    System.out.println("waiting for client...");
+                    ServerSocket server = new ServerSocket(PORT);
+                    latch.countDown();
+                    Socket client = server.accept();
+                    System.out.println("client connected..");
+                    is = new DataInputStream(client.getInputStream());
+                    os = new DataOutputStream(client.getOutputStream());
+
+                    String recevied = is.readLine();
+                    System.out.println("about to send: " + recevied);
+                    os.writeBytes(recevied.toUpperCase());
+                    System.out.println("sent data to client, shutdown server...");
+                    server.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    closeQuietly(is, os);
+                }
+            }
+        }).start();
+
+        latch.await(5, TimeUnit.SECONDS);
+    }
+
+    @After
+    public void tearDown() throws InterruptedException {
+        IOLoop.INSTANCE.addCallback(new AsyncCallback() {
+            @Override
+            public void onCallback() {
+                IOLoop.INSTANCE.stop();
+            }
+        });
+        Thread.sleep(300); // give the IOLoop thread some time to gracefully
+                           // shutdown
+    }
+
+    private void closeQuietly(InputStream is, OutputStream os) {
+        try {
+            if (is != null) {
+                is.close();
+            }
+            if (os != null) {
+                os.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private final AsynchronousSocket socket;
+    private final CountDownLatch latch = new CountDownLatch(3); // 3
+                                                                // op/callbacks
+                                                                // (connect,
+                                                                // write, read)
+
+    public AsynchronousSocketTest() throws IOException {
+        socket = new AsynchronousSocket(SocketChannel.open());
+    }
+
+    @Test
+    public void connectWriteAndReadCallbackTest() throws InterruptedException, IOException {
+        AsyncResult<Boolean> ccb = new AsyncResult<Boolean>() {
+            public void onFailure(Throwable caught) {
+            }
+
+            public void onSuccess(Boolean result) {
+                onConnect();
+            }
+        };
+        socket.connect(HOST, PORT, ccb);
+
+        latch.await(20, TimeUnit.SECONDS);
+
+        assertEquals(0, latch.getCount());
+        // TODO stop ioloop
+    }
+
+    private void onConnect() {
+        latch.countDown();
+        AsyncCallback wcb = new AsyncCallback() {
+            @Override
+            public void onCallback() {
+                onWriteComplete();
+            }
+        };
+        socket.write("roger|\r\n".getBytes(), wcb);
+    }
+
+    private void onWriteComplete() {
+        latch.countDown();
+        AsyncResult<byte[]> rcb = new AsyncResult<byte[]>() {
+            @Override
+            public void onFailure(Throwable caught) {
+                assertTrue(false);
+            }
+
+            @Override
+            public void onSuccess(byte[] result) {
+                onReadComplete(new String(result));
+            }
+        };
+        socket.readUntil("|".getBytes(), rcb);
+    }
+
+    private void onReadComplete(String result) {
+        if ("ROGER".equals(result)) {
+            latch.countDown();
+        }
+        assertEquals("ROGER", result);
+    }
+
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/buffer/DynamicByteBufferTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/buffer/DynamicByteBufferTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/buffer/DynamicByteBufferTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/buffer/DynamicByteBufferTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,103 @@
+/*
+ *  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.io.buffer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.awf.io.buffer.DynamicByteBuffer;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DynamicByteBufferTest {
+
+	private DynamicByteBuffer dbb;
+	private static final int INITIAL_CAPACITY = 10;	// bytes
+	
+	@Before
+	public void allocation() {
+		this.dbb = DynamicByteBuffer.allocate(INITIAL_CAPACITY);
+	}
+	
+	@Test
+	public void testAllocation() {
+		assertInternalState(INITIAL_CAPACITY, 0, INITIAL_CAPACITY, INITIAL_CAPACITY);
+	}
+	
+	private void assertInternalState(int expectedCapacity, int expectedPosition, int expectedLimit, int arrayLength) {
+		assertEquals(expectedCapacity, dbb.capacity());
+		assertEquals(expectedPosition, dbb.position());
+		assertEquals(expectedLimit, dbb.limit());
+		assertEquals(arrayLength, dbb.array().length);
+	}
+	
+	@Test
+	public void testNoReallactionPut() {
+		byte[] data = new byte[] {'q', 'w', 'e', 'r', 't', 'y'};
+		dbb.put(data);
+		assertInternalState(INITIAL_CAPACITY, data.length, INITIAL_CAPACITY, INITIAL_CAPACITY);
+	}
+	
+	@Test
+	public void testReallocationTriggeredPut() {
+		byte[] data = new byte[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A'};
+		dbb.put(data);
+		assertInternalState(16, 11, 16, 16);
+		
+		dbb.put(data);
+		assertInternalState(33, 22, 33, 33);
+		
+		dbb.put(data);
+		dbb.put(data);
+		assertInternalState(66, 44, 66, 66);
+	}
+	
+	@Test
+	public void testPrepend() {
+		byte[] data = new byte[] {'[', 'q', 'w', 'e', 'r', 't', 'y', ']'};
+		dbb.put(data);
+		
+		String initial = "|HTTP/1.1 200 OK|";
+		int initialLength = initial.length();
+		dbb.prepend(initial);
+		
+		int expectedCapacity = data.length + initialLength;
+		int expectedPosition = data.length + initialLength;
+		int expectedLimit 	 = data.length + initialLength;
+		int arrayLength 	 = data.length + initialLength;
+		assertInternalState(expectedCapacity, expectedPosition, expectedLimit, arrayLength);
+		
+		dbb.put(data);
+		expectedCapacity = 49;	
+		expectedPosition += data.length;
+		expectedLimit 	 = 49;
+		arrayLength 	 = 49;
+		assertInternalState(expectedCapacity, expectedPosition, expectedLimit, arrayLength);
+	}
+
+	@Test
+	public void testReallocationLimit() {
+		byte[] data = "0123456".getBytes();
+		dbb.put(data);
+		assertInternalState(10, 7, 10, 10);
+		dbb.put("0123456789".getBytes());
+		assertInternalState(25, 17, 25, 25);
+	}
+	
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/JMXDebuggableCallbackManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/JMXDebuggableCallbackManagerTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/JMXDebuggableCallbackManagerTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/JMXDebuggableCallbackManagerTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,121 @@
+/*
+ *  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.io.callback;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.awf.io.callback.JMXDebuggableCallbackManager;
+import org.apache.awf.web.AsyncCallback;
+import org.junit.Test;
+
+
+public class JMXDebuggableCallbackManagerTest {
+	
+	private final JMXDebuggableCallbackManager cm = new JMXDebuggableCallbackManager();
+	
+	@Test
+	public void simpleJMXDeubggableCallbackManagerTest() {
+		final CountDownLatch latch = new CountDownLatch(3);
+		
+		final AsyncCallback cb1 = new AsyncCallback() {
+			@Override
+			public void onCallback() { latch.countDown(); }
+		};
+		
+		final AsyncCallback cb2 = new AsyncCallback() {
+			@Override
+			public void onCallback() { latch.countDown(); }
+		};
+		
+		final AsyncCallback cb3 = new AsyncCallback() {
+			@Override
+			public void onCallback() { 
+				latch.countDown();
+				cm.addCallback(cb1); 	// adding a new callback that should be scheduled for execution 
+										// during the next iteration (i.e next call to execute)
+			}
+		};
+		
+		cm.addCallback(cb1);
+		cm.addCallback(cb2);
+		cm.addCallback(cb3);
+		
+		assertEquals(3, cm.getNumberOfCallbacks());
+		
+		boolean pending = cm.execute();
+		
+		assertEquals(true, pending);
+		assertEquals(1, cm.getNumberOfCallbacks());
+		assertEquals(0, latch.getCount());
+	}
+	
+	@Test
+	public void concurrencyTest() {
+		final int nThreads = 25;
+		final int n = 20 * 1000;
+		final int[] exceptionThrown = {0};
+		Runnable ioLoopTask = new Runnable() {
+			
+			public void run() { 
+				try {
+					cm.execute(); 
+				} catch (Exception e) {
+					exceptionThrown[0] = 1;
+				}
+			}
+			
+		};
+
+		ScheduledExecutorService ioLoop = Executors.newSingleThreadScheduledExecutor();
+		ioLoop.scheduleAtFixedRate(ioLoopTask, 0, 1, TimeUnit.MILLISECONDS);
+
+		final CountDownLatch latch = new CountDownLatch(n);
+		ScheduledExecutorService workerThreads = Executors.newScheduledThreadPool(nThreads);
+		Runnable work = new Runnable() { 
+
+			public void run() { 
+				cm.addCallback(AsyncCallback.nopCb); 
+				latch.countDown();
+			}
+
+		};
+
+		for (int i = 0; i < 25; i++) {
+			workerThreads.scheduleWithFixedDelay(work, 0, 1, TimeUnit.MILLISECONDS);
+		}
+
+		try {
+			latch.await(10, TimeUnit.SECONDS);
+		} catch (InterruptedException e) {
+			assertTrue(false);
+		}
+		assertEquals(0, latch.getCount());
+		assertEquals(0, exceptionThrown[0]);
+		ioLoop.shutdownNow();
+		workerThreads.shutdownNow();
+	}
+
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/PeriodicCallbackTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/PeriodicCallbackTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/PeriodicCallbackTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/callback/PeriodicCallbackTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,58 @@
+/*
+ *  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.io.callback;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.awf.io.IOLoop;
+import org.apache.awf.io.callback.PeriodicCallback;
+import org.apache.awf.web.AsyncCallback;
+import org.junit.Test;
+
+public class PeriodicCallbackTest {
+	
+	@Test
+	public void testPeriodicCallback() throws InterruptedException {
+		// start the IOLoop from a new thread so we dont block this test.
+		new Thread(new Runnable() {
+
+			@Override public void run() { IOLoop.INSTANCE.start(); }
+		
+		}).start();
+		
+		final CountDownLatch latch = new CountDownLatch(200);
+		long period = 10; // 10ms (=> ~100times / s)
+		AsyncCallback cb = new AsyncCallback() {
+			@Override public void onCallback() { latch.countDown(); }
+		};
+		final PeriodicCallback pcb = new PeriodicCallback(cb, period);
+		IOLoop.INSTANCE.addCallback(new AsyncCallback() { public void onCallback() { pcb.start(); }});
+		
+		latch.await(5, TimeUnit.SECONDS);
+		pcb.cancel();
+		IOLoop.INSTANCE.stop();
+		// TODO wait?
+		assertEquals(0, latch.getCount());
+	}
+	
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/JMXDebuggableTimeoutManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/JMXDebuggableTimeoutManagerTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/JMXDebuggableTimeoutManagerTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/JMXDebuggableTimeoutManagerTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,213 @@
+/*
+ *  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.io.timeout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Map;
+
+import org.apache.awf.io.timeout.JMXDebuggableTimeoutManager;
+import org.apache.awf.io.timeout.Timeout;
+import org.apache.awf.web.AsyncCallback;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class JMXDebuggableTimeoutManagerTest {
+
+	private final JMXDebuggableTimeoutManager tm = new JMXDebuggableTimeoutManager();
+	
+	@Test
+	public void timeoutManagerTest() throws InterruptedException {
+		final long now = System.currentTimeMillis();
+		MockChannel c1 = new MockChannel();
+		MockChannel c2 = new MockChannel();
+		MockChannel c3 = new MockChannel();
+
+		addNopTimeout(now);
+		addNopTimeout(now);
+		addNopTimeout(now);
+		addNopTimeout(now+1);
+		addNopTimeout(now+2);
+		addNopTimeout(now+1000);
+		addNopTimeout(now+1200);
+		addNopTimeout(now+1400);
+		
+		addNopKeepAliveTimeout(c1, now);
+		addNopKeepAliveTimeout(c2, now);
+		addNopKeepAliveTimeout(c3, now+1);
+		
+		assertEquals(11, tm.getNumberOfTimeouts());
+		assertEquals(3, tm.getNumberOfKeepAliveTimeouts());
+
+		Thread.sleep(200);
+	
+		tm.execute();
+		assertEquals(3, tm.getNumberOfTimeouts());
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts());
+	
+		Thread.sleep(2000);
+		tm.execute();
+		assertEquals(0, tm.getNumberOfTimeouts());
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts());
+	}
+	
+	private void addNopTimeout(long timeout) {
+		tm.addTimeout(new Timeout(timeout, new AsyncCallback() {
+			@Override public void onCallback() { /*nop*/}
+		}));	
+	}
+
+	private void addNopKeepAliveTimeout(SelectableChannel channel, long timeout) {
+		tm.addKeepAliveTimeout(channel, new Timeout(timeout, new AsyncCallback() {
+			@Override public void onCallback() { /*nop*/ }
+		}));
+	}
+	
+	@Test
+	public void addTimeoutDuringTimeoutExecution() throws InterruptedException {
+		final long now = System.currentTimeMillis();
+		addRecursiveTimeout(now);
+		addRecursiveTimeout(now+10);
+		addRecursiveTimeout(now+20);
+		
+		assertEquals(3, tm.getNumberOfTimeouts());
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts());
+
+		Thread.sleep(50);
+		long ms = tm.execute();
+		assertTrue(ms != Long.MAX_VALUE);
+		
+		assertEquals(3, tm.getNumberOfTimeouts());
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts());
+		
+		Thread.sleep(50);
+		tm.execute();
+		Thread.sleep(50);
+		tm.execute();
+		Thread.sleep(50);
+		tm.execute();
+		
+		assertEquals(0, tm.getNumberOfTimeouts());
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts());
+	}
+	
+	private void addRecursiveTimeout(final long timeout) {
+		final Timeout t = new Timeout(timeout, new AsyncCallback() {
+			@Override public void onCallback() { addNopTimeout(System.currentTimeMillis()); }
+		});
+		tm.addTimeout(t);	
+	}
+	
+	private class MockChannel extends SelectableChannel {
+
+		@Override
+		public Object blockingLock() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public SelectableChannel configureBlocking(boolean block)
+		throws IOException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public boolean isBlocking() {
+			// TODO Auto-generated method stub
+			return false;
+		}
+
+		@Override
+		public boolean isRegistered() {
+			// TODO Auto-generated method stub
+			return false;
+		}
+
+		@Override
+		public SelectionKey keyFor(Selector sel) {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public SelectorProvider provider() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public SelectionKey register(Selector sel, int ops, Object att)
+		throws ClosedChannelException {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		@Override
+		public int validOps() {
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		@Override
+		protected void implCloseChannel() throws IOException {
+			// TODO Auto-generated method stub
+
+		}
+		
+	}
+	
+	@Test
+	public void testAddTimeoutsThatHasTheSameDeadline() throws InterruptedException {
+		assertEquals(0, tm.getNumberOfKeepAliveTimeouts() + tm.getNumberOfTimeouts());
+		final int N = 1000;
+		final long now = System.currentTimeMillis();
+		final Map<Integer, Boolean> register = Maps.newHashMap();
+		for (int i = 0; i < N; i++) {
+			final int j = i;
+			Timeout t = new Timeout(
+					now + 10, 
+					new AsyncCallback() { public void onCallback() { register.put(j, true); }}
+			);
+			register.put(j, false);
+			tm.addTimeout(t);
+		}
+		assertEquals(N, register.size());
+		assertEquals(N, tm.getNumberOfTimeouts());
+		
+		Thread.sleep(100);
+		tm.execute();
+		assertEquals(N, register.size());
+		assertEquals(0, tm.getNumberOfTimeouts());
+		for (Boolean timeoutTriggered: register.values()) {
+			assertTrue(timeoutTriggered);
+		}
+	}
+
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/TimeoutTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/TimeoutTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/TimeoutTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/io/timeout/TimeoutTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,56 @@
+/*
+ *  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.io.timeout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.awf.io.timeout.Timeout;
+import org.apache.awf.web.AsyncCallback;
+import org.junit.Test;
+
+public class TimeoutTest {
+
+	@Test
+	public void simpleTimeoutConstructorTest() {
+		final AsyncCallback cb = new AsyncCallback() {
+			@Override public void onCallback() {}
+		};
+		
+		Timeout t = new Timeout(1492, cb);
+
+		assertEquals(1492, t.getTimeout());
+		assertEquals(cb, t.getCallback());
+	}
+	
+	@Test
+	public void timeoutCancelledTest() {
+		final long now = System.currentTimeMillis();
+		final AsyncCallback cb = new AsyncCallback() { @Override public void onCallback() { /*nop*/} };
+		Timeout t1 = new Timeout(now + 2000, cb);
+		assertTrue(t1.getCallback() == cb);
+
+		t1.cancel();
+		
+		assertTrue(t1.getCallback() != cb);
+		assertTrue(t1.isCancelled());
+	}
+	
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/DateUtilTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/DateUtilTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/DateUtilTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/DateUtilTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,69 @@
+/*
+ *  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.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Date;
+
+import org.apache.awf.util.DateUtil;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link DateUtil}.
+ */
+public class DateUtilTest {
+
+    @Test
+    public void testParseToMillisecondsForLong() {
+
+        final long actual = DateUtil.parseToMilliseconds("123");
+        assertEquals(123, actual);
+    }
+
+    @Test
+    public void testParseToMillisecondsForRFC1123String() {
+
+        final long actual = DateUtil.parseToMilliseconds("Sat, 20 Feb 2010 18:12:38 GMT");
+        assertEquals(1266689558000L, actual);
+    }
+
+    @Test
+    public void testParseToMillisecondsForInvalidString() {
+
+        final long actual = DateUtil.parseToMilliseconds("INVALID");
+        assertEquals(0, actual);
+    }
+
+    @Test
+    public void testParseToRFC1123() {
+
+        final String actual = DateUtil.parseToRFC1123(1266689558000L);
+        assertEquals("Sat, 20 Feb 2010 18:12:38 GMT", actual);
+    }
+
+    @Test
+    public void testGetDateAsString() {
+
+        Date date = new Date(1266689558000L);
+        String actual = DateUtil.getDateAsString(date);
+        assertEquals("Sat, 20 Feb 2010 18:12:38 GMT", actual);
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/HttpRequestHelper.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/HttpRequestHelper.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/HttpRequestHelper.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/HttpRequestHelper.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,165 @@
+/*
+ *  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.util;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * This class can be used to create HttpRequests (and corresponding byte
+ * representations)
+ */
+public class HttpRequestHelper {
+
+    // Default request will look like this:
+    /*
+     * GET / HTTP/1.0 Host: localhost:8080 User-Agent: Mozilla/5.0 From:
+     * abcde@qwert.com
+     */
+
+    enum ParameterDelimMode {
+        AMPERSAND, SEMICOLON, MIXED
+    }
+
+    private ParameterDelimMode paramDelimMode = ParameterDelimMode.MIXED;
+
+    private String protocol = "HTTP";
+    private String method = "GET";
+    private String version = "1.1";
+    private String requestedPath = "/";
+    private Map<String, String> headers = new HashMap<String, String>();
+    private Multimap<String, String> getParameters = HashMultimap.create();
+
+    public HttpRequestHelper() {
+        headers.put("Host", "localhost:8080");
+        headers.put("User-Agent", "Mozilla/5.0");
+        headers.put("From", "abcde@qwert.com");
+    }
+
+    public String getRequestAsString() {
+        String requestLine = createRequestLine();
+        String headerString = createHeaders();
+        // TODO Body
+        String request = requestLine + headerString;
+        return request;
+    }
+
+    public byte[] getRequestAsBytes() {
+        String request = getRequestAsString();
+        return request.getBytes();
+    }
+
+    public ByteBuffer getRequestAsByteBuffer() {
+        return ByteBuffer.wrap(getRequestAsBytes());
+    }
+
+    public String addHeader(String name, String value) {
+        return headers.put(name, value);
+    }
+
+    public String removeHeader(String name) {
+        return headers.remove(name);
+    }
+
+    public boolean addGetParameter(String name, String value) {
+        return getParameters.put(name, value);
+    }
+
+    public void setRequestedPath(String path) {
+        requestedPath = path;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public void setParameterDelimMode(ParameterDelimMode mode) {
+        paramDelimMode = mode;
+    }
+
+    private String getParameterDelimiter() {
+        String delim;
+        switch (paramDelimMode) {
+        case AMPERSAND:
+            delim = "&";
+            break;
+        case SEMICOLON:
+            delim = ";";
+            break;
+        case MIXED:
+            if (Math.random() > 0.5) {
+                delim = "&";
+            } else {
+                delim = ";";
+            }
+            break;
+        default:
+            delim = ";";
+        }
+        return delim;
+    }
+
+    /**
+     * Creates the initial request line, i.e: GET / HTTP/1.0
+     * 
+     * It also add \r\n to the end of the line
+     */
+    private String createRequestLine() {
+        String requestedPathWithParams = requestedPath;
+
+        if (!getParameters.isEmpty()) { // Add get parameters
+            requestedPathWithParams += "?";
+            for (String paramName : getParameters.keySet()) {
+                String delimiter = getParameterDelimiter();
+                Collection<String> values = getParameters.get(paramName);
+                for (String value : values) { // A single param can have
+                                              // multiple values
+                    String val = value == null ? "" : value;
+                    requestedPathWithParams += paramName + "=" + val + delimiter;
+                }
+            }
+            // Remove last &
+            requestedPathWithParams = requestedPathWithParams.substring(0, requestedPathWithParams.length() - 1);
+        }
+        String reqLine = method + " " + requestedPathWithParams + " " + protocol + "/" + version + "\r\n";
+        return reqLine;
+    }
+
+    /**
+     * Creates the header lines, i.e: Host: localhost:8080 User-Agent:
+     * Mozilla/5.0 From: abcde@qwert.com
+     * 
+     * It also add \r\n to the end of the line
+     */
+    private String createHeaders() {
+        String result = "";
+        for (String headerKey : headers.keySet()) {
+            String headerValue = headers.get(headerKey);
+            result += headerKey + ": " + headerValue + "\r\n";
+        }
+        result += "\r\n";
+        return result;
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/ReflectionToolsTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/ReflectionToolsTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/ReflectionToolsTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/ReflectionToolsTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,40 @@
+/*
+ *  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.util;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.awf.util.ReflectionTools;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link ReflectionTools}.
+ */
+public class ReflectionToolsTest {
+
+    @Test
+    public void testCreateInstance() {
+
+        Object created = ReflectionTools.createInstance(ReflectionToolsTest.class.getCanonicalName());
+        assertNotNull(created);
+        assertTrue(created instanceof ReflectionToolsTest);
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/UrlUtilTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/UrlUtilTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/UrlUtilTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/util/UrlUtilTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,39 @@
+/*
+ *  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.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.awf.util.UrlUtil;
+import org.junit.Test;
+
+public class UrlUtilTest {
+
+    @Test
+    public void urlJoinTest() throws MalformedURLException {
+        assertEquals("http://tt.se/start/", UrlUtil.urlJoin(new URL("http://tt.se/"), "/start/"));
+        assertEquals("http://localhost.com/", UrlUtil.urlJoin(new URL("http://localhost.com/moved_perm"), "/"));
+        assertEquals("https://github.com/", UrlUtil.urlJoin(new URL("http://github.com/"), "https://github.com/"));
+    }
+
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/ApplicationTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/ApplicationTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/ApplicationTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/ApplicationTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,150 @@
+/*
+ *  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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.awf.web.Application;
+import org.apache.awf.web.handler.BadRequestRequestHandler;
+import org.apache.awf.web.handler.NotFoundRequestHandler;
+import org.apache.awf.web.handler.RequestHandler;
+import org.apache.awf.web.http.HttpRequest;
+import org.apache.awf.web.http.HttpRequestImpl;
+import org.apache.awf.web.http.HttpResponse;
+import org.junit.Test;
+
+public class ApplicationTest {
+
+    @Test
+    public void simpleApplicationTest() {
+        Map<String, RequestHandler> handlers = new HashMap<String, RequestHandler>();
+        final RequestHandler handler1 = new RequestHandler() {
+            @Override
+            public void get(HttpRequest request, HttpResponse response) {
+            }
+        };
+        final RequestHandler handler2 = new RequestHandler() {
+            @Override
+            public void get(HttpRequest request, HttpResponse response) {
+            }
+        };
+        final RequestHandler handler3 = new RequestHandler() {
+            @Override
+            public void get(HttpRequest request, HttpResponse response) {
+            }
+        };
+        final RequestHandler handler4 = new RequestHandler() {
+            @Override
+            public void get(HttpRequest request, HttpResponse response) {
+            }
+        };
+
+        handlers.put("/", handler1);
+        handlers.put("/persons/([0-9]+)", handler2);
+        handlers.put("/persons/phone_numbers", handler3);
+        handlers.put("/pets/([0-9]{0,3})", handler4);
+        Application app = new Application(handlers);
+
+        String requestLine = "GET / HTTP/1.1";
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put("host", "localhost");
+        HttpRequest request = new HttpRequestImpl(requestLine, headers);
+
+        assertNotNull(app.getHandler(request));
+
+        requestLine = "GET /persons/1911 HTTP/1.1";
+        request = new HttpRequestImpl(requestLine, headers);
+        assertNotNull(app.getHandler(request));
+
+        requestLine = "GET /persons/phone_numbers HTTP/1.1";
+        request = new HttpRequestImpl(requestLine, headers);
+        assertNotNull(app.getHandler(request));
+
+        requestLine = "GET /pets/123 HTTP/1.1";
+        request = new HttpRequestImpl(requestLine, headers);
+        assertNotNull(app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /missing HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /persons HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /persons/roger HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /persons/123a HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /persons/a123 HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /pets/a123 HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /pets/123a HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET /pets/1234 HTTP/1.1", headers);
+        assertEquals(NotFoundRequestHandler.getInstance(), app.getHandler(request));
+
+        request = new HttpRequestImpl("GET / HTTP/1.1", headers);
+        assertFalse(handler1.equals(app.getHandler(request)));
+        assertEquals(handler1.getClass(), app.getHandler(request).getClass());
+
+        request = new HttpRequestImpl("GET /persons/1911 HTTP/1.1", headers);
+        assertFalse(handler2.equals(app.getHandler(request)));
+        assertEquals(handler2.getClass(), app.getHandler(request).getClass());
+
+        request = new HttpRequestImpl("GET /persons/phone_numbers HTTP/1.1", headers);
+        assertFalse(handler3.equals(app.getHandler(request)));
+        assertEquals(handler3.getClass(), app.getHandler(request).getClass());
+
+        request = new HttpRequestImpl("GET /pets/123 HTTP/1.1", headers);
+        assertFalse(handler4.equals(app.getHandler(request)));
+        assertEquals(handler4.getClass(), app.getHandler(request).getClass());
+
+        // Verify that BadRequestRequestHandler is returned if request does not
+        // include Host header
+        headers = new HashMap<String, String>();
+        request = new HttpRequestImpl("GET /pets/123 HTTP/1.1", headers);
+        assertEquals(BadRequestRequestHandler.getInstance(), app.getHandler(request));
+
+    }
+
+    @Test(expected = PatternSyntaxException.class)
+    public void malFormedRegularExpressionTest() {
+        Map<String, RequestHandler> handlers = new HashMap<String, RequestHandler>();
+        final RequestHandler handler1 = new RequestHandler() {
+            @Override
+            public void get(HttpRequest request, HttpResponse response) {
+            }
+        };
+
+        handlers.put("/persons/([[0-9]{0,3})", handler1);
+        new Application(handlers);
+    }
+}

Added: incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/HttpServerTest.java
URL: http://svn.apache.org/viewvc/incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/HttpServerTest.java?rev=1243316&view=auto
==============================================================================
--- incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/HttpServerTest.java (added)
+++ incubator/deft/sandbox/jmeehan/awf-core/src/test/java/org/apache/awf/web/HttpServerTest.java Sun Feb 12 20:24:30 2012
@@ -0,0 +1,90 @@
+/*
+ *  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;
+
+import org.apache.awf.configuration.Configuration;
+import org.apache.awf.io.IOLoop;
+import org.apache.awf.web.Application;
+import org.apache.awf.web.HttpServer;
+import org.apache.awf.web.handler.RequestHandler;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+
+/**
+ * Test cases for {@link HttpServer}.
+ */
+public class HttpServerTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPortInRange_low() {
+        int port = 0;
+        HttpServer server = createServer();
+        server.listen(port);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPortInRange_high() {
+        int port = 65536;
+        HttpServer server = createServer();
+        server.listen(port);
+    }
+
+    @Test
+    public void testPortInRange_ok() {
+        int port = 8084;
+        HttpServer server = createServer();
+        server.listen(port);
+    }
+
+
+    @Test
+    public void multiThreadServerStartStop(){
+        int port = 8181;
+        HttpServer server = createServer();
+        server.bind(port);
+        server.start(3);
+
+        org.junit.Assert.assertEquals(3, server.getIoLoops().size());
+        for (IOLoop loop : server.getIoLoops()){
+            Assert.assertTrue(loop.isRunning());
+        }
+
+        server.stop();
+        for (IOLoop loop : server.getIoLoops()){
+            Assert.assertFalse(loop.isRunning());
+        }
+
+    }
+
+    private HttpServer createServer() {
+
+        HttpServer server = new HttpServer(new Configuration()) {
+            @Override
+            protected Application createApplication(String packageName) {
+                return new Application(Maps.<String, RequestHandler> newHashMap());
+            }
+        };
+
+        return server;
+    }
+}



Mime
View raw message