You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ko...@apache.org on 2014/03/22 20:41:53 UTC

[3/4] git commit: updated refs/heads/master to 265208a

Basic tests for ApiServlet

new tests for ApiServlet covering
 - utf8Fixup
 - some of processRequestInContext

minor cleanup done in StringBuffer handling and utf8Fixup got a bit shorter

Signed-off-by: Laszlo Hornyak <la...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/265208a2
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/265208a2
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/265208a2

Branch: refs/heads/master
Commit: 265208a261403dc33edb6903c83b0a943ee4aafa
Parents: 3dc4d2e
Author: Laszlo Hornyak <la...@gmail.com>
Authored: Sat Mar 22 17:32:16 2014 +0100
Committer: Laszlo Hornyak <la...@gmail.com>
Committed: Sat Mar 22 18:34:46 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/api/ApiServlet.java      |  34 ++---
 server/test/com/cloud/api/ApiServletTest.java | 169 +++++++++++++++++++++
 2 files changed, 186 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/265208a2/server/src/com/cloud/api/ApiServlet.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java
index 37a2549..c24877a 100755
--- a/server/src/com/cloud/api/ApiServlet.java
+++ b/server/src/com/cloud/api/ApiServlet.java
@@ -82,7 +82,7 @@ public class ApiServlet extends HttpServlet {
         processRequest(req, resp);
     }
 
