From 2ea37b1243aa2e1b3bb06b05b95b1755f5ff4029 Mon Sep 17 00:00:00 2001 From: jweden Date: Fri, 24 Feb 2012 17:36:31 -0500 Subject: [PATCH] Integrate groovy. Now create events and have support for concurrently creating events. --- ctct/pom.xml | 25 ++++++++++++++ .../jason/qa/ctct/TestcaseGrabber.groovy | 17 ++++++++++ .../weden/jason/qa/ctct/EventsTester.java | 27 ++++++++++++++- .../weden/jason/qa/ctct/HttpConnector.java | 34 ++++++++++--------- .../java/weden/jason/qa/ctct/TestBase.java | 23 +++++++++++++ ctct/src/main/resources/log4j.xml | 2 +- ctct/src/main/resources/testCases.properties | 24 +++++++++++++ pom.xml | 1 + readme.txt | 14 ++++++-- 9 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 ctct/src/main/groovy/weden/jason/qa/ctct/TestcaseGrabber.groovy create mode 100644 ctct/src/main/resources/testCases.properties diff --git a/ctct/pom.xml b/ctct/pom.xml index 2b915e8..1ebc43f 100644 --- a/ctct/pom.xml +++ b/ctct/pom.xml @@ -57,6 +57,21 @@ jar-with-dependencies + + org.codehaus.groovy.maven + gmaven-plugin + ${gmaven-version} + + + + generateStubs + compile + generateTestStubs + testCompile + + + + @@ -70,6 +85,16 @@ json-simple ${jsonSimple-version} + + org.codehaus.groovy.maven.runtime + gmaven-runtime-1.6 + ${gmaven-version} + + + org.codehaus.groovy.maven + gmaven-mojo + ${gmaven-version} + diff --git a/ctct/src/main/groovy/weden/jason/qa/ctct/TestcaseGrabber.groovy b/ctct/src/main/groovy/weden/jason/qa/ctct/TestcaseGrabber.groovy new file mode 100644 index 0000000..6ee170d --- /dev/null +++ b/ctct/src/main/groovy/weden/jason/qa/ctct/TestcaseGrabber.groovy @@ -0,0 +1,17 @@ +package weden.jason.qa.ctct; + +/** + * This is the groovy class which puts the test cases in the external testCases.properties + * file into a data structure for the java program to use. + */ +public class TestcaseGrabber { + protected List> getTestcases() { + def testConfig = null; + try { + testConfig = new ConfigSlurper().parse(new File('src/main/resources/testCases.properties').toURL()) + } catch (Exception ex) { + println('Error reading in test case property file' + ex.printStackTrace()); + } + return testConfig.testCases + } +} diff --git a/ctct/src/main/java/weden/jason/qa/ctct/EventsTester.java b/ctct/src/main/java/weden/jason/qa/ctct/EventsTester.java index e9d1cfb..7e5fa7b 100644 --- a/ctct/src/main/java/weden/jason/qa/ctct/EventsTester.java +++ b/ctct/src/main/java/weden/jason/qa/ctct/EventsTester.java @@ -6,12 +6,13 @@ import org.testng.Assert; import org.testng.annotations.Test; +import java.util.List; import java.util.Map; public class EventsTester extends TestBase { private static final Logger LOG = LogManager.getLogger(EventsTester.class); - @Test(description = "Looking for correct content-type when getting events", invocationCount = 5, threadPoolSize = 5, groups = "fast") + @Test(description = "Looking for correct content-type when getting events", invocationCount = 1, threadPoolSize = 1, groups = "fast") public void getEventsAndEnsureContentTypeTest() throws Exception { String user = System.getProperty("user"); HttpResponse resp = httpConn.sendRequest("https://api.constantcontact.com/ws/customers/" + user + "/events", @@ -38,4 +39,28 @@ public void badOauth2Login() throws Exception { Assert.assertEquals(jsonResult.get("error_description"), "Invalid verification code: d", "Verifying error description for bad oauth2 login"); } + + @Test(description = "Looking for correct content-type when getting events", dataProvider = "queries", groups = "fast") + public void createEventsTest(final String testDescription, final String xmlToUse) throws Exception { + String user = System.getProperty("user"); + LOG.info("Testing scenario: " + testDescription); + HttpResponse resp = httpConn.sendRequest("https://api.constantcontact.com/ws/customers/" + user + "/events", + HTTPMethod.POST, xmlToUse); + httpConn.getBody(resp); + + Assert.assertEquals(resp.getStatusLine().getStatusCode(), 201, + "Looking for success status code for event creation"); + } + + @Test(description = "Looking for correct content-type when getting events", invocationCount = 5, threadPoolSize = 5, groups = "fast") + public void createConcurrentEventsTest() throws Exception { + String user = System.getProperty("user"); + final List> testCases1 = new TestcaseGrabber().getTestcases(); + HttpResponse resp = httpConn.sendRequest("https://api.constantcontact.com/ws/customers/" + user + "/events", + HTTPMethod.POST, testCases1.get(0).get("xmlToUse")); + httpConn.getBody(resp); + + Assert.assertEquals(resp.getStatusLine().getStatusCode(), 201, + "Looking for success status code for each concurrent event creation"); + } } diff --git a/ctct/src/main/java/weden/jason/qa/ctct/HttpConnector.java b/ctct/src/main/java/weden/jason/qa/ctct/HttpConnector.java index c9db655..d8dbefe 100644 --- a/ctct/src/main/java/weden/jason/qa/ctct/HttpConnector.java +++ b/ctct/src/main/java/weden/jason/qa/ctct/HttpConnector.java @@ -2,9 +2,6 @@ import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; @@ -12,18 +9,15 @@ import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.util.EntityUtils; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import static org.apache.http.auth.AuthScope.ANY_PORT; +import javax.xml.bind.DatatypeConverter; +import java.io.*; public class HttpConnector { private static final Logger LOG = LogManager.getLogger(HttpConnector.class); @@ -37,15 +31,9 @@ protected void initialize() { new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry); httpclient = new DefaultHttpClient(cm); - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope("api.constantcontact.com", ANY_PORT), - new UsernamePasswordCredentials(System.getProperty("apikey") + "%" + System.getProperty("user"), - System.getProperty("password"))); - httpclient.setCredentialsProvider(credsProvider); } - protected HttpResponse sendRequest(String uri, HTTPMethod httpMethod) throws IOException { + protected HttpResponse sendRequest(String uri, HTTPMethod httpMethod, String... entityBody) throws IOException { HttpRequestBase httpRequest = null; switch (httpMethod) { case GET: @@ -54,6 +42,12 @@ protected HttpResponse sendRequest(String uri, HTTPMethod httpMethod) throws IOE case POST: httpRequest = new HttpPost(uri); + if (entityBody.length > 0) { + String body = entityBody[0]; + InputStream is = new ByteArrayInputStream(body.getBytes()); + InputStreamEntity ie = new InputStreamEntity(is, body.length()); + ((HttpPost) httpRequest).setEntity(ie); + } break; } @@ -61,6 +55,14 @@ protected HttpResponse sendRequest(String uri, HTTPMethod httpMethod) throws IOE LOG.debug("executing request to: " + httpRequest.getURI()); } + httpRequest.setHeader("Accept", "application/atom+xml"); + httpRequest.setHeader("Content-Type", "application/atom+xml"); + + String userPassToUse = System.getProperty("apikey") + "%" + System.getProperty("user") + ":" + + System.getProperty("password"); + String encoding = DatatypeConverter.printBase64Binary(userPassToUse.getBytes()); + httpRequest.setHeader("Authorization", "Basic " + encoding); + return httpclient.execute(httpRequest); } diff --git a/ctct/src/main/java/weden/jason/qa/ctct/TestBase.java b/ctct/src/main/java/weden/jason/qa/ctct/TestBase.java index 4bf6023..c84a4b3 100644 --- a/ctct/src/main/java/weden/jason/qa/ctct/TestBase.java +++ b/ctct/src/main/java/weden/jason/qa/ctct/TestBase.java @@ -4,6 +4,10 @@ import org.apache.log4j.Logger; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; + +import java.util.List; +import java.util.Map; public class TestBase { private static final Logger LOG = LogManager.getLogger(TestBase.class); @@ -15,6 +19,25 @@ public void setup() throws Exception { httpConn.initialize(); } + @DataProvider(name = "queries") + public Object[][] obtainTestCasesDataProvider() { + final List> testCases = new TestcaseGrabber().getTestcases(); + + final Object[][] dataProvider = new Object[testCases.size()][2]; + int outerArrayIndex = 0; + + for (final Map testCase : testCases) { + final Object[] innerArray = new Object[2]; + LOG.info(testCase.get("testDescription")); + innerArray[0] = testCase.get("testDescription"); + innerArray[1] = testCase.get("xmlToUse"); + + dataProvider[outerArrayIndex] = innerArray; + outerArrayIndex++; + } + + return dataProvider; + } @AfterClass(description = "Gracefully shut down http connection") public void tearDown() throws Exception { diff --git a/ctct/src/main/resources/log4j.xml b/ctct/src/main/resources/log4j.xml index eb84e55..5a5254c 100644 --- a/ctct/src/main/resources/log4j.xml +++ b/ctct/src/main/resources/log4j.xml @@ -23,7 +23,7 @@ - + diff --git a/ctct/src/main/resources/testCases.properties b/ctct/src/main/resources/testCases.properties new file mode 100644 index 0000000..43dd1cf --- /dev/null +++ b/ctct/src/main/resources/testCases.properties @@ -0,0 +1,24 @@ +testCases = [ +['testDescription': 'Initial Test', +'xmlToUse' : ''' + + + + 2011 ''' + java.util.UUID.randomUUID().toString() + ''' Run For Dimes 5K + 2011 Run For Dimes 5K + OUTDOORS_RECREATION + 2012-08-14T09:00:00-04:00 + 2012-09-14T18:00:00-04:00 + + US/Eastern + + + John Smith + + + Myer Arena + + + + '''] +] \ No newline at end of file diff --git a/pom.xml b/pom.xml index aec0eec..6044abd 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ 6.4 4.1.3 1.1 + 1.0 diff --git a/readme.txt b/readme.txt index 19d9ea4..2ccee13 100644 --- a/readme.txt +++ b/readme.txt @@ -12,8 +12,18 @@ Commons HttpClient). The first test is a multi-threaded test that sends in the same request 5 times and ensures a correct response (Content-Type header) to each of -these requests. The second test sends in a bad oauth2 login and parses -the json response for correct error messages. +these requests. + +The second test sends in a bad oauth2 login and parses +the json response (using the json-simple library) for correct error messages. + +The third test uses built-in data-driven TestNG functionality with the help of +groovy to create an event. The idea here is that one could put multiple test cases +in the groovy testCases.properties file. 201 created response is verified. + +The fourth test concurrently creates events. The TestNG annotation can be easily changed +to a higher number from the current 5. (I've successfully created 500 concurrent events). +201 created response is verified for each response. This was tested with the following environment: