KEMBAR78
Docker Testing | PDF
with	a	dash	of	chaos
with	a	dash	of	chaos
with	a	dash	of	chaos
with	a	dash	of	chaos
with	a	dash	of	chaos
with	a	dash	of	chaos
with	a	dash	of	chaoswith	a	dash	of	chaos






	
	
alexsotob		
alexsotob		
	
	
alexsotob		
alexsotob		
	
	
alexsotob		
alexsotob		
		alexsotob		alexsotob		
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
D O C K E R I Z E D 	 S Y S T E M 	 T E S T I N GD O C K E R I Z E D 	 S Y S T E M 	 T E S T I N G
A L E X 	 S O T O
R E D 	 H A T 	 E N G I N E E R
O P E N 	 S O U R C E 	 A D V O C A T E
@ A L E X S O T O B
	alexsotob		lordofthejars
Q U E S T I O N S
	alexsotob		lordofthejars
S O F T W A R E 	I S
E A T I N G 	 T H E 	W O R L D
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
A U T O M A T I C 	 T E S T S	A S 	 S O L U T I O N
	alexsotob		lordofthejars
U N I T 	 T E S T S 	A R E 	 N O T 	 E N O U G H
	alexsotob		lordofthejars
S O C I A B L E 	U N I T 	 T E S T S
	alexsotob		lordofthejars
W O U L D 	 I T 	 W O R K 	 I N 	P R O D U C T I O N 	?
	alexsotob		lordofthejars
H I G H - L E V E L 	 T E S T S	R U N N I N G 	 I N 	
P R O D U C T I O N - L I K E 	E N V I R O N M E N T
	alexsotob		lordofthejars
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
Fills
the
gap
between
Unit/Integration
tests
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
Fills
the
gap
between
Unit/Integration
tests
Child's
game
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
Fills
the
gap
between
Unit/Integration
tests
Child's
game
Any
kind
of
high-level
tests
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
Fills
the
gap
between
Unit/Integration
tests
Child's
game
Any
kind
of
high-level
tests
JavaEE
and
beyond
	alexsotob		lordofthejars
W H A T 	 I S 	A R Q U I L L I A N ?
Middleware
for
your
tests
Fills
the
gap
between
Unit/Integration
tests
Child's
game
Any
kind
of
high-level
tests
JavaEE
and
beyond
Open
Source
	alexsotob		lordofthejars
apply	pluginapply	plugin::		"io.spring.dependency-management""io.spring.dependency-management"
dependencyManagement	dependencyManagement	{{
		imports			imports	{{
				mavenBom					mavenBom	'org.jboss.arquillian:arquillian-bom:1.1.10.Final''org.jboss.arquillian:arquillian-bom:1.1.10.Final'
				}}
}}		
B U I L D . G R A D L E
	alexsotob		lordofthejars
