How To Test an Extension
Overview
The alakai platform includes a robust test "harness," that works in conjuction with the junit test framework, that you can use to test your newly developed Extension. The "harness" is implemented as a custom maven plugin. The intent of this how to is to highlight the usage of the plugin through various different examples - all of which fall into two primary categories: unit test examples and integration test examples.
Unit Testing
First off, you need to locate your unit test source files in the correct location. All unit tests, regardless of type, must be defined within the project sub-directory depicted below. If you don't define any sources here, the plugin will skip the unit test execution phase.

Note that if you want to install your artifact without running your tests (this skips integration tests also) run the mvn command with the following argument:
mvn install -Dmaven.test.skip=true
Now - the way in which you code your unit test differs upon the type of unit test you intend to implement. They type of test you write depends upon how you define the the term 'unit,' i.e. is the unit bigger than a bread box?
Plain Vanilla Unit Tests
The first type of unit test is the classic, plain vanilla type which typically tests an individual class. Note that you'll find nothing special here in regards to this type of test, i.e. you can implement these just as you would within any typical java project, e.g.
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class MyUnitTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void test() throws Exception {
}
}
Because the test harness uses junit to execute the actual test and to generate the reports, you'll want to make sure that your unit tests classpath includes the junit jar dependency. To do this, add the junit artifact as a dependency with scope 'test' as shown below. If you used the extension project archetype plugin to create your project, this dependency was added for you. After adding any dependency to your project, you'll want to update the classpath used by your IDE. Our custom eclipse plugin can be used for this purpose. It understands the various EOA dependency types and configures the classpath accordingly.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.2</version>
<scope>test</scope>
</dependency>
Extension Unit Tests
The second type of unit test is one where the unit represents your entire extension. This type of unit test tests the extension as a whole without relying upon the existence of other 'real' extension objects (we say 'real' as compared to 'mock' or 'stubbed'). Think of this as a sort of 'clean room' test where your test is insulated from bugs which may exist within the other dependent extension objects.
An extension unit test tests your extension within the context of a light-weight, mocked alakai system. It allows you to test that your extension provides the expected behavior from the perspective of the alakai system, e.g. that the factory bootstraps correctly and that it creates extension instances as expected. It also allows you to test your external API, e.g. that it is correctly implemented and that your API classes correctly switch the context classloader, etc ...
To implement this type of unit test, first off make sure that you're project defines the following 'test' dependency. Again, if you used the extension project archetype plugin to create your project, the dependency was added for you. And remember, after adding any dependency to your project, you'll want to update the classpath used by your IDE.
<dependency>
<groupId>org.bluestemsoftware.open.eoa.ext</groupId>
<artifactId>ext-system-test</artifactId>
<version>0.8.2.0</version>
<scope>test</scope>
</dependency>
To facilitate unit testing your extension, we've created an abstract class which you will want to extend. The class implements a 'partially' functional alakai system which will bootstrap your extension factory and instantiate an instance of your extension for you. You can than retrieve the extension instance from alakai and exercise its API. Here's a sample test which does just that. Make sure to take note of the comments we inserted which explain some conveniences available to you.
import java.io.File;
import java.util.HashSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.bluestemsoftware.open.eoa.test.system.AbstractUnitTest;
import org.bluestemsoftware.specification.eoa.ext.feature.FeatureFactory;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.HostInfo;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.ClearTextPassword;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.Credential;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.CredentialStore;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.CredentialStoreFeature;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.Password;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
public class UnitTest extends AbstractUnitTest {
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Test
public void testDefaultFeatureConfiguration() throws Exception {
// the instance variable 'systemContext' can be used to retrieve
// the 'partially' functional system instance provided by
// our AbstractUnitTest ancestor
org.bluestemsoftware.specification.eoa.system.System system = systemContext.getSystem();
// use the system instance to retrieve an instance of our
// extension, i.e. a CredentialStoreFeature instance. note that
// the feature is initialized with 'default' configuration
CredentialStoreFeature feature = system.getServer().getFeature(CredentialStoreFeature.class);
// test the feature by exercising its api ...
CredentialStore cstore = feature.getCredentialStore(CredentialStoreFeature.DEFAULT_CSTORE_ID);
Assert.assertNotNull(cstore);
}
@Test
public void testAlternateFeatureConfiguration() throws Exception {
// retrieve a test resource from the unit test 'resources'
// directory. note that an instance variable exists on
// ancestor which you can use to easily locate the directory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new File(resourcesDir, "configuration-1.xml"));
// the instance variable 'systemContext' can be used to retrieve
// the 'partially' functional system instance provided by
// our AbstractUnitTest ancestor
org.bluestemsoftware.specification.eoa.system.System system = systemContext.getSystem();
// now we set alternate configuration on our extension provider
// prior to initializing the feature instance
FeatureFactory factory = system.getFeatureFactory(CredentialStoreFeature.TYPE, null);
CredentialStoreFeature feature = (CredentialStoreFeature)factory.createFeature();
CredentialStoreFeatureImpl provider = (CredentialStoreFeatureImpl)feature.getExtensionProvider();
provider.setConfiguration(doc.getDocumentElement());
feature.init(new HashSet<ManagementContext>());
// verify that the feature was intialized as expected
CredentialStore cstore = feature.getCredentialStore(CredentialStoreFeature.DEFAULT_CSTORE_ID);
Credential credential = cstore.getCredential(new HostInfo("myhost"), "default", "sa");
Assert.assertTrue(credential.getUserName().equals("sa"));
Password password = credential.getPassword();
Assert.assertTrue(((ClearTextPassword)password).getText().equals("alakai"));
}
}
Mocking Unit Test Dependencies
Note that the extension tested above had no dependencies on other extension objects in order to perform its behavior. If it did, these extensions could be mocked and/or stubbed. If you're accustomed to using a mock testing framework, e.g. easymock, etc ..., feel free to add the necessary libraries to your tests classpath by defining the artifact within your extension project with 'test' scope. Again, after adding the dependency you'll want to update the classpath used by your IDE. To create mock and or stubbed extension objects for your unit test, override the getSystemDependencies() method on the AbstractUnitTest ancestor. Here's an example which 'stubs' the dependent extension behavior, i.e. rather than using the more sophisticated 'mock' approach, e.g. as provided by easymock.
package com.my.company.test;
import java.io.BufferedReader;
import java.util.List;
import org.bluestemsoftware.open.eoa.test.system.AbstractUnitTest;
import org.bluestemsoftware.open.eoa.test.system.dependency.FactoryDependencyImpl;
import org.bluestemsoftware.open.eoa.test.system.feature.HTTPClientFeatureFactoryProvider;
import org.bluestemsoftware.open.eoa.test.system.util.MockExtensionProviderFactory;
import org.bluestemsoftware.specification.eoa.FactoryDependency;
import org.bluestemsoftware.specification.eoa.SystemDependencies;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClient;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeature;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientRequest;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientResponse;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientRequest.Method;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class MyUnitTest extends AbstractUnitTest {
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Test
public void test() throws Exception {
// retrieve in instance of our stubbed feature provider
// and verify that it returns the canned response we
// are expecting
org.bluestemsoftware.specification.eoa.system.System system = systemContext.getSystem();
HTTPClientFeature f = system.getServer().getFeature(HTTPClientFeature.class);
HTTPClient client = f.createHTTPClient();
HTTPClientRequest req = new HTTPClientRequest("http://foo", Method.GET){};
HTTPClientResponse res = client.doSend(req);
String result = null;
BufferedReader in = null;
try {
in = new BufferedReader(res.getContent().getCharacterStream());
result = in.readLine();
} finally {
if (in != null) {
in.close();
}
}
assert(result.equals("canned"));
}
@Override
public SystemDependencies getSystemDependencies() {
// invoke method on super which will add our extension
// artifact as a 'system' dependency. note that // what we are doing here is simulating the model
// that would have existed had an actual alakai
// system instance parsed the system's pom file
SystemDependencies sd = super.getSystemDependencies();
List<FactoryDependency> efds = sd.getFactoryDependencies();
// assuming our extension depends upon the HTTPClientFeature
// to implement its behavior, we use the
// HTTPClientFeatureFactoryProvider class which is provided
// within the ext-system-test library to wrap our
// stubbed factory provider
MockExtensionProviderFactory mp = new StubbedFactoryProvider();
HTTPClientFeatureFactoryProvider p = new HTTPClientFeatureFactoryProvider(mp);
// create the dependency. note that we do not pass the
// organization id and we use a default name for the
// artifact id, i.e. the versionless ref is unimportant
// in this case. it may, however, be important within
// context of an integration test which explained
// within a different example
String name = HTTPClientFeatureFactoryProvider.NAME;
FactoryDependency efd = new FactoryDependencyImpl(name, p);
efds.add(efd);
// now we return the system dependencies. note that what
// we are doing here is mocking up the dependencies that
return sd;
}
}
package com.my.company.test;
import java.lang.reflect.Method;
import org.bluestemsoftware.open.eoa.test.system.util.MockExtensionProviderFactory;
import org.bluestemsoftware.specification.eoa.ext.ExtensionException;
import org.bluestemsoftware.specification.eoa.ext.Extension.Provider;
public class StubbedFactoryProvider implements MockExtensionProviderFactory {
@Override
public Provider createExtensionProvider(Method method, Object[] args) throws ExtensionException {
// when instance of HTTPClientFeatureFactoryProvider that
// 'wraps' this instance is invoked and asked by alakai
// to create any object which implements Extension.Provider,
// the wrapper delegates the call to us via this method.
if (method.getName().equals("spi_createFeature")) {
// the spi_createFeature method has no arguments, but if it
// did, we could evaluate them here and perhaps pass
// them to our StubbedFeatureProvider instance so that
// it can behave as expected
return new StubbedFeatureProvider();
} else {
// note that the HTTPClientFeatureFactory.Provider has
// no other methods which create Extension.Provider
// instances, but if it did, we would introspect and
// handle accordingly
throw new ExtensionException("Unexpected method");
}
}
}
package com.my.company.test;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import org.bluestemsoftware.specification.eoa.ext.Extension;
import org.bluestemsoftware.specification.eoa.ext.feature.FeatureException;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.HostInfo;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeature;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeatureException;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientRequest;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientResponse;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeature.ClientAuthInfo;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClient;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
public class StubbedFeatureProvider implements HTTPClientFeature.Provider {
@Override
public HTTPClient spi_createHTTPClient() throws HTTPClientFeatureException {
return new HTTPClientImpl();
}
@Override
public HTTPClient spi_createHTTPClient(HostInfo hostInfo, ClientAuthInfo authInfo) throws HTTPClientFeatureException {
return new HTTPClientImpl();
}
static class HTTPClientImpl implements HTTPClient {
@Override
public HTTPClientResponse doSend(HTTPClientRequest request) throws IOException {
// here's where you would stub out the required behavior.
// based upon the requirements of your test, you would
// return a 'canned' response, based upon, e.g. the
// content of the request ...
return new HTTPClientResponse() {
@Override
public InputSource getContent() throws IOException {
return new InputSource(new StringReader("canned")) {
};
}
...
};
}
}
...
}
So that's pretty much a wrap as far as unit testing is concerned. We realize, however, that mocking up the behavior for all dependent extension objects may be difficult to pull off, especially if the dependent extension objects provide complex behavior, e.g. a SOAP binding, WSDL Feature, WS-Policy Feature, etc ... No worries - for this type of test our test harness supports integration based testing.
Integration Testing
In situations where you need to test your Extension within the context of an actual running alakai system, including its interaction with other 'real' (we say 'real' as compared to 'mock' or 'stubbed') extensions - you will write an integration test. Integration tests must, by convention, be located within a specific subdirectory, as depicted below. Note that you can have as many 'suite' sub-directories under the src/it sub-directory as you require. Each one should represent a collection of related tests, e.g. related by use case. Note also that the example below uses the name suite1 as the suite name, but you can name your test suites however you'd like.

