Skip to content

Commit

Permalink
Integrate groovy. Now create events and have support for concurrently…
Browse files Browse the repository at this point in the history
… creating events.
  • Loading branch information
jweden committed Feb 24, 2012
1 parent f18bb9e commit 2ea37b1
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 20 deletions.
25 changes: 25 additions & 0 deletions ctct/pom.xml
Expand Up @@ -57,6 +57,21 @@
<descriptorId>jar-with-dependencies</descriptorId>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>${gmaven-version}</version>
<executions>
<execution>
<goals>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
Expand All @@ -70,6 +85,16 @@
<artifactId>json-simple</artifactId>
<version>${jsonSimple-version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy.maven.runtime</groupId>
<artifactId>gmaven-runtime-1.6</artifactId>
<version>${gmaven-version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-mojo</artifactId>
<version>${gmaven-version}</version>
</dependency>
</dependencies>
</project>

17 changes: 17 additions & 0 deletions 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<Map<String, String>> 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
}
}
27 changes: 26 additions & 1 deletion ctct/src/main/java/weden/jason/qa/ctct/EventsTester.java
Expand Up @@ -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",
Expand All @@ -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<Map<String, String>> 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");
}
}
34 changes: 18 additions & 16 deletions ctct/src/main/java/weden/jason/qa/ctct/HttpConnector.java
Expand Up @@ -2,28 +2,22 @@

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;
import org.apache.http.conn.ClientConnectionManager;
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);
Expand All @@ -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:
Expand All @@ -54,13 +42,27 @@ 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;
}

if (LOG.isDebugEnabled()) {
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);
}

Expand Down
23 changes: 23 additions & 0 deletions ctct/src/main/java/weden/jason/qa/ctct/TestBase.java
Expand Up @@ -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);
Expand All @@ -15,6 +19,25 @@ public void setup() throws Exception {
httpConn.initialize();
}

@DataProvider(name = "queries")
public Object[][] obtainTestCasesDataProvider() {
final List<Map<String, String>> testCases = new TestcaseGrabber().getTestcases();

final Object[][] dataProvider = new Object[testCases.size()][2];
int outerArrayIndex = 0;

for (final Map<String, String> 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 {
Expand Down
2 changes: 1 addition & 1 deletion ctct/src/main/resources/log4j.xml
Expand Up @@ -23,7 +23,7 @@
</category>

<root>
<priority value="DEBUG"/>
<priority value="TRACE"/>
<!-- appender-ref ref="filelog"/ -->
<appender-ref ref="ConsoleAppender"/>
</root>
Expand Down
24 changes: 24 additions & 0 deletions ctct/src/main/resources/testCases.properties
@@ -0,0 +1,24 @@
testCases = [
['testDescription': 'Initial Test',
'xmlToUse' : '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
<atom:content>
<Event>
<Name>2011 ''' + java.util.UUID.randomUUID().toString() + ''' Run For Dimes 5K</Name>
<Title>2011 Run For Dimes 5K</Title>
<EventType>OUTDOORS_RECREATION</EventType>
<StartDate>2012-08-14T09:00:00-04:00</StartDate>
<EndDate>2012-09-14T18:00:00-04:00</EndDate>
<TimeZone>
<ID>US/Eastern</ID>
</TimeZone>
<EventContact>
<Name>John Smith</Name>
</EventContact>
<EventLocation>
<Location>Myer Arena</Location>
</EventLocation>
</Event>
</atom:content>
</atom:entry>''']
]
1 change: 1 addition & 0 deletions pom.xml
Expand Up @@ -12,6 +12,7 @@
<testNG-version>6.4</testNG-version>
<httpclient-version>4.1.3</httpclient-version>
<jsonSimple-version>1.1</jsonSimple-version>
<gmaven-version>1.0</gmaven-version>
</properties>
<dependencies>
<dependency>
Expand Down
14 changes: 12 additions & 2 deletions readme.txt
Expand Up @@ -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:

Expand Down

0 comments on commit 2ea37b1

Please sign in to comment.