httplite: re-add test code after project re-org

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1214817 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractHttpliteTestCase.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractHttpliteTestCase.java
new file mode 100644
index 0000000..db185c0
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractHttpliteTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * 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.felix.httplite.osgi.test;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpService;
+
+
+/**
+ * Base class with commong HTTP testing methods.  Depends on Apache Commons-IO.
+ *
+ */
+public abstract class AbstractHttpliteTestCase extends AbstractPojoSRTestCase
+{
+
+    protected static final int DEFAULT_PORT = 8080;
+    protected static final String DEFAULT_BASE_URL = "http://localhost:" + DEFAULT_PORT;
+
+    protected static String readInputAsString( InputStream in ) throws IOException
+    {
+        return IOUtils.toString( in );
+    }
+
+
+    /**
+     * Create an array of bytesfrom the complete contents of an InputStream.
+     * 
+     * @param in
+     *            InputStream to turn into a byte array
+     * @return byte array (byte[]) w/ contents of input stream, or null if inputstream is null.
+     * @throws IOException
+     *             on I/O error
+     */
+    protected static byte[] readInputAsByteArray( InputStream in ) throws IOException
+    {
+        return IOUtils.toByteArray( in );
+    }
+
+
+    /**
+     * Create a HttpURLConnection for specified url.
+     * 
+     * @param urlStr
+     * @param method
+     * @return
+     * @throws IOException
+     */
+    protected static HttpURLConnection getConnection( String urlStr, String method ) throws IOException
+    {
+        URL url = new URL( urlStr );
+        HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
+        connection.setRequestMethod( method );
+        connection.setConnectTimeout( 1000 );
+
+        return connection;
+
+    }
+
+
+    /**
+     * @param context
+     * @return instance of HTTP service
+     */
+    protected HttpService getHTTPService( BundleContext context )
+    {
+        ServiceReference sr = registry.getServiceReference( HttpService.class.getName() );
+
+        assertNotNull( sr );
+
+        Object svc = registry.getService( sr );
+
+        assertNotNull( svc );
+        assertTrue( svc instanceof HttpService );
+
+        return ( HttpService ) svc;
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractPojoSRTestCase.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractPojoSRTestCase.java
new file mode 100644
index 0000000..6bcc12e
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/AbstractPojoSRTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * 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.felix.httplite.osgi.test;
+
+
+import java.util.HashMap;
+import java.util.ServiceLoader;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.httplite.osgi.Activator;
+
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistry;
+import de.kalpatec.pojosr.framework.launch.PojoServiceRegistryFactory;
+
+
+/**
+ * Common functionality for PojoSR-based tests.
+ * 
+ */
+public abstract class AbstractPojoSRTestCase extends TestCase
+{
+
+    protected PojoServiceRegistry registry;
+    protected Activator activator;
+
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        //Initialize service registry
+        ServiceLoader loader = ServiceLoader.load( PojoServiceRegistryFactory.class );
+
+        registry = ( ( PojoServiceRegistryFactory ) loader.iterator().next() ).newPojoServiceRegistry( new HashMap() );
+
+        assertNotNull( registry );
+
+        //Initialize bundle
+        activator = new Activator();
+        activator.start( registry.getBundleContext() );
+    }
+
+
+    protected void tearDown() throws Exception
+    {
+        if ( activator != null && registry != null )
+        {
+            activator.stop( registry.getBundleContext() );
+        }
+        super.tearDown();
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/BasicTestingServlet.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/BasicTestingServlet.java
new file mode 100644
index 0000000..6e5b405
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/BasicTestingServlet.java
@@ -0,0 +1,218 @@
+/*
+ * 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.felix.httplite.osgi.test;
+
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * Servlet for tests.
+ *
+ */
+public class BasicTestingServlet extends HttpServlet implements Servlet
+{
+
+    boolean m_getCalled, m_postCalled, m_putCalled, m_deleteCalled = false;
+    private final String m_responseStringContent;
+    private final boolean m_asWriter;
+    private final byte[] m_responseBinaryContent;
+    private Map m_requestParams;
+    private Map m_queryStringMap;
+    private String m_pathInfo;
+    private HttpServletRequest m_request;
+
+
+    /**
+     * Most basic constructor.
+     */
+    public BasicTestingServlet()
+    {
+        this.m_responseStringContent = null;
+        this.m_responseBinaryContent = null;
+        this.m_asWriter = false;
+    }
+
+
+    /**
+     * Pass back content in GET.
+     * @param content
+     * @param asWriter
+     */
+    public BasicTestingServlet( String content, boolean asWriter )
+    {
+        this.m_responseStringContent = content;
+        this.m_responseBinaryContent = null;
+        this.m_asWriter = asWriter;
+    }
+
+
+    public BasicTestingServlet( byte[] content, boolean asWriter )
+    {
+        this.m_responseStringContent = null;
+        this.m_responseBinaryContent = content;
+        this.m_asWriter = asWriter;
+    }
+
+
+    protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        m_getCalled = true;
+        m_requestParams = req.getParameterMap();
+        m_queryStringMap = parseQueryStringMap( req.getQueryString() );
+        m_pathInfo = req.getPathInfo();
+        m_request = req;
+
+        if ( m_responseStringContent != null )
+        {
+            if ( m_asWriter )
+            {
+                resp.getWriter().print( m_responseStringContent );
+            }
+            else
+            {
+                resp.getOutputStream().print( m_responseStringContent );
+            }
+        }
+        else if ( m_responseBinaryContent != null )
+        {
+           
+            resp.getOutputStream().write( m_responseBinaryContent );
+
+        }
+    }
+
+
+    private Map parseQueryStringMap( String queryString )
+    {
+        if ( queryString == null || queryString.length() == 0 )
+        {
+            return Collections.EMPTY_MAP;
+        }
+
+        Map m = new HashMap();
+
+        String[] kvp = queryString.split( "&" );
+
+        for ( int i = 0; i < kvp.length; ++i )
+        {
+            String elem[] = kvp[i].split( "=" );
+            m.put( elem[0], elem[1] );
+        }
+
+        return m;
+    }
+
+
+    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        m_postCalled = true;
+        m_requestParams = req.getParameterMap();
+        m_queryStringMap = parseQueryStringMap( req.getQueryString() );
+        m_pathInfo = req.getPathInfo();
+        m_request = req;
+    }
+
+
+    protected void doDelete( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        m_deleteCalled = true;
+        m_requestParams = req.getParameterMap();
+        m_queryStringMap = parseQueryStringMap( req.getQueryString() );
+        m_pathInfo = req.getPathInfo();
+        m_request = req;
+    }
+
+
+    protected void doPut( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        m_putCalled = true;
+        m_requestParams = req.getParameterMap();
+        m_queryStringMap = parseQueryStringMap( req.getQueryString() );
+        m_pathInfo = req.getPathInfo();
+        m_request = req;
+    }
+
+
+    public boolean isGetCalled()
+    {
+        return m_getCalled;
+    }
+
+
+    public boolean isPostCalled()
+    {
+        return m_postCalled;
+    }
+
+
+    public boolean isPutCalled()
+    {
+        return m_putCalled;
+    }
+
+
+    public boolean isDeleteCalled()
+    {
+        return m_deleteCalled;
+    }
+
+
+    public Map getRequestParameters()
+    {
+        return m_requestParams;
+    }
+
+
+    public Map getQueryStringMap()
+    {
+        return m_queryStringMap;
+    }
+
+
+    public String getPathInfo()
+    {
+        return m_pathInfo;
+    }
+
+    public Enumeration getHeaderNames()
+    {
+        return m_request.getHeaderNames();
+    }
+
+    public String getHeader(String name) 
+    {
+        return m_request.getHeader( name );
+    }
+    
+    public Enumeration getHeaders(String name) 
+    {
+        return m_request.getHeaders( name );
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestOSGiService.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestOSGiService.java
new file mode 100644
index 0000000..542a9bc
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestOSGiService.java
@@ -0,0 +1,147 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.apache.felix.httplite.osgi.test.BasicTestingServlet;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Tests related to OSGi service registry.
+ * 
+ * @author kgilmer
+ * 
+ */
+public class TestOSGiService extends AbstractHttpliteTestCase
+{
+
+    /**
+     * HTTPService is available
+     */
+    public void testHTTPServiceAvailability()
+    {
+        assertNotNull( getHTTPService( registry.getBundleContext() ) );
+    }
+
+
+    /**
+     * Can register a servlet with the HTTPService
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void testCanRegisterServlet() throws ServletException, NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        httpService.registerServlet( "/", new BasicTestingServlet(), null, null );
+    }
+
+
+    /**
+     * Test that HTTP Service does not allow same alias to be registered twice.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void testCannotRegisterSameAliasTwice() throws ServletException, NamespaceException
+    {
+
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        boolean namespaceExceptionThrown = false;
+        httpService.registerServlet( "/alias", new BasicTestingServlet(), null, null );
+
+        try
+        {
+            httpService.registerServlet( "/alias", new BasicTestingServlet(), null, null );
+        }
+        catch ( NamespaceException e )
+        {
+            namespaceExceptionThrown = true;
+        }
+
+        assertTrue( namespaceExceptionThrown );
+    }
+
+
+    /**
+     * Test invalid aliases throw NamespaceException.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void testCannotRegisterInvalidAlias() throws ServletException, NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+        String[] badAliases =
+            { "noslash" };
+
+        for ( int i = 0; i < badAliases.length; ++i )
+        {
+            boolean namespaceExceptionThrown = false;
+            try
+            {
+                httpService.registerServlet( badAliases[i], new BasicTestingServlet(), null, null );
+            }
+            catch ( NamespaceException e )
+            {
+                namespaceExceptionThrown = true;
+            }
+
+        }
+    }
+
+
+    /**
+     * Test that an alias can be registered after it's been previously registered and then unregistered.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void testCanReregisterAlias() throws ServletException, NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        httpService.registerServlet( "/alias", new BasicTestingServlet(), null, null );
+
+        httpService.unregister( "/alias" );
+
+        httpService.registerServlet( "/alias", new BasicTestingServlet(), null, null );
+    }
+
+
+    /**
+     * Test resources can be registered.
+     * 
+     * @throws NamespaceException
+     */
+    public void testCanRegisterResources() throws NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        httpService.registerResources( "/restest", "/webroot/", null );
+    }
+
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestParameters.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestParameters.java
new file mode 100644
index 0000000..62b57c5
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestParameters.java
@@ -0,0 +1,119 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.apache.felix.httplite.osgi.test.BasicTestingServlet;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Test request parameter handling by container.
+ *
+ */
+public class TestParameters extends AbstractHttpliteTestCase
+{
+
+    //TODO: test unicode parameters
+    //TODO: test parameters with empty values
+    //TODO: test parameter name collision
+
+    /**
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testCorrectParameterCount() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        int parameterCount = 16;
+        for ( int i = 0; i < parameterCount; ++i )
+        {
+            client.addRequestProperty( "k" + i, "v" + i );
+        }
+        client.connect();
+        assertTrue( client.getResponseCode() == 200 );
+        
+        int headerCount = 0;
+        Enumeration enum = testServlet.getHeaderNames();
+        while (enum.hasMoreElements()) 
+        {
+            headerCount++;
+            System.out.println("header: " + enum.nextElement().toString());
+        }
+        
+        
+        assertTrue( headerCount >= parameterCount );
+    }
+
+
+    /**
+     * Test the parameter contents.
+     * 
+     * @throws IOException
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void testParameterContents() throws IOException, ServletException, NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        int parameterCount = 16;
+        for ( int i = 0; i < parameterCount; ++i )
+        {
+            client.addRequestProperty( "k" + i, "v" + i );
+        }
+        client.connect();
+        assertTrue( client.getResponseCode() == 200 );
+        Map rp = new HashMap();
+        
+        Enumeration e = testServlet.getHeaderNames();
+        while (e.hasMoreElements()) 
+        {
+            String key = e.nextElement().toString();
+            rp.put( key , testServlet.getHeader( key ) );
+        }
+        
+        for ( int i = 0; i < parameterCount; ++i )
+        {
+             assertTrue( rp.get( "k" + i ).equals( "v" + i ) );
+        }
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestQueryString.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestQueryString.java
new file mode 100644
index 0000000..425785e
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestQueryString.java
@@ -0,0 +1,84 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.apache.felix.httplite.osgi.test.BasicTestingServlet;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Tests for query string handling by the container.
+ *
+ */
+public class TestQueryString extends AbstractHttpliteTestCase
+{
+
+    //TODO: test unicode keys and values
+    //TODO: test invalid query string in request
+
+    /**
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testQueryString() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        StringBuffer qs = new StringBuffer( "?" );
+        int parameterCount = 16;
+        for ( int i = 0; i < parameterCount; ++i )
+        {
+            qs.append( "k" + i );
+            qs.append( "=" );
+            qs.append( "v" + i );
+            if ( i != ( parameterCount - 1 ) )
+            {
+                qs.append( '&' );
+            }
+        }
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test" + qs.toString(), "GET" );
+
+        client.connect();
+        assertTrue( client.getResponseCode() == 200 );
+
+        Map qsm = testServlet.getQueryStringMap();
+
+        assertTrue( qsm.size() == parameterCount );
+
+        for ( int i = 0; i < parameterCount; ++i )
+        {
+            assertTrue( qsm.containsKey( "k" + i ) );
+            assertTrue( qsm.get( "k" + i ).equals( "v" + i ) );
+        }
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestRequestPath.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestRequestPath.java
new file mode 100644
index 0000000..7d64f5f
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestRequestPath.java
@@ -0,0 +1,68 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.apache.felix.httplite.osgi.test.BasicTestingServlet;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Tests for handling of client request path.
+ *
+ */
+public class TestRequestPath extends AbstractHttpliteTestCase
+{
+
+    public void testSimpleRequestPath() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test/a/b/c", "GET" );
+
+        client.connect();
+        assertTrue( client.getResponseCode() == 200 );
+        assertTrue( testServlet.getPathInfo().equals( "/a/b/c" ) );
+    }
+
+
+    public void testMultipleSeperatorsRequestPath() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test/a/b//c", "GET" );
+
+        client.connect();
+        assertTrue( client.getResponseCode() == 200 );
+        assertTrue( testServlet.getPathInfo().equals( "/a/b/c" ) );
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestResources.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestResources.java
new file mode 100644
index 0000000..9810a7c
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestResources.java
@@ -0,0 +1,76 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Tests for resources.
+ *
+ */
+public class TestResources extends AbstractHttpliteTestCase
+{
+
+    //TODO: test GET binary file
+
+    /**
+     * Test that a resource can be retrieved from client.
+     * @throws NamespaceException
+     * @throws IOException 
+     */
+    public void testCanGetResource() throws NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        httpService.registerResources( "/", "/webroot/", null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/index.html", "GET" );
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+        String response = readInputAsString( client.getInputStream() );
+        assertNotNull( response );
+        assertTrue( response.indexOf( "boo" ) > -1 );
+    }
+
+
+    /**
+     * Test that non-existent resource returns 404.
+     * @throws IOException
+     * @throws NamespaceException
+     */
+    public void testCannotGetInvalidResource() throws IOException, NamespaceException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        httpService.registerResources( "/", "/webroot/", null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/index2.html", "GET" );
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 404 );
+    }
+}
diff --git a/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestServletContainer.java b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestServletContainer.java
new file mode 100644
index 0000000..239a71c
--- /dev/null
+++ b/httplite/minimum/src/test/java/org/apache/felix/httplite/osgi/test/cases/TestServletContainer.java
@@ -0,0 +1,252 @@
+/*
+ * 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.felix.httplite.osgi.test.cases;
+
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.Random;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.httplite.osgi.test.AbstractHttpliteTestCase;
+import org.apache.felix.httplite.osgi.test.BasicTestingServlet;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+
+/**
+ * Tests related to OSGi service registry.
+ * 
+ * @author kgilmer
+ * 
+ */
+public class TestServletContainer extends AbstractHttpliteTestCase
+{
+    /**
+     * Test calling GET enters TestServlet doGet() method.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException 
+     */
+    public void testExecuteGET() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+        assertTrue( testServlet.isGetCalled() );
+        assertFalse( testServlet.isDeleteCalled() );
+        assertFalse( testServlet.isPostCalled() );
+        assertFalse( testServlet.isPutCalled() );
+    }
+
+
+    /**
+     * Test can execute POST method.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testExecutePOST() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "POST" );
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+        assertFalse( testServlet.isGetCalled() );
+        assertFalse( testServlet.isDeleteCalled() );
+        assertTrue( testServlet.isPostCalled() );
+        assertFalse( testServlet.isPutCalled() );
+    }
+
+
+    /**
+     * Test can execute PUT method.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testExecutePUT() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "PUT" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+        assertFalse( testServlet.isGetCalled() );
+        assertFalse( testServlet.isDeleteCalled() );
+        assertFalse( testServlet.isPostCalled() );
+        assertTrue( testServlet.isPutCalled() );
+    }
+
+
+    /**
+     * Test can execute DELETE method.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testExecuteDELETE() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        BasicTestingServlet testServlet = new BasicTestingServlet();
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "DELETE" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+        assertFalse( testServlet.isGetCalled() );
+        assertTrue( testServlet.isDeleteCalled() );
+        assertFalse( testServlet.isPostCalled() );
+        assertFalse( testServlet.isPutCalled() );
+    }
+
+
+    /**
+     * Test that container returns exact content as specified in servlet.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testGETResponseStringContent() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        String content = "test content";
+
+        BasicTestingServlet testServlet = new BasicTestingServlet( content, false );
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+
+        String response = readInputAsString( client.getInputStream() );
+
+        printBytes( content.getBytes() );
+        printBytes( response.getBytes() );
+        assertTrue( content.equals( response ) );
+
+        httpService.unregister( "/test" );
+
+        content = "test content";
+        testServlet = new BasicTestingServlet( content, true );
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+
+        response = readInputAsString( client.getInputStream() );
+        printBytes( content.getBytes() );
+        printBytes( response.getBytes() );
+        assertTrue( content.length() == response.length() );
+        assertTrue( content.equals( response ) );
+    }
+
+
+    /**
+     * Test that container returns exact content as specified in servlet.
+     * 
+     * @throws ServletException
+     * @throws NamespaceException
+     * @throws IOException
+     */
+    public void testGETResponseBinaryContent() throws ServletException, NamespaceException, IOException
+    {
+        HttpService httpService = getHTTPService( registry.getBundleContext() );
+
+        byte[] content = generateRandomBinaryContent();
+
+        BasicTestingServlet testServlet = new BasicTestingServlet( content, false );
+        httpService.registerServlet( "/test", testServlet, null, null );
+
+        HttpURLConnection client = getConnection( DEFAULT_BASE_URL + "/test", "GET" );
+
+        client.connect();
+
+        assertTrue( client.getResponseCode() == 200 );
+
+        byte[] response = readInputAsByteArray( client.getInputStream() );
+
+        printBytes( content );
+        printBytes( response );
+        assertTrue( content.length ==  response.length );
+        for (int i = 0; i < content.length; ++i) 
+        {
+            assertTrue( content[i] == response[i] );
+        }
+
+        httpService.unregister( "/test" );       
+    }
+
+
+    private byte[] generateRandomBinaryContent()
+    {
+        Random rnd = new Random();
+
+        int l = rnd.nextInt( 40 ) + 20;
+
+        byte[] buf = new byte[l];
+
+        rnd.nextBytes( buf );
+
+        return buf;
+    }
+
+
+    private static void printBytes( byte[] b )
+    {
+        for ( int i = 0; i < b.length; ++i )
+        {
+            System.out.print( b[i] );
+            System.out.print( ", " );
+        }
+        System.out.println();
+    }
+}
diff --git a/httplite/minimum/src/test/resources/webroot/index.html b/httplite/minimum/src/test/resources/webroot/index.html
new file mode 100644
index 0000000..e16978c
--- /dev/null
+++ b/httplite/minimum/src/test/resources/webroot/index.html
@@ -0,0 +1,6 @@
+<html>
+<head></head>
+<body>
+<p>boo</p>
+</body>
+</html>
\ No newline at end of file