-    private void utf8Fixup(final HttpServletRequest req, final Map<String, Object[]> params) {
+    void utf8Fixup(final HttpServletRequest req, final Map<String, Object[]> params) {
         if (req.getQueryString() == null) {
             return;
         }
@@ -91,18 +91,9 @@ public class ApiServlet extends HttpServlet {
         if (paramsInQueryString != null) {
             for (final String param : paramsInQueryString) {
                 final String[] paramTokens = param.split("=", 2);
-                if (paramTokens != null && paramTokens.length == 2) {
-                    String name = paramTokens[0];
-                    String value = paramTokens[1];
-
-                    try {
-                        name = URLDecoder.decode(name, "UTF-8");
-                    } catch (final UnsupportedEncodingException e) {
-                    }
-                    try {
-                        value = URLDecoder.decode(value, "UTF-8");
-                    } catch (final UnsupportedEncodingException e) {
-                    }
+                if (paramTokens.length == 2) {
+                    String name = decodeUtf8(paramTokens[0]);
+                    String value = decodeUtf8(paramTokens[1]);
                     params.put(name, new String[] {value});
                 } else {
                     s_logger.debug("Invalid parameter in URL found. param: " + param);
@@ -111,6 +102,15 @@ public class ApiServlet extends HttpServlet {
         }
     }
 
+    private String decodeUtf8(final String value) {
+        try {
+            return URLDecoder.decode(value, "UTF-8");
+        } catch (final UnsupportedEncodingException e) {
+            //should never happen
+            return null;
+        }
+    }
+
     private void processRequest(final HttpServletRequest req, final HttpServletResponse resp) {
         _managedContext.runWithContext(new Runnable() {
             @Override
@@ -120,10 +120,10 @@ public class ApiServlet extends HttpServlet {
         });
     }
 
-    private void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) {
+    void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) {
         final StringBuffer auditTrailSb = new StringBuffer();
-        auditTrailSb.append(" " + req.getRemoteAddr());
-        auditTrailSb.append(" -- " + req.getMethod() + " ");
+        auditTrailSb.append(" ").append(req.getRemoteAddr());
+        auditTrailSb.append(" -- ").append(req.getMethod()).append(' ');
         // get the response format since we'll need it in a couple of places
         String responseType = BaseCmd.RESPONSE_TYPE_XML;
         final Map<String, Object[]> params = new HashMap<String, Object[]>();
@@ -171,7 +171,7 @@ public class ApiServlet extends HttpServlet {
                         }
                     }
                     auditTrailSb.append("command=logout");
-                    auditTrailSb.append(" " + HttpServletResponse.SC_OK);
+                    auditTrailSb.append(" ").append(HttpServletResponse.SC_OK);
                     writeResponse(resp, getLogoutSuccessResponse(responseType), HttpServletResponse.SC_OK, responseType);
                     return;
                 } else if ("login".equalsIgnoreCase(command)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/265208a2/server/test/com/cloud/api/ApiServletTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/api/ApiServletTest.java b/server/test/com/cloud/api/ApiServletTest.java
new file mode 100644
index 0000000..85c5723
--- /dev/null
+++ b/server/test/com/cloud/api/ApiServletTest.java
@@ -0,0 +1,169 @@
+// 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 com.cloud.api;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.net.URLEncoder;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ApiServletTest {
+
+    @Mock
+    ApiServer apiServer;
+
+    @Mock
+    HttpServletRequest request;
+
+    @Mock
+    HttpServletResponse response;
+
+    @Mock
+    AccountService accountService;
+
+    @Mock
+    User user;
+
+    @Mock
+    Account account;
+
+    @Mock
+    HttpSession session;
+
+    StringWriter responseWriter;
+
+    ApiServlet servlet;
+
+    @Before
+    public void setup() throws SecurityException, NoSuchFieldException,
+            IllegalArgumentException, IllegalAccessException, IOException {
+        servlet = new ApiServlet();
+        responseWriter = new StringWriter();
+        Mockito.when(response.getWriter()).thenReturn(
+                new PrintWriter(responseWriter));
+        Mockito.when(request.getRemoteAddr()).thenReturn("127.0.0.1");
+        Mockito.when(accountService.getSystemUser()).thenReturn(user);
+        Mockito.when(accountService.getSystemAccount()).thenReturn(account);
+        Field accountMgrField = ApiServlet.class
+                .getDeclaredField("_accountMgr");
+        accountMgrField.setAccessible(true);
+        accountMgrField.set(servlet, accountService);
+
+        Field apiServerField = ApiServlet.class.getDeclaredField("_apiServer");
+        apiServerField.setAccessible(true);
+        apiServerField.set(servlet, apiServer);
+    }
+
+    @Test
+    public void utf8Fixup() {
+        Mockito.when(request.getQueryString()).thenReturn(
+                "foo=12345&bar=blah&baz=&param=param");
+        HashMap<String, Object[]> params = new HashMap<String, Object[]>();
+        servlet.utf8Fixup(request, params);
+        Assert.assertEquals("12345", params.get("foo")[0]);
+        Assert.assertEquals("blah", params.get("bar")[0]);
+    }
+
+    @Test
+    public void utf8FixupNull() {
+        Mockito.when(request.getQueryString()).thenReturn("&&=a&=&&a&a=a=a=a");
+        servlet.utf8Fixup(request, new HashMap<String, Object[]>());
+    }
+
+    @Test
+    public void utf8FixupStrangeInputs() {
+        Mockito.when(request.getQueryString()).thenReturn("&&=a&=&&a&a=a=a=a");
+        HashMap<String, Object[]> params = new HashMap<String, Object[]>();
+        servlet.utf8Fixup(request, params);
+        Assert.assertTrue(params.containsKey(""));
+    }
+
+    @Test
+    public void utf8FixupUtf() throws UnsupportedEncodingException {
+        Mockito.when(request.getQueryString()).thenReturn(
+                URLEncoder.encode("防水镜钻孔机", "UTF-8") + "="
+                        + URLEncoder.encode("árvíztűrőtükörfúró", "UTF-8"));
+        HashMap<String, Object[]> params = new HashMap<String, Object[]>();
+        servlet.utf8Fixup(request, params);
+        Assert.assertEquals("árvíztűrőtükörfúró", params.get("防水镜钻孔机")[0]);
+    }
+
+    @Test
+    public void processRequestInContextUnauthorizedGET() {
+        Mockito.when(request.getMethod()).thenReturn("GET");
+        Mockito.when(
+                apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong()))
+                .thenReturn(false);
+        servlet.processRequestInContext(request, response);
+        Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        Mockito.verify(apiServer, Mockito.never()).handleRequest(
+                Mockito.anyMap(), Mockito.anyString(),
+                Mockito.any(StringBuffer.class));
+    }
+
+    @Test
+    public void processRequestInContextAuthorizedGet() {
+        Mockito.when(request.getMethod()).thenReturn("GET");
+        Mockito.when(
+                apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong()))
+                .thenReturn(true);
+        servlet.processRequestInContext(request, response);
+        Mockito.verify(response).setStatus(HttpServletResponse.SC_OK);
+        Mockito.verify(apiServer, Mockito.times(1)).handleRequest(
+                Mockito.anyMap(), Mockito.anyString(),
+                Mockito.any(StringBuffer.class));
+    }
+
+    @Test
+    public void processRequestInContextLougout() {
+        Mockito.when(request.getMethod()).thenReturn("GET");
+        Mockito.when(request.getSession(Mockito.anyBoolean())).thenReturn(
+                session);
+        Mockito.when(session.getAttribute("userid")).thenReturn(1l);
+        Mockito.when(session.getAttribute("accountobj")).thenReturn(account);
+        HashMap<String, String[]> params = new HashMap<String, String[]>();
+        params.put(ApiConstants.COMMAND, new String[] { "logout" });
+        Mockito.when(request.getParameterMap()).thenReturn(params);
+
+        servlet.processRequestInContext(request, response);
+
+        Mockito.verify(apiServer).logoutUser(1l);
+        Mockito.verify(session).invalidate();
+    }
+
+}