Testing Fuse Fabric with Pax Exam

29
Testing Fuse Fabric with Pax Exam Brought to you by / Henryk Konsek @hekonsek

Transcript of Testing Fuse Fabric with Pax Exam

Page 1: Testing Fuse Fabric with Pax Exam

Testing Fuse Fabric with

Pax ExamBrought to you by / Henryk Konsek @hekonsek

Page 2: Testing Fuse Fabric with Pax Exam

This talk1. Our goals2. Pax Exam3. Case studies

Page 3: Testing Fuse Fabric with Pax Exam

1. Our goals

Page 4: Testing Fuse Fabric with Pax Exam

Our problemsOSGi ;)it works on my computer aka responsibility ping-pongcreating repeatable middleware proof of concepts is difficultgoing production without proper testing

Page 5: Testing Fuse Fabric with Pax Exam

Our goalsrepeatable tests of middleware - infracodingOSGi issues detected and fixed as soon as possibleeducated customers sending us runnable and repeatableexamples

Page 6: Testing Fuse Fabric with Pax Exam

2. Pax Exam

Page 7: Testing Fuse Fabric with 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

Page 8: Testing Fuse Fabric with Pax Exam

Exam hello world!Project structure

my-project my-project-services my-project-routes ... my-project-bundle my-project-itest

Page 9: Testing Fuse Fabric with Pax Exam

Exam hello world!JUnit class

@RunWith(PaxExam.class)public class MyKarafTest extends Assert {

@Inject MyOsgiService myOsgiService;

@Configuration public Option[] configuration() { ... }

@Test public void shouldReturnResponse() { ... }

}

Page 10: Testing Fuse Fabric with Pax Exam

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()};}

Page 11: Testing Fuse Fabric with Pax Exam

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()); }

}

Page 12: Testing Fuse Fabric with Pax Exam

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); }

}

Page 13: Testing Fuse Fabric with Pax Exam

3. Case studies

Page 14: Testing Fuse Fabric with Pax Exam

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.

Page 15: Testing Fuse Fabric with Pax Exam

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!).

Page 16: Testing Fuse Fabric with Pax Exam

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!"); }

}

Page 17: Testing Fuse Fabric with Pax Exam

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

Page 18: Testing Fuse Fabric with Pax Exam

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

Page 19: Testing Fuse Fabric with Pax Exam

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

Page 20: Testing Fuse Fabric with Pax Exam

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

Page 21: Testing Fuse Fabric with Pax Exam

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

Page 22: Testing Fuse Fabric with Pax Exam

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

Page 23: Testing Fuse Fabric with Pax Exam

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

Page 24: Testing Fuse Fabric with Pax Exam

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...

Page 25: Testing Fuse Fabric with Pax Exam

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

Page 26: Testing Fuse Fabric with Pax Exam

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.

Page 27: Testing Fuse Fabric with Pax Exam

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

Page 28: Testing Fuse Fabric with Pax Exam

Exampleshttps://github.com/hekonsek/fuse-pocs/tree/master/fuse-pocs-

fabric

Page 29: Testing Fuse Fabric with Pax Exam

Many thanks!