Fix some bugs and add java integration test for api rate limit plugin. Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/86ada92f Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/86ada92f Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/86ada92f
Branch: refs/heads/add_remove_nics Commit: 86ada92ffa20d7624ff3c411ac24ea9dbd9e0196 Parents: c1a540c Author: Min Chen <min.c...@citrix.com> Authored: Thu Jan 17 15:13:51 2013 -0800 Committer: Min Chen <min.c...@citrix.com> Committed: Thu Jan 17 15:13:51 2013 -0800 ---------------------------------------------------------------------- client/tomcatconf/components.xml.in | 2 +- plugins/api/rate-limit/pom.xml | 22 ++ .../api/command/user/ratelimit/GetApiLimitCmd.java | 3 +- .../cloudstack/ratelimit/integration/APITest.java | 211 ++++++++++++++ .../ratelimit/integration/LoginResponse.java | 142 ++++++++++ .../integration/RateLimitIntegrationTest.java | 214 +++++++++++++++ server/test/com/cloud/api/APITest.java | 39 ++- server/test/com/cloud/api/ListPerfTest.java | 140 ---------- 8 files changed, 622 insertions(+), 151 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/client/tomcatconf/components.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index e19b418..8157051 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -185,7 +185,7 @@ under the License. <pluggableservice name="ApiDiscoveryService" key="org.apache.cloudstack.discovery.ApiDiscoveryService" class="org.apache.cloudstack.discovery.ApiDiscoveryServiceImpl"/> <pluggableservice name="VirtualRouterElementService" key="com.cloud.network.element.VirtualRouterElementService" class="com.cloud.network.element.VirtualRouterElement"/> <pluggableservice name="NiciraNvpElementService" key="com.cloud.network.element.NiciraNvpElementService" class="com.cloud.network.element.NiciraNvpElement"/> - <pluggableservice name="ApiRateLimitService" key="org.apache.cloudstack.api.ratelimit.ApiRateLimitService" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/> + <pluggableservice name="ApiRateLimitService" key="org.apache.cloudstack.ratelimit.ApiRateLimitService" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/> <dao name="OvsTunnelInterfaceDao" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" singleton="false"/> <dao name="OvsTunnelAccountDao" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" singleton="false"/> <dao name="NiciraNvpDao" class="com.cloud.network.dao.NiciraNvpDaoImpl" singleton="false"/> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/plugins/api/rate-limit/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 416c901..1f03309 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -26,4 +26,26 @@ <version>4.1.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> + <build> + <defaultGoal>install</defaultGoal> + <sourceDirectory>src</sourceDirectory> + <testSourceDirectory>test</testSourceDirectory> + <testResources> + <testResource> + <directory>test/resources</directory> + </testResource> + </testResources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <argLine>-Xmx1024m</argLine> + <excludes> + <exclude>org/apache/cloudstack/ratelimit/integration/*</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java ---------------------------------------------------------------------- diff --git a/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java b/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java index ad1fb28..2b7b8e6 100644 --- a/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java +++ b/plugins/api/rate-limit/src/org/apache/cloudstack/api/command/user/ratelimit/GetApiLimitCmd.java @@ -46,7 +46,7 @@ import com.cloud.user.UserContext; import com.cloud.utils.exception.CloudRuntimeException; @APICommand(name = "getApiLimit", responseObject=ApiLimitResponse.class, description="Get API limit count for the caller") -public class GetApiLimitCmd extends BaseListCmd { +public class GetApiLimitCmd extends BaseCmd { private static final Logger s_logger = Logger.getLogger(GetApiLimitCmd.class.getName()); private static final String s_name = "getapilimitresponse"; @@ -81,6 +81,7 @@ public class GetApiLimitCmd extends BaseListCmd { Account caller = UserContext.current().getCaller(); ApiLimitResponse response = _apiLimitService.searchApiLimit(caller); response.setResponseName(getCommandName()); + response.setObjectName("apilimit"); this.setResponseObject(response); } } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java ---------------------------------------------------------------------- diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java new file mode 100644 index 0000000..7701b15 --- /dev/null +++ b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/APITest.java @@ -0,0 +1,211 @@ +// 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 +// 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.cloudstack.ratelimit.integration; + +import java.io.BufferedReader; +import java.io.EOFException; +import java.io.InputStreamReader; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.cloudstack.api.response.SuccessResponse; + +import com.cloud.api.ApiGsonHelper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.Gson; + +/** + * Base class for API Test + * + * @author Min Chen + * + */ +public abstract class APITest { + + protected String rootUrl = "http://localhost:8080/client/api"; + protected String sessionKey = null; + protected String cookieToSent = null; + + + /** + * Sending an api request through Http GET + * @param command command name + * @param params command query parameters in a HashMap + * @return http request response string + */ + protected String sendRequest(String command, HashMap<String, String> params){ + try { + // Construct query string + StringBuilder sBuilder = new StringBuilder(); + sBuilder.append("command="); + sBuilder.append(command); + if ( params != null && params.size() > 0){ + Iterator<String> keys = params.keySet().iterator(); + while (keys.hasNext()){ + String key = keys.next(); + sBuilder.append("&"); + sBuilder.append(key); + sBuilder.append("="); + sBuilder.append(URLEncoder.encode(params.get(key), "UTF-8")); + } + } + + // Construct request url + String reqUrl = rootUrl + "?" + sBuilder.toString(); + + // Send Http GET request + URL url = new URL(reqUrl); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + + if ( !command.equals("login") && cookieToSent != null){ + // add the cookie to a request + conn.setRequestProperty("Cookie", cookieToSent); + } + conn.connect(); + + + if ( command.equals("login")){ + // if it is login call, store cookie + String headerName=null; + for (int i=1; (headerName = conn.getHeaderFieldKey(i))!=null; i++) { + if (headerName.equals("Set-Cookie")) { + String cookie = conn.getHeaderField(i); + cookie = cookie.substring(0, cookie.indexOf(";")); + String cookieName = cookie.substring(0, cookie.indexOf("=")); + String cookieValue = cookie.substring(cookie.indexOf("=") + 1, cookie.length()); + cookieToSent = cookieName + "=" + cookieValue; + } + } + } + + // Get the response + StringBuilder response = new StringBuilder(); + BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line; + try { + while ((line = rd.readLine()) != null) { + response.append(line); + } + } catch (EOFException ex) { + // ignore this exception + System.out.println("EOF exception due to java bug"); + } + rd.close(); + + + + return response.toString(); + + } catch (Exception e) { + throw new CloudRuntimeException("Problem with sending api request", e); + } + } + + protected String createMD5String(String password) { + MessageDigest md5; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + throw new CloudRuntimeException("Error", e); + } + + md5.reset(); + BigInteger pwInt = new BigInteger(1, md5.digest(password.getBytes())); + + // make sure our MD5 hash value is 32 digits long... + StringBuffer sb = new StringBuffer(); + String pwStr = pwInt.toString(16); + int padding = 32 - pwStr.length(); + for (int i = 0; i < padding; i++) { + sb.append('0'); + } + sb.append(pwStr); + return sb.toString(); + } + + + protected Object fromSerializedString(String result, Class<?> repCls) { + try { + if (result != null && !result.isEmpty()) { + // get real content + int start; + int end; + if (repCls == LoginResponse.class || repCls == SuccessResponse.class) { + + start = result.indexOf('{', result.indexOf('{') + 1); // find + // the + // second + // { + + end = result.lastIndexOf('}', result.lastIndexOf('}') - 1); // find + // the + // second + // } + // backwards + + } else { + // get real content + start = result.indexOf('{', result.indexOf('{', result.indexOf('{') + 1) + 1); // find + // the + // third + // { + end = result.lastIndexOf('}', result.lastIndexOf('}', result.lastIndexOf('}') - 1) - 1); // find + // the + // third + // } + // backwards + } + if (start < 0 || end < 0) { + throw new CloudRuntimeException("Response format is wrong: " + result); + } + String content = result.substring(start, end + 1); + Gson gson = ApiGsonHelper.getBuilder().create(); + return gson.fromJson(content, repCls); + } + return null; + } catch (RuntimeException e) { + throw new CloudRuntimeException("Caught runtime exception when doing GSON deserialization on: " + result, e); + } + } + + /** + * Login call + * @param username user name + * @param password password (plain password, we will do MD5 hash here for you) + * @return login response string + */ + protected void login(String username, String password) + { + //String md5Psw = createMD5String(password); + // send login request + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("username", username); + params.put("password", password); + String result = this.sendRequest("login", params); + LoginResponse loginResp = (LoginResponse)fromSerializedString(result, LoginResponse.class); + sessionKey = loginResp.getSessionkey(); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java ---------------------------------------------------------------------- diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java new file mode 100644 index 0000000..719f39c --- /dev/null +++ b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/LoginResponse.java @@ -0,0 +1,142 @@ +// 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 +// 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.cloudstack.ratelimit.integration; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +/** + * Login Response object + * + * @author Min Chen + * + */ +public class LoginResponse extends BaseResponse { + + @SerializedName("timeout") + @Param(description = "session timeout period") + private String timeout; + + @SerializedName("sessionkey") + @Param(description = "login session key") + private String sessionkey; + + @SerializedName("username") + @Param(description = "login username") + private String username; + + @SerializedName("userid") + @Param(description = "login user internal uuid") + private String userid; + + @SerializedName("firstname") + @Param(description = "login user firstname") + private String firstname; + + @SerializedName("lastname") + @Param(description = "login user lastname") + private String lastname; + + @SerializedName("account") + @Param(description = "login user account type") + private String account; + + @SerializedName("domainid") + @Param(description = "login user domain id") + private String domainid; + + @SerializedName("type") + @Param(description = "login user type") + private int type; + + public String getTimeout() { + return timeout; + } + + public void setTimeout(String timeout) { + this.timeout = timeout; + } + + public String getSessionkey() { + return sessionkey; + } + + public void setSessionkey(String sessionkey) { + this.sessionkey = sessionkey; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDomainid() { + return domainid; + } + + public void setDomainid(String domainid) { + this.domainid = domainid; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + + +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java ---------------------------------------------------------------------- diff --git a/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java new file mode 100644 index 0000000..72d354c --- /dev/null +++ b/plugins/api/rate-limit/test/org/apache/cloudstack/ratelimit/integration/RateLimitIntegrationTest.java @@ -0,0 +1,214 @@ +// 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 +// 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.cloudstack.ratelimit.integration; + +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.apache.cloudstack.api.response.ApiLimitResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.junit.Before; +import org.junit.Test; + +import com.cloud.utils.exception.CloudRuntimeException; + + +/** + * Test fixture to do integration rate limit test. + * Currently we commented out this test suite since it requires a real MS and Db running. + * + * @author Min Chen + * + */ +public class RateLimitIntegrationTest extends APITest { + + private static int apiMax = 25; // assuming ApiRateLimitService set api.throttling.max = 25 + + @Before + public void setup(){ + // always reset count for each testcase + login("admin", "password"); + + // issue reset api limit calls + final HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("sessionkey", sessionKey); + String resetResult = sendRequest("resetApiLimit", params); + assertNotNull("Reset count failed!", fromSerializedString(resetResult, SuccessResponse.class)); + + } + + + @Test + public void testNoApiLimitOnRootAdmin() throws Exception { + // issue list Accounts calls + final HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + // assuming ApiRateLimitService set api.throttling.max = 25 + int clientCount = 26; + Runnable[] clients = new Runnable[clientCount]; + final boolean[] isUsable = new boolean[clientCount]; + + final CountDownLatch startGate = new CountDownLatch(1); + + final CountDownLatch endGate = new CountDownLatch(clientCount); + + + for (int i = 0; i < isUsable.length; ++i) { + final int j = i; + clients[j] = new Runnable() { + + /** + * {@inheritDoc} + */ + @Override + public void run() { + try { + startGate.await(); + + sendRequest("listAccounts", params); + + isUsable[j] = true; + + } catch (CloudRuntimeException e){ + isUsable[j] = false; + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + endGate.countDown(); + } + } + }; + } + + ExecutorService executor = Executors.newFixedThreadPool(clientCount); + + for (Runnable runnable : clients) { + executor.execute(runnable); + } + + startGate.countDown(); + + endGate.await(); + + int rejectCount = 0; + for ( int i = 0; i < isUsable.length; ++i){ + if ( !isUsable[i]) + rejectCount++; + } + + assertEquals("No request should be rejected!", 0, rejectCount); + + } + + + @Test + public void testApiLimitOnUser() throws Exception { + // log in using normal user + login("demo", "password"); + // issue list Accounts calls + final HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + + int clientCount = apiMax + 1; + Runnable[] clients = new Runnable[clientCount]; + final boolean[] isUsable = new boolean[clientCount]; + + final CountDownLatch startGate = new CountDownLatch(1); + + final CountDownLatch endGate = new CountDownLatch(clientCount); + + + for (int i = 0; i < isUsable.length; ++i) { + final int j = i; + clients[j] = new Runnable() { + + /** + * {@inheritDoc} + */ + @Override + public void run() { + try { + startGate.await(); + + sendRequest("listAccounts", params); + + isUsable[j] = true; + + } catch (CloudRuntimeException e){ + isUsable[j] = false; + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + endGate.countDown(); + } + } + }; + } + + ExecutorService executor = Executors.newFixedThreadPool(clientCount); + + for (Runnable runnable : clients) { + executor.execute(runnable); + } + + startGate.countDown(); + + endGate.await(); + + int rejectCount = 0; + for ( int i = 0; i < isUsable.length; ++i){ + if ( !isUsable[i]) + rejectCount++; + } + + assertEquals("Only one request should be rejected!", 1, rejectCount); + + } + + @Test + public void testGetApiLimitOnUser() throws Exception { + // log in using normal user + login("demo", "password"); + + // issue an api call + HashMap<String, String> params = new HashMap<String, String>(); + params.put("response", "json"); + params.put("listAll", "true"); + params.put("sessionkey", sessionKey); + sendRequest("listAccounts", params); + + // issue get api limit calls + final HashMap<String, String> params2 = new HashMap<String, String>(); + params2.put("response", "json"); + params2.put("sessionkey", sessionKey); + String getResult = sendRequest("getApiLimit", params2); + ApiLimitResponse getLimitResp = (ApiLimitResponse)fromSerializedString(getResult, ApiLimitResponse.class); + assertEquals("Issued api count is incorrect!", 2, getLimitResp.getApiIssued() ); // should be 2 apis issues plus this getlimit api + assertEquals("Allowed api count is incorrect!", apiMax -2, getLimitResp.getApiAllowed()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/server/test/com/cloud/api/APITest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/api/APITest.java b/server/test/com/cloud/api/APITest.java index 69c488f..0b040ab 100644 --- a/server/test/com/cloud/api/APITest.java +++ b/server/test/com/cloud/api/APITest.java @@ -19,17 +19,17 @@ package com.cloud.api; import java.io.BufferedReader; import java.io.EOFException; import java.io.InputStreamReader; -import java.io.OutputStreamWriter; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; -import java.net.URLConnection; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Iterator; +import org.apache.cloudstack.api.response.SuccessResponse; + import com.cloud.utils.exception.CloudRuntimeException; import com.google.gson.Gson; @@ -147,17 +147,38 @@ public abstract class APITest { protected Object fromSerializedString(String result, Class<?> repCls) { try { if (result != null && !result.isEmpty()) { - // get real content - int start = result.indexOf('{', result.indexOf('{') + 1); // find the second { - if ( start < 0 ){ - throw new CloudRuntimeException("Response format is wrong: " + result); + int start; + int end; + if (repCls == LoginResponse.class || repCls == SuccessResponse.class) { + + start = result.indexOf('{', result.indexOf('{') + 1); // find + // the + // second + // { + + end = result.lastIndexOf('}', result.lastIndexOf('}') - 1); // find + // the + // second + // } + // backwards + + } else { + // get real content + start = result.indexOf('{', result.indexOf('{', result.indexOf('{') + 1) + 1); // find + // the + // third + // { + end = result.lastIndexOf('}', result.lastIndexOf('}', result.lastIndexOf('}') - 1) - 1); // find + // the + // third + // } + // backwards } - int end = result.lastIndexOf('}', result.lastIndexOf('}')-1); // find the second } backwards - if ( end < 0 ){ + if (start < 0 || end < 0) { throw new CloudRuntimeException("Response format is wrong: " + result); } - String content = result.substring(start, end+1); + String content = result.substring(start, end + 1); Gson gson = ApiGsonHelper.getBuilder().create(); return gson.fromJson(content, repCls); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/86ada92f/server/test/com/cloud/api/ListPerfTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/api/ListPerfTest.java b/server/test/com/cloud/api/ListPerfTest.java index c6fda9b..b8cb97e 100644 --- a/server/test/com/cloud/api/ListPerfTest.java +++ b/server/test/com/cloud/api/ListPerfTest.java @@ -170,144 +170,4 @@ public class ListPerfTest extends APITest { } - @Test - public void testNoApiLimitOnRootAdmin() throws Exception { - // issue list Accounts calls - final HashMap<String, String> params = new HashMap<String, String>(); - params.put("response", "json"); - params.put("listAll", "true"); - params.put("sessionkey", sessionKey); - // assuming ApiRateLimitService set api.throttling.max = 25 - int clientCount = 26; - Runnable[] clients = new Runnable[clientCount]; - final boolean[] isUsable = new boolean[clientCount]; - - final CountDownLatch startGate = new CountDownLatch(1); - - final CountDownLatch endGate = new CountDownLatch(clientCount); - - - for (int i = 0; i < isUsable.length; ++i) { - final int j = i; - clients[j] = new Runnable() { - - /** - * {@inheritDoc} - */ - @Override - public void run() { - try { - startGate.await(); - - sendRequest("listAccounts", params); - - isUsable[j] = true; - - } catch (CloudRuntimeException e){ - isUsable[j] = false; - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - endGate.countDown(); - } - } - }; - } - - ExecutorService executor = Executors.newFixedThreadPool(clientCount); - - for (Runnable runnable : clients) { - executor.execute(runnable); - } - - startGate.countDown(); - - endGate.await(); - - int rejectCount = 0; - for ( int i = 0; i < isUsable.length; ++i){ - if ( !isUsable[i]) - rejectCount++; - } - - assertEquals("No request should be rejected!", 0, rejectCount); - - } - - - @Test - public void testApiLimitOnUser() throws Exception { - // log in using normal user - login("demo", "password"); - // issue list Accounts calls - final HashMap<String, String> params = new HashMap<String, String>(); - params.put("response", "json"); - params.put("listAll", "true"); - params.put("sessionkey", sessionKey); - // assuming ApiRateLimitService set api.throttling.max = 25 - int clientCount = 26; - Runnable[] clients = new Runnable[clientCount]; - final boolean[] isUsable = new boolean[clientCount]; - - final CountDownLatch startGate = new CountDownLatch(1); - - final CountDownLatch endGate = new CountDownLatch(clientCount); - - - for (int i = 0; i < isUsable.length; ++i) { - final int j = i; - clients[j] = new Runnable() { - - /** - * {@inheritDoc} - */ - @Override - public void run() { - try { - startGate.await(); - - sendRequest("listAccounts", params); - - isUsable[j] = true; - - } catch (CloudRuntimeException e){ - isUsable[j] = false; - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - endGate.countDown(); - } - } - }; - } - - ExecutorService executor = Executors.newFixedThreadPool(clientCount); - - for (Runnable runnable : clients) { - executor.execute(runnable); - } - - startGate.countDown(); - - endGate.await(); - - int rejectCount = 0; - for ( int i = 0; i < isUsable.length; ++i){ - if ( !isUsable[i]) - rejectCount++; - } - - assertEquals("Only one request should be rejected!", 1, rejectCount); - - // issue get api limit calls - final HashMap<String, String> params2 = new HashMap<String, String>(); - params2.put("response", "json"); - params2.put("sessionkey", sessionKey); - String getResult = sendRequest("getApiLimit", params2); - //ApiLimitResponse loginResp = (ApiLimitResponse)fromSerializedString(getResult, ApiLimitResponse.class); - - } - }