Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 635B410756 for ; Tue, 18 Feb 2014 08:53:28 +0000 (UTC) Received: (qmail 39424 invoked by uid 500); 18 Feb 2014 08:53:25 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 39181 invoked by uid 500); 18 Feb 2014 08:53:24 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 38710 invoked by uid 99); 18 Feb 2014 08:53:04 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Feb 2014 08:53:04 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 37445829F3E; Tue, 18 Feb 2014 08:53:04 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: hugo@apache.org To: commits@cloudstack.apache.org Date: Tue, 18 Feb 2014 08:53:04 -0000 Message-Id: <5b8ed254cc544bb88564eb709407b476@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/4] Nvp and rest refactoring and more tests Repository: cloudstack Updated Branches: refs/heads/master dda47dbd6 -> 510972abd http://git-wip-us.apache.org/repos/asf/cloudstack/blob/510972ab/utils/test/com/cloud/utils/rest/RESTServiceConnectorTest.java ---------------------------------------------------------------------- diff --git a/utils/test/com/cloud/utils/rest/RESTServiceConnectorTest.java b/utils/test/com/cloud/utils/rest/RESTServiceConnectorTest.java new file mode 100644 index 0000000..d406f94 --- /dev/null +++ b/utils/test/com/cloud/utils/rest/RESTServiceConnectorTest.java @@ -0,0 +1,373 @@ +package com.cloud.utils.rest; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Collections; +//import java.util.List; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.methods.DeleteMethod; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.http.HttpStatus; +import org.junit.Before; +import org.junit.Test; + +public class RESTServiceConnectorTest { + protected static final String UUID = "aaaa"; + protected static final String UUID2 = "bbbb"; + protected static final String SCHEMA = "myTestSchema"; + protected static final String SCHEMA2 = "myTestSchema2"; + protected static final String HREF = "myTestHref"; + protected static final String HREF2 = "myTestHref2"; + protected static final String DISPLAY_NAME = "myTestName"; + protected static final String UUID_JSON_RESPONSE = "{\"uuid\" : \"aaaa\"}"; + protected static final String SEC_PROFILE_JSON_RESPONSE = + "{\"uuid\" : \"aaaa\"," + + "\"display_name\" : \"myTestName\"," + + "\"href\" : \"myTestHref\"," + + "\"schema\" : \"myTestSchema\"}"; + + protected static final String SEC_PROFILE_LIST_JSON_RESPONSE = "{\"results\" : [{\"uuid\" : \"aaaa\"," + + "\"display_name\" : \"myTestName\"," + + "\"href\" : \"myTestHref\"," + + "\"schema\" : \"myTestSchema\"}," + + "{ \"uuid\" : \"bbbb\"," + + "\"display_name\" : \"myTestName2\"," + + "\"href\" : \"myTestHref2\"," + + "\"schema\" : \"myTestSchema2\"}]," + + "\"result_count\": 2}"; + + RESTServiceConnector connector; + HttpClient client = mock(HttpClient.class); + HttpMethod method; + String type; + String uri; + + @Before + public void setUp() { + final HttpClientParams hmp = mock(HttpClientParams.class); + when(client.getParams()).thenReturn(hmp); + connector = new RESTServiceConnector(null) { + @Override + public HttpClient createHttpClient() { + return client; + } + + @Override + public HttpMethod createMethod(final String newType, final String newUri) { + type = newType; + uri = newUri; + return method; + } + }; + + connector.validation = new RESTValidationStrategy(); + connector.setAdminCredentials("admin", "adminpass"); + connector.setControllerAddress("localhost"); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteLoginWithoutHostname() throws CloudstackRESTException { + connector.setControllerAddress(null); + connector.validation.login(RESTServiceConnector.protocol, client); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteLoginWithoutCredentials() throws CloudstackRESTException { + method = mock(PutMethod.class); + connector.setAdminCredentials(null, null); + connector.validation.login(RESTServiceConnector.protocol, client); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteUpdateObjectWithoutHostname() throws CloudstackRESTException { + method = mock(PutMethod.class); + connector.setControllerAddress(null); + connector.executeUpdateObject(new String(), "/", Collections. emptyMap()); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteUpdateObjectWithoutCredentials() throws CloudstackRESTException { + method = mock(PutMethod.class); + connector.setAdminCredentials(null, null); + connector.executeUpdateObject(new String(), "/", Collections. emptyMap()); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteCreateObjectWithoutHostname() throws CloudstackRESTException { + method = mock(PostMethod.class); + connector.setControllerAddress(null); + connector.executeCreateObject(new String(), String.class, "/", Collections. emptyMap()); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteCreateObjectWithoutCredentials() throws CloudstackRESTException { + method = mock(PostMethod.class); + connector.setAdminCredentials(null, null); + connector.executeCreateObject(new String(), String.class, "/", Collections. emptyMap()); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteDeleteObjectWithoutHostname() throws CloudstackRESTException { + method = mock(DeleteMethod.class); + connector.setControllerAddress(null); + connector.executeDeleteObject("/"); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteDeleteObjectWithoutCredentials() throws CloudstackRESTException { + method = mock(DeleteMethod.class); + connector.setAdminCredentials(null, null); + connector.executeDeleteObject("/"); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteRetrieveObjectWithoutHostname() throws CloudstackRESTException { + method = mock(GetMethod.class); + connector.setControllerAddress(null); + connector.executeRetrieveObject(String.class, "/", Collections. emptyMap()); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteRetrieveObjectWithoutCredentials() throws CloudstackRESTException { + method = mock(GetMethod.class); + connector.setAdminCredentials(null, null); + connector.executeRetrieveObject(String.class, "/", Collections. emptyMap()); + } + + @Test + public void testExecuteMethod() throws CloudstackRESTException { + final GetMethod gm = mock(GetMethod.class); + + when(gm.getStatusCode()).thenReturn(HttpStatus.SC_OK); + connector.executeMethod(gm); + verify(gm, times(1)).getStatusCode(); + } + + /* Bit of a roundabout way to ensure that login is called after an un authorized result + * It not possible to properly mock login() + */ + @Test(expected = CloudstackRESTException.class) + public void testExecuteMethodWithLogin() throws CloudstackRESTException, HttpException, IOException { + final GetMethod gm = mock(GetMethod.class); + when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); + when(gm.getStatusCode()).thenReturn(HttpStatus.SC_UNAUTHORIZED).thenReturn(HttpStatus.SC_UNAUTHORIZED); + connector.executeMethod(gm); + verify(gm, times(1)).getStatusCode(); + } + + @Test + public void testExecuteCreateObject() throws CloudstackRESTException, IOException { + JsonEntity ls = new JsonEntity(); + method = mock(PostMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_CREATED); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); + ls = connector.executeCreateObject(ls, JsonEntity.class, "/", Collections. emptyMap()); + assertTrue(UUID.equals(ls.getUuid())); + verify(method, times(1)).releaseConnection(); + + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteCreateObjectFailure() throws CloudstackRESTException, IOException { + JsonEntity ls = new JsonEntity(); + method = mock(PostMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + final Header header = mock(Header.class); + when(header.getValue()).thenReturn("text/html"); + when(method.getResponseHeader("Content-Type")).thenReturn(header); + when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); + when(method.isRequestSent()).thenReturn(true); + try { + ls = connector.executeCreateObject(ls, JsonEntity.class, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteCreateObjectException() throws CloudstackRESTException, IOException { + JsonEntity ls = new JsonEntity(); + when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); + method = mock(PostMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + final Header header = mock(Header.class); + when(header.getValue()).thenReturn("text/html"); + when(method.getResponseHeader("Content-Type")).thenReturn(header); + when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); + try { + ls = connector.executeCreateObject(ls, JsonEntity.class, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test + public void testExecuteUpdateObject() throws CloudstackRESTException, IOException { + final JsonEntity ls = new JsonEntity(); + method = mock(PutMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + connector.executeUpdateObject(ls, "/", Collections. emptyMap()); + verify(method, times(1)).releaseConnection(); + verify(client, times(1)).executeMethod(method); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteUpdateObjectFailure() throws CloudstackRESTException, IOException { + final JsonEntity ls = new JsonEntity(); + method = mock(PutMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + final Header header = mock(Header.class); + when(header.getValue()).thenReturn("text/html"); + when(method.getResponseHeader("Content-Type")).thenReturn(header); + when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); + when(method.isRequestSent()).thenReturn(true); + try { + connector.executeUpdateObject(ls, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteUpdateObjectException() throws CloudstackRESTException, IOException { + final JsonEntity ls = new JsonEntity(); + method = mock(PutMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(client.executeMethod((HttpMethod)any())).thenThrow(new IOException()); + try { + connector.executeUpdateObject(ls, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test + public void testExecuteDeleteObject() throws CloudstackRESTException, IOException { + method = mock(DeleteMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + connector.executeDeleteObject("/"); + verify(method, times(1)).releaseConnection(); + verify(client, times(1)).executeMethod(method); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteDeleteObjectFailure() throws CloudstackRESTException, IOException { + method = mock(DeleteMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + final Header header = mock(Header.class); + when(header.getValue()).thenReturn("text/html"); + when(method.getResponseHeader("Content-Type")).thenReturn(header); + when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); + when(method.isRequestSent()).thenReturn(true); + try { + connector.executeDeleteObject("/"); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteDeleteObjectException() throws CloudstackRESTException, IOException { + method = mock(DeleteMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); + try { + connector.executeDeleteObject("/"); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test + public void testExecuteRetrieveObject() throws CloudstackRESTException, IOException { + method = mock(GetMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); + connector.executeRetrieveObject(JsonEntity.class, "/", Collections. emptyMap()); + verify(method, times(1)).releaseConnection(); + verify(client, times(1)).executeMethod(method); + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteRetrieveObjectFailure() throws CloudstackRESTException, IOException { + method = mock(GetMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); + final Header header = mock(Header.class); + when(header.getValue()).thenReturn("text/html"); + when(method.getResponseHeader("Content-Type")).thenReturn(header); + when(method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later."); + when(method.isRequestSent()).thenReturn(true); + try { + connector.executeRetrieveObject(JsonEntity.class, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + + @Test(expected = CloudstackRESTException.class) + public void testExecuteRetrieveObjectException() throws CloudstackRESTException, IOException { + method = mock(GetMethod.class); + when(method.getStatusCode()).thenReturn(HttpStatus.SC_OK); + when(method.getResponseBodyAsString()).thenReturn(UUID_JSON_RESPONSE); + when(client.executeMethod((HttpMethod)any())).thenThrow(new HttpException()); + try { + connector.executeRetrieveObject(JsonEntity.class, "/", Collections. emptyMap()); + } finally { + verify(method, times(1)).releaseConnection(); + } + } + +} + +class JsonEntity { + private String displayName; + private String uuid; + private String href; + private String schema; + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(final String displayName) { + this.displayName = displayName; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getHref() { + return href; + } + + public void setHref(final String href) { + this.href = href; + } + + public String getSchema() { + return schema; + } + + public void setSchema(final String schema) { + this.schema = schema; + } +} \ No newline at end of file