apply	pluginapply	plugin::		"io.spring.dependency-management""io.spring.dependency-management"
dependencyManagement	dependencyManagement	{{
		imports			imports	{{
				mavenBom					mavenBom	'org.jboss.arquillian:arquillian-bom:1.1.10.Final''org.jboss.arquillian:arquillian-bom:1.1.10.Final'
				}}
}}		
dependencies	dependencies	{{
		testCompile	group		testCompile	group::		'org.jboss.arquillian.junit''org.jboss.arquillian.junit',,	name	name::		'arquillian-junit-container''arquillian-junit-container'
B U I L D . G R A D L E
	alexsotob		lordofthejars
apply	pluginapply	plugin::		"io.spring.dependency-management""io.spring.dependency-management"
dependencyManagement	dependencyManagement	{{
		imports			imports	{{
				mavenBom					mavenBom	'org.jboss.arquillian:arquillian-bom:1.1.10.Final''org.jboss.arquillian:arquillian-bom:1.1.10.Final'
				}}
}}		
dependencies	dependencies	{{
		testCompile	group		testCompile	group::		'org.jboss.arquillian.junit''org.jboss.arquillian.junit',,	name	name::		'arquillian-junit-container''arquillian-junit-container'
		testCompile			testCompile	'org.apache.tomee:arquillian-tomee-remote:7.0.0''org.apache.tomee:arquillian-tomee-remote:7.0.0'
}}
B U I L D . G R A D L E
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		PlanetServiceAPITestPlanetServiceAPITest		{{
P L A N E T S T E S T . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		PlanetServiceAPITestPlanetServiceAPITest		{{
		@		@DeploymentDeployment((testable	testable	==		falsefalse))
				publicpublic		staticstatic	WebArchive		WebArchive	createDeploymentcreateDeployment(())		{{
								returnreturn	ShrinkWrap	ShrinkWrap..createcreate((WebArchiveWebArchive..classclass))
												..addClassesaddClasses((SwapiGatewaySwapiGateway..classclass,,	PlanetService	PlanetService..classclass,,		......))
												..addAsResourceaddAsResource(("swapitest.properties""swapitest.properties",,		"swapi.properties""swapi.properties"));;
				}}
P L A N E T S T E S T . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		PlanetServiceAPITestPlanetServiceAPITest		{{
		@		@DeploymentDeployment((testable	testable	==		falsefalse))
				publicpublic		staticstatic	WebArchive		WebArchive	createDeploymentcreateDeployment(())		{{
								returnreturn	ShrinkWrap	ShrinkWrap..createcreate((WebArchiveWebArchive..classclass))
												..addClassesaddClasses((SwapiGatewaySwapiGateway..classclass,,	PlanetService	PlanetService..classclass,,		......))
												..addAsResourceaddAsResource(("swapitest.properties""swapitest.properties",,		"swapi.properties""swapi.properties"));;
				}}
		@ArquillianResource		@ArquillianResource
		URL	url		URL	url;;
		@Test		@Test
				publicpublic		voidvoid		shouldReturnTheAverageshouldReturnTheAverage(())		{{
				final	String	average					final	String	average	==	RestAssured	RestAssured..getget((urlurl..toExternalFormtoExternalForm(())		++		
																																																				"rest/planet/orbital/average""rest/planet/orbital/average"))..asStringasString(());;
				assertThat				assertThat((averageaverage,,		isis(("1699.42""1699.42"))));;
				}}
}}
P L A N E T S T E S T . J A V A
	alexsotob		lordofthejars
D E M O
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
Executable
from
IDE
and
buildtool
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
Executable
from
IDE
and
buildtool
Reuse
exitsing
frameworks
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
Executable
from
IDE
and
buildtool
Reuse
exitsing
frameworks
Flexible
to
adapt
technologies
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
Executable
from
IDE
and
buildtool
Reuse
exitsing
frameworks
Flexible
to
adapt
technologies
Extensible
to
new
platforms
	alexsotob		lordofthejars
P R I N C I P L E S 	 O F 	A R Q U I L L I A N ?
Portable
tests
Executable
from
IDE
and
buildtool
Reuse
exitsing
frameworks
Flexible
to
adapt
technologies
Extensible
to
new
platforms
Ease
of
deployment
	alexsotob		lordofthejars
D O C K E R
	alexsotob		lordofthejars
	alexsotob		lordofthejars
A R Q U I L L I A N 	 C U B E
	alexsotob		lordofthejars
W H A T 	 I S 	C U B E ?
Manage
lifecycle
of
Docker
containers
	alexsotob		lordofthejars
W H A T 	 I S 	C U B E ?
Manage
lifecycle
of
Docker
containers
Uses
Arquillian
remote
adapters
	alexsotob		lordofthejars
W H A T 	 I S 	C U B E ?
Manage
lifecycle
of
Docker
containers
Uses
Arquillian
remote
adapters
Orchestrate
containers
	alexsotob		lordofthejars
W H A T 	 I S 	C U B E ?
Manage
lifecycle
of
Docker
containers
Uses
Arquillian
remote
adapters
Orchestrate
containers
Support
for
containerless
systems
	alexsotob		lordofthejars
W H A T 	 I S 	C U B E ?
Manage
lifecycle
of
Docker
containers
Uses
Arquillian
remote
adapters
Orchestrate
containers
Support
for
containerless
systems
Ready
for
Docker
Machine
	alexsotob		lordofthejars
dependencies	dependencies	{{
		testCompile			testCompile	'org.arquillian.cube:arquillian-cube-docker:1.0.0.Alpha11''org.arquillian.cube:arquillian-cube-docker:1.0.0.Alpha11'
}}
B U I L D . G R A D L E
	alexsotob		lordofthejars
<<arquillianarquillian>>
				<<extensionextension		qualifierqualifier==""dockerdocker"">>
												<<propertyproperty		namename==""machineNamemachineName"">>devdev</</propertyproperty>>
												<<propertyproperty		namename==""definitionFormatdefinitionFormat"">>COMPOSECOMPOSE</</propertyproperty>>
												<<propertyproperty		namename==""dockerContainersFiledockerContainersFile"">>docker-compose.ymldocker-compose.yml</</propertyproperty>>
				</</extensionextension>>
				
S R C / T E S T / R E S O U R C E S / A R Q U I L L I A N . X M L
	alexsotob		lordofthejars
<<arquillianarquillian>>
				<<extensionextension		qualifierqualifier==""dockerdocker"">>
												<<propertyproperty		namename==""machineNamemachineName"">>devdev</</propertyproperty>>
												<<propertyproperty		namename==""definitionFormatdefinitionFormat"">>COMPOSECOMPOSE</</propertyproperty>>
												<<propertyproperty		namename==""dockerContainersFiledockerContainersFile"">>docker-compose.ymldocker-compose.yml</</propertyproperty>>
				</</extensionextension>>
				
				<<containercontainer		qualifierqualifier==""tomcattomcat"">>
								<<configurationconfiguration>>
												<<propertyproperty		namename==""useruser"">>adminadmin</</propertyproperty>>
												<<propertyproperty		namename==""passpass"">>mypassmypass</</propertyproperty>>
								</</configurationconfiguration>>
				</</containercontainer>>
</</arquillianarquillian>>
S R C / T E S T / R E S O U R C E S / A R Q U I L L I A N . X M L
	alexsotob		lordofthejars
tomcattomcat::
		env_file		env_file::	envs	envs
		image		image::	tutum	tutum//tomcattomcat::7.07.0
		ports		ports::
												--		"8089:8089""8089:8089"
												--		"8088:8088""8088:8088"
												--		"8081:8080""8081:8080"
		links		links::
												--	pingpong	pingpong::pingpongpingpong
												
		pingpong		pingpong::
				image				image::	jonmorehouse	jonmorehouse//pingping--pongpong
				ports				ports::
												--		"8080:8080""8080:8080"
												
D O C K E R - C O M P O S E . Y M L
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		HelloWorldServletTestHelloWorldServletTest		{{
		@		@DeploymentDeployment((testabletestable==falsefalse))
				publicpublic		staticstatic	WebArchive		WebArchive	createcreate(())		{{
												returnreturn	ShrinkWrap	ShrinkWrap..createcreate((WebArchiveWebArchive..classclass,,		"hello.war""hello.war"))
																				..addClassaddClass((HelloWorldServletHelloWorldServlet..classclass));;
				}}
				
P I N G P O N G T E S T . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		HelloWorldServletTestHelloWorldServletTest		{{
		@		@DeploymentDeployment((testabletestable==falsefalse))
				publicpublic		staticstatic	WebArchive		WebArchive	createcreate(())		{{
												returnreturn	ShrinkWrap	ShrinkWrap..createcreate((WebArchiveWebArchive..classclass,,		"hello.war""hello.war"))
																				..addClassaddClass((HelloWorldServletHelloWorldServlet..classclass));;
				}}
				
		@HostIp		@HostIp
		String	hostIp		String	hostIp;;
		@		@HostPortHostPort((containerName	containerName	==		"tomcat""tomcat",,	value		value	==		80808080))
		int	tomcatPort		int	tomcatPort;;
P I N G P O N G T E S T . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		HelloWorldServletTestHelloWorldServletTest		{{
		@		@DeploymentDeployment((testabletestable==falsefalse))
				publicpublic		staticstatic	WebArchive		WebArchive	createcreate(())		{{
												returnreturn	ShrinkWrap	ShrinkWrap..createcreate((WebArchiveWebArchive..classclass,,		"hello.war""hello.war"))
																				..addClassaddClass((HelloWorldServletHelloWorldServlet..classclass));;
				}}
				
		@HostIp		@HostIp
		String	hostIp		String	hostIp;;
		@		@HostPortHostPort((containerName	containerName	==		"tomcat""tomcat",,	value		value	==		80808080))
		int	tomcatPort		int	tomcatPort;;
		@Test		@Test
				publicpublic		voidvoid		testtest((@ArquillianResource	URL	base@ArquillianResource	URL	base))	throws	IOException		throws	IOException	{{
				URL	obj					URL	obj	==		newnew		URLURL((basebase,,		"HelloWorld""HelloWorld"));;
				}}
P I N G P O N G T E S T . J A V A
	alexsotob		lordofthejars
D E M O
	alexsotob		lordofthejars
C O N T A I N E R L E S S
	alexsotob		lordofthejars
W H A T 	 I S 	C O N T A I N E R L E S S ?
Runs
any
application
that
runs
on
Docker
	alexsotob		lordofthejars
W H A T 	 I S 	C O N T A I N E R L E S S ?
Runs
any
application
that
runs
on
Docker
Including
but
not
limited
Nodejs,
Wildfly
Swarm,
Spring
Boot,
Vert.x,
Go
	alexsotob		lordofthejars
W H A T 	 I S 	C O N T A I N E R L E S S ?
Runs
any
application
that
runs
on
Docker
Including
but
not
limited
Nodejs,
Wildfly
Swarm,
Spring
Boot,
Vert.x,
Go
Shrinkwrap
support
	alexsotob		lordofthejars
dependencies	dependencies	{{
		testCompile			testCompile	'org.arquillian.cube:arquillian-cube-containerless:1.0.0.Alpha11''org.arquillian.cube:arquillian-cube-containerless:1.0.0.Alpha11'
}}
B U I L D . G R A D L E
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		NodeTestNodeTest		{{
				@				@DeploymentDeployment((testable	testable	==		falsefalse))
								publicpublic		staticstatic	GenericArchive		GenericArchive	createDeploymentcreateDeployment(())		{{
																returnreturn	ShrinkWrap	ShrinkWrap..createcreate((GenericArchiveGenericArchive..classclass,,		"app.tar""app.tar"))
																																..addadd((newnew		FileAssetFileAsset((newnew		FileFile(("src/test/js/index.js""src/test/js/index.js")))),,		"index.js""index.js"))
																																..addadd((newnew		FileAssetFileAsset((newnew		FileFile(("src/test/js/package.json""src/test/js/package.json")))),,		"package.json""package.json"));;
								}}
								
				@Test				@Test
								publicpublic		voidvoid		shouldReturnMessageFromNodeJsshouldReturnMessageFromNodeJs((@ArquillianResource	URL	base@ArquillianResource	URL	base))		{{
								}}
}}
N O D E J S T E S T . J A V A
	alexsotob		lordofthejars
FROM	nodeFROM	node::0.110.11..1414
RUN	mkdir	RUN	mkdir	--p	p	//usrusr//srcsrc//appapp
WORKDIR	WORKDIR	//usrusr//srcsrc//appapp
ADD	$ADD	${{deployableFilenamedeployableFilename}}		//usrusr//srcsrc//appapp
RUN	npm	installRUN	npm	install
EXPOSE	EXPOSE	80808080
CMD	CMD	[[		"npm""npm",,		"start""start"		]]
D O C K E R F I L E T E M P L A T E
	alexsotob		lordofthejars
nodeexamplenodeexample::
		build		build::	src	src//testtest//resourcesresources
				
D O C K E R - C O M P O S E . Y M L
	alexsotob		lordofthejars
<<extensionextension		qualifierqualifier==""dockerdocker"">>
				<<propertyproperty		namename==""machineNamemachineName"">>devdev</</propertyproperty>>
</</extensionextension>>
A R Q U I L L I A N . X M L
	alexsotob		lordofthejars
<<extensionextension		qualifierqualifier==""dockerdocker"">>
				<<propertyproperty		namename==""machineNamemachineName"">>devdev</</propertyproperty>>
</</extensionextension>>
<<containercontainer		qualifierqualifier==""containerlesscontainerless""		defaultdefault==""truetrue"">>
				<<configurationconfiguration>>
								<<propertyproperty		namename==""containerlessDockercontainerlessDocker"">>nodeexamplenodeexample</</propertyproperty>>
				</</configurationconfiguration>>
</</containercontainer>>
A R Q U I L L I A N . X M L
	alexsotob		lordofthejars
D E M O
	alexsotob		lordofthejars
C O N T A I N E R 	 O B J E C T	P A T T E R N
	alexsotob		lordofthejars
W H A T 	 A R E 	C O N T A I N E R 	 O B J E C T S?
Encapsulate
containers
(Operations
and
Configuration)
	alexsotob		lordofthejars
W H A T 	 A R E 	C O N T A I N E R 	 O B J E C T S?
Encapsulate
containers
(Operations
and
Configuration)
Single
Responsibility
	alexsotob		lordofthejars
W H A T 	 A R E 	C O N T A I N E R 	 O B J E C T S?
Encapsulate
containers
(Operations
and
Configuration)
Single
Responsibility
Reuse
	alexsotob		lordofthejars
@@CubeCube((value	value	==		"pingpong""pingpong",,	portBinding		portBinding	==		"5000->8080/tcp""5000->8080/tcp"))
publicpublic		classclass		PingPongContainerPingPongContainer		{{
P I N G - P O N G - C O N T A I N E R . J A R
	alexsotob		lordofthejars
@@CubeCube((value	value	==		"pingpong""pingpong",,	portBinding		portBinding	==		"5000->8080/tcp""5000->8080/tcp"))
publicpublic		classclass		PingPongContainerPingPongContainer		{{
		@HostIp		@HostIp
		String	dockerHost		String	dockerHost;;
		@		@HostPortHostPort((80808080))
				privateprivate	int	port	int	port;;
		@ArquillianResource		@ArquillianResource
				privateprivate	DockerClient	dockerClient	DockerClient	dockerClient;;
		@CubeDockerFile		@CubeDockerFile
				publicpublic		staticstatic	Archive		Archive	createContainercreateContainer(())		{{
				String	dockerDescriptor					String	dockerDescriptor	==	Descriptors	Descriptors..createcreate((DockerDescriptorDockerDescriptor..classclass))
																..fromfrom(("jonmorehouse/ping-pong""jonmorehouse/ping-pong"))..exportAsStringexportAsString(());;
								returnreturn	ShrinkWrap	ShrinkWrap..createcreate((GenericArchiveGenericArchive..classclass))
																..addadd((newnew		StringAssetStringAsset((dockerDescriptordockerDescriptor)),,		"Dockerfile""Dockerfile"));;
				}}
P I N G - P O N G - C O N T A I N E R . J A R
	alexsotob		lordofthejars
@@CubeCube((value	value	==		"pingpong""pingpong",,	portBinding		portBinding	==		"5000->8080/tcp""5000->8080/tcp"))
publicpublic		classclass		PingPongContainerPingPongContainer		{{
		@HostIp		@HostIp
		String	dockerHost		String	dockerHost;;
		@		@HostPortHostPort((80808080))
				privateprivate	int	port	int	port;;
		@ArquillianResource		@ArquillianResource
				privateprivate	DockerClient	dockerClient	DockerClient	dockerClient;;
		@CubeDockerFile		@CubeDockerFile
				publicpublic		staticstatic	Archive		Archive	createContainercreateContainer(())		{{
				String	dockerDescriptor					String	dockerDescriptor	==	Descriptors	Descriptors..createcreate((DockerDescriptorDockerDescriptor..classclass))
																..fromfrom(("jonmorehouse/ping-pong""jonmorehouse/ping-pong"))..exportAsStringexportAsString(());;
								returnreturn	ShrinkWrap	ShrinkWrap..createcreate((GenericArchiveGenericArchive..classclass))
																..addadd((newnew		StringAssetStringAsset((dockerDescriptordockerDescriptor)),,		"Dockerfile""Dockerfile"));;
				}}
				publicpublic	URL		URL	getConnectionURLgetConnectionURL(())		{{
				URL	url					URL	url	==		newnew		URLURL(("http://""http://"		++	dockerHost		dockerHost	++		":"":"		++	port	port));;
				}}
}}
P I N G - P O N G - C O N T A I N E R . J A R
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		PingPongTestPingPongTest		{{
		@Cube		@Cube
		PingPongContainer	pingPongContainer		PingPongContainer	pingPongContainer;;
				
P I N G P O N G T E S T . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))
publicpublic		classclass		PingPongTestPingPongTest		{{
		@Cube		@Cube
		PingPongContainer	pingPongContainer		PingPongContainer	pingPongContainer;;
				
		@Test		@Test
				publicpublic		voidvoid		shouldReturnOkAsPongshouldReturnOkAsPong(())	throws	IOException		throws	IOException	{{
				String	pong					String	pong	==		pingping((pingPongContainerpingPongContainer..getConnectionUrlgetConnectionUrl(())));;
				assertThat				assertThat((pongpong,,		containsStringcontainsString(("OK""OK"))));;
				}}
}}
P I N G P O N G T E S T . J A V A
	alexsotob		lordofthejars
<<extensionextension		qualifierqualifier==""dockerdocker"">>
				<<propertyproperty		namename==""machineNamemachineName"">>devdev</</propertyproperty>>
</</extensionextension>>
A R Q U I L L I A N . X M L
	alexsotob		lordofthejars
D E M O
	alexsotob		lordofthejars
The	more	we	relay	on	being	online	
The	more	offline	support	is	needed?.
	alexsotob		lordofthejars
A R Q U I L L I A N 	 C U B E 	 Q
	alexsotob		lordofthejars
	alexsotob		lordofthejars
W H A T 	 I S 	Q ?
Automatic
redirect
to
Toxic
Proxy
	alexsotob		lordofthejars
W H A T 	 I S 	Q ?
Automatic
redirect
to
Toxic
Proxy
Toxicity
	alexsotob		lordofthejars
W H A T 	 I S 	Q ?
Automatic
redirect
to
Toxic
Proxy
Toxicity
Chaos
latency,
bandwidth,
down,
slow_close,
timeout,
slicer
	alexsotob		lordofthejars
W H A T 	 I S 	Q ?
Automatic
redirect
to
Toxic
Proxy
Toxicity
Chaos
latency,
bandwidth,
down,
slow_close,
timeout,
slicer
To
come
Long
test
execution
	alexsotob		lordofthejars
helloworldhelloworld::
		image		image::	lordofthejars	lordofthejars//helloworldhelloworld
		ports		ports::
								--		"8081:8080""8081:8080"
		links		links::
								--	pingpong	pingpong::pingpongpingpong
								
pingpongpingpong::
		image		image::	jonmorehouse	jonmorehouse//pingping--pongpong
		expose		expose::
												--		"8080""8080"
D O C K E R - C O M P O S E . Y M L
	alexsotob		lordofthejars
dependencies	dependencies	{{
		testCompile			testCompile	'org.arquillian.cube.q:arquillian-cube-q-toxic:1.0.0.Alpha1''org.arquillian.cube.q:arquillian-cube-q-toxic:1.0.0.Alpha1'
}}
B U I L D . G R A D L E
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))		//@Ignore//@Ignore
publicpublic		classclass		ToxicFuntionalTestCaseToxicFuntionalTestCase		{{
		@ArquillianResource		@ArquillianResource
				privateprivate	Q	Q	Q	Q;;
				
		@HostIp		@HostIp
				privateprivate	String	ip	String	ip;;
				
T O X I C F U N T I O N A L T E S T C A S E . J A V A
	alexsotob		lordofthejars
@@RunWithRunWith((ArquillianArquillian..classclass))		//@Ignore//@Ignore
publicpublic		classclass		ToxicFuntionalTestCaseToxicFuntionalTestCase		{{
		@ArquillianResource		@ArquillianResource
				privateprivate	Q	Q	Q	Q;;
				
		@HostIp		@HostIp
				privateprivate	String	ip	String	ip;;
				
		@Test		@Test
				publicpublic		voidvoid		shouldSurviveOnLatencyshouldSurviveOnLatency(())	throws	Exception		throws	Exception	{{
				Q				Q..onon(("pingpong""pingpong",,		80808080))..latencylatency((40004000,,		00,,		(())		-->>		{{
						URL	url							URL	url	==		newnew		URLURL(("http://""http://"		++	ip		ip	++		":"":"		++		80818081		++		"/hw/HelloWorld""/hw/HelloWorld"));;
						String	response							String	response	==	IOUtil	IOUtil..asStringasString((urlurl..openStreamopenStream(())));;
								}}));;
				}}
}}
T O X I C F U N T I O N A L T E S T C A S E . J A V A
	alexsotob		lordofthejars
D E M O
	alexsotob		lordofthejars
L E T ' S 	 W I N D 	 D O W N
	alexsotob		lordofthejars
Unit
tests
are
important
	alexsotob		lordofthejars
Unit
tests
are
important
But
test
in
production-like
environment
	alexsotob		lordofthejars
Unit
tests
are
important
But
test
in
production-like
environment
Arquillian
extensions
	alexsotob		lordofthejars
Unit
tests
are
important
But
test
in
production-like
environment
Arquillian
extensions
Be
prepared
for
Unexpected
	alexsotob		lordofthejars
Unit
tests
are
important
But
test
in
production-like
environment
Arquillian
extensions
Be
prepared
for
Unexpected
Arquillian
works
in
No
Java
projects
	alexsotob		lordofthejars
I T 
 I S 
N O T 
 N E C E S S A R Y
T O 
 C H A N G E . 

S U R V I V A L 
I S 
 N O T 
 M A N D A T O R Y.
W.	Edwards	Deming
	alexsotob		lordofthejars

http://www.slideshare.net/asotobu/docker-testing

asotobu@gmail.com
	alexsotob		lordofthejars
github.com/arquillian/arquillian-cube/tree/master/docker/ftest-docker-containerobject
github.com/arquillian/arquillian-cube/tree/master/docker/ftest-docker-compose
github.com/lordofthejars/starwars
http://toxiproxy.io
http://arquillian.org/
	alexsotob		lordofthejars

Docker Testing