Testing Fuse Fabric with Pax Exam
-
Upload
henryk-konsek -
Category
Technology
-
view
433 -
download
1
Transcript of Testing Fuse Fabric with Pax Exam
Testing Fuse Fabric with
Pax ExamBrought to you by / Henryk Konsek @hekonsek
This talk1. Our goals2. Pax Exam3. Case studies
1. Our goals
Our problemsOSGi ;)it works on my computer aka responsibility ping-pongcreating repeatable middleware proof of concepts is difficultgoing production without proper testing
Our goalsrepeatable tests of middleware - infracodingOSGi issues detected and fixed as soon as possibleeducated customers sending us runnable and repeatableexamples
2. Pax Exam
What is Pax ExamJUnit friendly framework for running tests in real KarafcontainersExam deploys JUnit test case as a bundleif the bundle can be successfully tested with the Exam, thenit can be successfully deployed to Karaf
Exam hello world!Project structure
my-project my-project-services my-project-routes ... my-project-bundle my-project-itest
Exam hello world!JUnit class
@RunWith(PaxExam.class)public class MyKarafTest extends Assert {
@Inject MyOsgiService myOsgiService;
@Configuration public Option[] configuration() { ... }
@Test public void shouldReturnResponse() { ... }
}
Exam hello world!Karaf configuration
@Configurationpublic Option[] configuration() { return new Option[]{ karafDistributionConfiguration() .frameworkUrl( maven().groupId("org.apache.karaf").artifactId("apache-karaf") .type("zip").version("2.3.3")). karafVersion("2.3.3").name("Apache Karaf") .unpackDirectory(new File("target/pax")) .useDeployFolder(false), keepRuntimeFolder(), configureConsole().ignoreLocalConsole().ignoreRemoteShell(),
mavenBundle().groupId("com.example").artifactId("my-project-bundle"). versionAsInProject()};}
Exam hello world!Testing OSGi service
@RunWith(PaxExam.class)public class MyKarafTest extends Assert {
@Inject MyOsgiService myOsgiService;
@Configuration public Option[] configuration() { ... }
@Test public void shouldReturnResponse() { assertEquals("Hello!", myOsgiService.helloWorld()); }
}
Exam hello world!Testing OSGi Camel service
@RunWith(PaxExam.class)public class MyDeployedCamelTest extends Assert {
@Inject CamelContext camelContext;
@Configuration public Option[] configuration() {...}
@Test public void shouldReturnResponse() { String response = camelContext.createProducerTemplate(). requestBody("jms:queue", "msg", String.class); assertEquals("Hello!", response); }
}
3. Case studies
Case #1: Hello world!Arm your POM
<repositories> <repository> <id>jboss-fuse-ea</id> <url>https://repository.jboss.org/nexus/content/groups/ea</url> </repository></repositories>
Engineering guys deploy here.
<properties> <fabric-version>1.0.0.redhat-340</fabric-version></properties>
Pick up some bleeding edge yet stable version of Fabric testAPI.
Case #1: Hello world!Arm your POM
<dependency> <groupid>io.fabric8</groupid> <artifactid>fabric8-karaf</artifactid> <version>${fabric-version}</version> <type>zip</type></dependency>
Download Fabric distribution.
<dependency> <groupid>io.fabric8.itests</groupid> <artifactid>fabric-itests-common</artifactid> <version>${fabric-version}</version></dependency>
Include Fabric test API (and nothing more!).
Case #1: Hello world!Tested Camel route
public class NettyHttpRoute extends RouteBuilder {
@Override public void configure() throws Exception { from("netty-http:http://localhost:18080/"). setBody().constant("Hello world!"); }
}
Case #1: Hello world!Base test class
import io.fabric8.itests.paxexam.support.FabricTestSupport;...@RunWith(JUnit4TestRunner.class)@ExamReactorStrategy(AllConfinedStagedReactorFactory.class)public class SimpleFabricTest extends FabricTestSupport {
@Configuration public Option[] config() { return new Option[]{ new DefaultCompositeOption(fabricDistributionConfiguration()), mavenBundle("commons-io", "commons-io").versionAsInProject() }; } ...
}
almost no config? Buy Ioannis a beer for creating theFabricTestSupport ;)yeah, this is the old and ugly Pax Exam 2.x API...you need to configure everything you use in the test bundle
Case #1: Hello world!Deploying Camel route
import static java.lang.System.err;
@Testpublic void shouldCreateCamelRouter() throws Exception { err.println(executeCommand("fabric:create -n")); err.println(executeCommand("fabric:profile-create " + "--parents feature-camel netty-http-server")); err.println(executeCommand("fabric:profile-edit " + "--features camel-netty-http netty-http-server")); err.println(executeCommand("fabric:profile-edit --bundles " + "mvn:com.example/my-project-bundle/1.0-SNAPSHOT netty-http-server"));
ContainerBuilder.create(). withName("router-container").withProfiles("netty-http-server"). assertProvisioningResult().build(); // ... assertions}
String output = executeCommand("some:karafCommand");assertProvisioningResult == block until container is ready
Case #1: Hello world!Testing deployed route
@Testpublic void shouldCreateCamelRouter() throws Exception { // ... creating container
InputStream inputStream = new URL("http://localhost:18080/").openStream(); String response = IOUtils.toString(inputStream); assertEquals("Hello world!", response);}
a poor-man's HTTP client
Case #1: Hello world!User friendly output
fabric:create -nUsing specified zookeeper password:admin
fabric:profile-create --parents feature-camel netty-http-serverfabric:profile-edit --features camel-netty-http netty-http-serverAdding feature:camel-netty-http to profile:netty-http-server version:1.0
fabric:profile-edit --bundles ... netty-http-server
Adding bundle:mvn:... to profile:netty-http-server version:1.0Waiting for containers: [ router-container1 ] to successfully provisionContainer:router-container1 Alive:false Status: SSH URL:nullContainer:router-container1 Alive:true Status:analyzing SSH URL:...Container:router-container1 Alive:true Status:downloading SSH URL:...Container:router-container1 Alive:true Status:finalizing SSH URL:...Container:router-container1 Alive:true Status:success SSH URL:...
output partially omitted (SSH address!)very similar to the output from the real Karaf session
Case #2: Hacking childcontainers with SSH
Container container = (Container) create().withName("router-container"). withProfiles("netty-http-server"). assertProvisioningResult().build().iterator().next();
String[] containerSshUrl = container.getSshUrl().split(":");String containerHost = containerSshUrl[0];String containerPort = containerSshUrl[1];
String bundlesOnContainer = executeCommand(format( "ssh -l %s -P %s -p %s %s osgi:list", "admin", "admin", containerPort, containerHost));
assertTrue(bundlesOnContainer.contains("camel-netty-http"));
running Karaf container can be accessed via SSH clientwe can execute any remote Karaf command via ssh
Case #3: Fabric Mastercomponent test
many customers request singleton Camel route in theclustered environmentFabric Master FTW!it is difficult to provide proof of concept for the customerPax Exam + Fabric Master = no brainer demo
Case #3: Fabric Mastercomponent test
public class MasterRoute extends RouteBuilder {
@Override public void configure() throws Exception { from("master:netty-master:netty-http:http://localhost:18081/"). setBody().constant("master"); }
}
the clustered route we want to testonly single Netty instance should handle requests at givenmoment
Case #3: Fabric Mastercomponent test
fabric:create -nfabric:profile-create --parents feature-camel master-nettyfabric:profile-edit --features camel-netty-http master-nettyfabric:profile-edit --bundles mvn:com.example/my-project-bundle/1.0-SNAPSHOT master-netty
Booooring...
Case #3: Fabric Mastercomponent test
Container master = ContainerBuilder.create(). withName("master").withProfiles("master-netty"). assertProvisioningResult().build();
InputStream inputStream = new URL("http://localhost:18081/").openStream();String response = IOUtils.toString(inputStream);assertEquals("master", response);
creating first Netty router container in the clusterfirst router must be the master
Case #3: Fabric Mastercomponent test
Container slave = ContainerBuilder.create(). withName("slave").withProfiles("master-netty"). assertProvisioningResult().build();
no port conflicts? That's good - only the single master node isrunning.
Case #3: Fabric Mastercomponent test
Container master = ...;...master.destroy();
InputStream inputStream = new URL("http://localhost:18081/").openStream();String response = IOUtils.toString(inputStream);assertEquals("master", response);
we are still receiving correct responseslave has been nominated to the master
Exampleshttps://github.com/hekonsek/fuse-pocs/tree/master/fuse-pocs-
fabric
Many thanks!