When the test harness runs, it will run an actual alakai system instance using the libraries defined within the system lib directory of the alakai installation pointed to by the environment variable ALAKAI_HOME. Instead of using the system configuration files located within this directory, however, the plugin will use the system configuration files defined within your integration test suite subdirectory, which by convention must be located within the following subdirectory:

To facilitate integration testing your extension, we've created an abstract class which you will want to extend. Note to add this class along with the other supporting system test classes to your classpath, you must define the ext-system-test artifact as a 'test' scoped dependency as described within the unit test section. Here's an example of a system integration test. Make sure to take note of the comments we inserted which explain some of the conveniences available to you.
package com.my.company.it.suite1;
import org.bluestemsoftware.open.eoa.test.system.AbstractIntegrationTest;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.CredentialStore;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.cstore.CredentialStoreFeature;
import org.bluestemsoftware.specification.eoa.system.server.Server;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MyIntegrationTest extends AbstractIntegrationTest {
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Test
public void testDefaultFeatureConfiguration() throws Exception {
// retrieve a reference to the alakai server from the running alakai
// system instance which was set as an instance variable by our
// ancestor class
Server server = system.getServer();
// use the server to retrieve an instance of our
// extension, i.e. a CredentialStoreFeature instance.
CredentialStoreFeature feature = server.getFeature(CredentialStoreFeature.class);
// test the feature by exercising its api ...
CredentialStore cstore = feature.getCredentialStore(CredentialStoreFeature.DEFAULT_CSTORE_ID);
Assert.assertNotNull(cstore);
}
}
Mocking Integration Test Dependencies
When writing integration tests, there are two different types of dependencies upon which your extension may depend within the context of your tests: extension dependencies and component dependences.
Mocking Extension Dependencies
For example sake, the extension tested in the code sample above had no dependencies on other extension objects (which means it could/should have been written as a unit test.) By writing an integration test, the implicit assumption is that your extension relies on other extension objects at runtime. So, when writing your test, you have a choice. You can either use 'real' extensions or you can mock/stub the required dependencies. To use real extensions, you define them just as you would within an actual alakai system instance, but instead using the configuration files within your suite specific sub-directory. To create mock and or stubbed extension objects for your integration tests, you extend the AbstractSystemConfiguration class as in the following example:
package com.my.company.it.suite1;
import java.util.HashSet;
import java.util.Set;
import org.bluestemsoftware.open.eoa.test.system.cfg.AbstractSystemConfiguration;
import org.bluestemsoftware.open.eoa.test.system.dependency.FactoryDependencyImpl;
import org.bluestemsoftware.open.eoa.test.system.feature.HTTPClientFeatureFactoryProvider;
import org.bluestemsoftware.open.eoa.test.system.util.MockExtensionProviderFactory;
import org.bluestemsoftware.specification.eoa.FactoryDependency;
public class SystemConfigurationImpl extends AbstractSystemConfiguration {
@Override
protected Set<FactoryDependency> getMockFactoryDependencies() {
Set<FactoryDependency> efds = new HashSet<FactoryDependency>();
// assuming our extension depends upon the HTTPClientFeature
// to implement its behavior, we use the
// HTTPClientFeatureFactoryProvider class which is provided
// within the ext-system-test library to wrap our
// stubbed factory provider
MockExtensionProviderFactory mp = new StubbedFactoryProvider();
HTTPClientFeatureFactoryProvider p = new HTTPClientFeatureFactoryProvider(mp);
// create the dependency. note that we do not pass the
// organization id and we use a default name for the
// artifact id, i.e. the versionless ref is unimportant
// in this case. to override a dependency which may
// be defined by your extension, there are alternate
// constructors you can use to specify the exact
// versionless ref
String name = HTTPClientFeatureFactoryProvider.NAME;
FactoryDependency efd = new FactoryDependencyImpl(name, p);
efds.add(efd);
return efds;
}
}
package com.my.company.it.suite1;
import java.lang.reflect.Method;
import org.bluestemsoftware.open.eoa.test.system.util.MockExtensionProviderFactory;
import org.bluestemsoftware.specification.eoa.ext.ExtensionException;
import org.bluestemsoftware.specification.eoa.ext.Extension.Provider;
public class StubbedFactoryProvider implements MockExtensionProviderFactory {
@Override
public Provider createExtensionProvider(Method method, Object[] args) throws ExtensionException {
// when instance of HTTPClientFeatureFactoryProvider that
// 'wraps' this instance is invoked and asked by alakai
// to create any object which implements Extension.Provider,
// the wrapper delegates the call to us via this method.
if (method.getName().equals("spi_createFeature")) {
// the spi_createFeature method has no arguments, but if it
// did, we could evaluate them here and perhaps pass
// them to our StubbedFeatureProvider instance so that
// it can behave as expected
return new StubbedFeatureProvider();
} else {
// note that the HTTPClientFeatureFactory.Provider has
// no other methods which create Extension.Provider
// instances, but if it did, we would introspect and
// handle accordingly
throw new ExtensionException("Unexpected method");
}
}
}
package com.my.company.it.suite1;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import org.bluestemsoftware.specification.eoa.ext.Extension;
import org.bluestemsoftware.specification.eoa.ext.feature.FeatureException;
import org.bluestemsoftware.specification.eoa.ext.feature.auth.HostInfo;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeature;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeatureException;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientRequest;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientResponse;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClientFeature.ClientAuthInfo;
import org.bluestemsoftware.specification.eoa.ext.feature.http.client.HTTPClient;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
public class StubbedFeatureProvider implements HTTPClientFeature.Provider {
@Override
public HTTPClient spi_createHTTPClient() throws HTTPClientFeatureException {
return new HTTPClientImpl();
}
@Override
public HTTPClient spi_createHTTPClient(HostInfo hostInfo, ClientAuthInfo authInfo) throws HTTPClientFeatureException {
return new HTTPClientImpl();
}
static class HTTPClientImpl implements HTTPClient {
@Override
public HTTPClientResponse doSend(HTTPClientRequest request) throws IOException {
// here's where you would stub out the required behavior.
// based upon the requirements of your test, you would
// return a 'canned' response, based upon, e.g. the
// content of the request ...
return new HTTPClientResponse() {
@Override
public InputSource getContent() throws IOException {
return new InputSource(new StringReader("canned")) {
};
}
...
};
}
}
...
}
Mocking Component Dependencies
At some point, you will more than likely want to provide component deployments to be used within the context of your tests. Rather than having to set-up the component deployments as separate projects, we've provided a method within AbstractSystemConfiguration that you can override to provide these dependencies. Here's an example:
package com.my.company.it.suite1;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import org.bluestemsoftware.open.eoa.test.system.cfg.AbstractSystemConfiguration;
import org.bluestemsoftware.open.eoa.test.system.dependency.ComponentDependencyImpl;
import org.bluestemsoftware.specification.eoa.ComponentDependency;
public class SystemConfigurationImpl extends AbstractSystemConfiguration {
@Override
protected Set<ComponentDependency> getMockComponentDependencies() {
Set<ComponentDependency> cds = new HashSet<ComponentDependency>();
File file = new File(resourcesDir, "/alakai/components/m1.eoa-component");
cds.add(new ComponentDependencyImpl(file, "m1.eoa-component"));
file = new File(resourcesDir, "/alakai/components/m2.eoa-component");
cds.add(new ComponentDependencyImpl(file, "m2.eoa-component"));
file = new File(resourcesDir, "/alakai/components/m3.eoa-component");
cds.add(new ComponentDependencyImpl(file, "m3.eoa-component"));
return cds;
}
}
The example above references three mock component deployments, each of which is in 'expanded' form and all of which are defined within the suite specific subdirectory as depicted below. In case you're wondering, the 'm1,' 'm2,' and 'm3' prefix stands for 'mock1,' etc ...

Registering Your Configuration Class
Now the last step in defining mocked/stubbed dependencies for your integration test requires that you tell the test harness how to load your implementation of AbstractSystemConfiguration. To do this, you simply overwrite the default class name contained within the following file with the fully qualified name of your implementation (the plugin uses the java service provider mechanism to load the configuration class.)

Testing Interoperability
If you're testing an application, a new engine type or a new ws-* binding module, you can excercise its behavior by invoking it from an external client. Our client-based test harness, wraps the Axis2 framework which allows you to write an Axis2 client application which invokes your alakai extension. This is especially useful in situations where you are testing your extension for interoperability, e.g. in terms of compliance with a certain web specification. Axis is, afterall, the gold standard for interoperability. By convention, your client based tests must be located in the following directory.

To configure the Axis2 environment, you update the required Axis2 configuration files. You'll notice that the following sub-directory contains the directory structure expected by Axis including a conf, modules and services sub-directory.

If you're familiar with developing Axis2 based client applications and/or services, configuring the client based test harness will be straight forward. When you run maven, the test harness will first execute your system based tests. It will then continue to run your system test instance while it forks a separate JVM within which your client tests will execute. Note that when configuring your tests classpath, you will want to separate the classes which are defined on the 'client' JVM's classpath from those which are defined on the 'system' tests JVM. To do this, please refer to the plugin usage page. For reference purposes, here is a sample client based test which we used to test our SOAP Binding implementation.
package org.bluestemsoftware.open.eoa.ext.binding.soap.dfault.it.http.mservice.client;
import static org.junit.Assert.assertEquals;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.OperationClient;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.util.CallbackReceiver;
import org.bluestemsoftware.open.eoa.test.client.AbstractClientTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Tests WSDL 2.0 content models.
*/
public class ContentModelTest extends AbstractClientTest {
@Before
public void setUp() throws Exception {
super.setUp();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
@Test
public void test() throws Exception {
testAnyMessage();
testMultiPartEmptyMessage();
testSinglePartEmptyMessage();
}
/*
* tests content model #any. note that this can only be described via WSDL 2.0
*/
private void testAnyMessage() throws Exception {
String address = "http://localhost:8090/eoa/ws/1.2/ValueLookupService/SOAP12Endpoint/";
EndpointReference targetEPR = new EndpointReference(address);
ServiceClient client = new ServiceClient(configurationContext, null);
client.engageModule("addressing");
Options options = new Options();
options.setTo(targetEPR);
options.setAction("http://com.mycompany/eoa/1.2/MyInterface/echoAnyRequest");
options.setTimeOutInMilliSeconds(1000000);
options.setSoapVersionURI("http://www.w3.org/2003/05/soap-envelope");
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
client.setOptions(options);
AxisService axisService = client.getAxisService();
AxisOperation axisOperation = axisService.getOperation(ServiceClient.ANON_OUT_IN_OP);
axisOperation.setMessageReceiver(new CallbackReceiver());
OperationClient mep = client.createClient(ServiceClient.ANON_OUT_IN_OP);
MessageContext request = new MessageContext();
request.setServiceContext(client.getServiceContext());
SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
SOAPEnvelope soapEnvelope = fac.getDefaultEnvelope();
OMNamespace omNs = fac.createOMNamespace("http://any/namespace", "ns");
OMElement anyPayload = fac.createOMElement("any", omNs);
anyPayload.addChild(fac.createOMText(anyPayload, "hi"));
soapEnvelope.getBody().addChild(anyPayload);
request.setEnvelope(soapEnvelope);
mep.addMessageContext(request);
mep.execute(true);
MessageContext response = mep.getMessageContext("In");
SOAPEnvelope responseEnvelope = response.getEnvelope();
OMElement responsePayload = responseEnvelope.getBody().getFirstElement();
String echo = responsePayload.getText();
assertEquals(echo, "hi");
}
/*
* tests interface described via WSDL 2.0 where content model is #none
*/
private void testSinglePartEmptyMessage() throws Exception {
String address = "http://localhost:8090/eoa/ws/1.2/ValueLookupService/SOAP12Endpoint/";
EndpointReference targetEPR = new EndpointReference(address);
ServiceClient client = new ServiceClient(configurationContext, null);
client.engageModule("addressing");
Options options = new Options();
options.setTo(targetEPR);
options.setAction("http://com.mycompany/eoa/1.2/MyInterface/getVersionRequest");
options.setTimeOutInMilliSeconds(1000000);
options.setSoapVersionURI("http://www.w3.org/2003/05/soap-envelope");
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
client.setOptions(options);
AxisService axisService = client.getAxisService();
AxisOperation axisOperation = axisService.getOperation(ServiceClient.ANON_OUT_IN_OP);
axisOperation.setMessageReceiver(new CallbackReceiver());
OperationClient mep = client.createClient(ServiceClient.ANON_OUT_IN_OP);
MessageContext request = new MessageContext();
request.setServiceContext(client.getServiceContext());
SOAPFactory soapFactory = OMAbstractFactory.getSOAP12Factory();
SOAPEnvelope soapEnvelope = soapFactory.getDefaultEnvelope();
request.setEnvelope(soapEnvelope);
mep.addMessageContext(request);
mep.execute(true);
MessageContext response = mep.getMessageContext("In");
SOAPEnvelope responseEnvelope = response.getEnvelope();
OMElement responsePayload = responseEnvelope.getBody().getFirstElement();
String version = responsePayload.getFirstElement().getText();
assertEquals(version, "1.1");
}
/*
* tests interface described via WSDL 1.1 where abstract message is empty
* and binding binds no soap body part, i.e. emulates content model #none
*/
private void testMultiPartEmptyMessage() throws Exception {
String address = "http://localhost:8090/eoa/ws/1.1/ValueLookupService/SOAP11Endpoint/";
EndpointReference targetEPR = new EndpointReference(address);
ServiceClient client = new ServiceClient(configurationContext, null);
client.engageModule("addressing");
Options options = new Options();
options.setTo(targetEPR);
options.setAction("http://com.mycompany/eoa/1.1/MyInterface/getVersionRequest");
options.setTimeOutInMilliSeconds(1000000);
options.setSoapVersionURI("http://schemas.xmlsoap.org/soap/envelope/");
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
client.setOptions(options);
AxisService axisService = client.getAxisService();
AxisOperation axisOperation = axisService.getOperation(ServiceClient.ANON_OUT_IN_OP);
axisOperation.setMessageReceiver(new CallbackReceiver());
OperationClient mep = client.createClient(ServiceClient.ANON_OUT_IN_OP);
MessageContext request = new MessageContext();
request.setServiceContext(client.getServiceContext());
SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();
SOAPEnvelope soapEnvelope = soapFactory.getDefaultEnvelope();
request.setEnvelope(soapEnvelope);
mep.addMessageContext(request);
mep.execute(true);
MessageContext response = mep.getMessageContext("In");
SOAPEnvelope responseEnvelope = response.getEnvelope();
OMElement responsePayload = responseEnvelope.getBody().getFirstElement();
String version = responsePayload.getFirstElement().getText();
assertEquals(version, "1.1");
}
}
Debugging
To debug your extension within the context of a test, you must configure the test harness to wait for a JWDP attachment. You do this by executing maven with a specific phase and command line argument depending upon the type of test you are running. Note that if you enabled the EOA plugin correctly, it is automatically associated with the various test related phases of your extension project's lifecycle. To debug your unit tests use the following command:
mvn test -Dmaven.surefire.debug
To debug your integration system tests, use the following command:
mvn install -Dmaven.surefire.it.debug
To debug your integration client tests, use the following command:
mvn install -Dmaven.surefire.it.client.debug
Note that you may want to create new maven batch/script files which contain the appropriate command line arguments by copying the mvn batch/script file and renaming to, e.g. mvn-debug, mvn-it-debug and mvn-it-client-debug and adding the approriate command line argument to each. Then you can just execute,e.g. mvn-debug test, mvn-it-debug install, etc ... In any case, the test harness will fork a separate JVM which waits for the JWDP attachment on port 5005.
Debugging With Eclipse
To connect with the eclipse debugger, follow these steps:
- Set a breakpoint within your test.
- Go to run > debug configurations.
- Click on icon to add a new launch configuration.
- Name the configuration, e.g. my-extension-debug.
- Select the your extension project, e.g. my-extension.
- Change the attachment port to 5005.
- Click apply and then debug to attach.
- The debugger will stop at your breakpoints.
- Note that all related alakai source artifacts are automatically configured for you.
- For subsequent debugging sessions, just launch the configuration created above.
Locating Test Reports
After running your tests, you'll want to navigate to the reports directory to diagnose any test failures. For unit tests, the reports are located within the following directory:

For integration tests, the test harness creates separate directories for each test suite. Within each suite's sub-directory, the reports are separated according to whether the integration test suite contains client based integration tests, or whether it contains system based integration tests. The test reports for system based integration tests are located in the following directory.

And you guessed it, the test reports for client based integration tests are located in the following directory.

Locating System Logs
If, when running your integration tests, the test fails due to an error which occurred when trying to start alakai, the error will be logged to the alakai system log. If you've configured the log4j.xml file within your test suite to use the file appender, the alaki system log will be located at the following location:

If, when running your integration tests, the test fails due to an error which occurred when trying to set-up the client environment, i.e. Axis2, the error will be logged to the file client.log . If you've configured the log4j.xml file within your client test suite to use the file appender, the axis log will be located at the following location:
