Simple and Scalable Microservices: Using NATS with Docker Compose and Swarm
Automated integration testing of distributed systems with Docker Compose and JUnit
-
Upload
boris-kravtsov -
Category
Technology
-
view
213 -
download
0
Transcript of Automated integration testing of distributed systems with Docker Compose and JUnit
![Page 1: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/1.jpg)
Integration testing with Docker Compose and JUnit
Dariusz Lorenc Boris Kravtsov
![Page 2: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/2.jpg)
Pivotal Labs
![Page 3: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/3.jpg)
Problem
End-2-end test of GemFire in various cluster configurations and with different failover scenarios
![Page 4: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/4.jpg)
GemFire
GemFire is a distributed, in-memory database with strong data consistency, built to support transactional applications with low latency
and high concurrency needs
![Page 5: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/5.jpg)
GemFire Server
GemFire
GemFire Server GemFire Server
Partitioned Data
Partitioned Data
Partitioned Data
GemFire Server GemFire Server GemFire Server
Partitioned Data
Partitioned Data
Partitioned Data
Client
WAN / Multi-Site
Gateway Hub
Gateway Hub
Relational Database
![Page 6: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/6.jpg)
Docker Compose to the rescue
Docker Compose is a tool for defining and running multi-container Docker applications
![Page 7: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/7.jpg)
Docker Compose JUnit Rule
A JUnit rule to manage docker containers using docker-compose
• Start and stop docker-compose multi-container applications
• Waits for services to become available before running tests
• Extends logging and debugging
https://github.com/palantir/docker-compose-rule
![Page 8: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/8.jpg)
GreetingCounter
Master
Our Sample Distributed System
![Page 9: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/9.jpg)
Test First - Happy Path
@Test public void shouldReturnData(){ get("/info") .then().assertThat() .body("counter", isA(Number.class)) .body("greeting", is("Hello World")); }
![Page 10: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/10.jpg)
Spring Boot - Application.kt
@SpringBootApplication open class Application { companion object { @JvmStatic fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) } } }
![Page 11: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/11.jpg)
Greeting Service
@RestController class Controller { @RequestMapping("/greeting") fun greet(): Greeting { return Greeting("Hello World") } }
data class Greeting(val greeting: String)
![Page 12: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/12.jpg)
Counter Service
@RestController class Controller { val counter = AtomicLong() @RequestMapping("/counter") fun count(): Counter { return Counter(counter.incrementAndGet()) } }
data class Counter(val counter: Long)
![Page 13: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/13.jpg)
Master Service
@RestController class Controller @Autowired constructor( val greetingClient: GreetingClient, val counterClient: CounterClient) { @RequestMapping("/info") fun info(): Response { return Response(counterClient.counter().counter, greetingClient.greeting().greeting) } }
data class Response(val counter: Long, val greeting: String)
![Page 14: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/14.jpg)
Master Service - Greeting Client
@FeignClient(name = "greeting", url = "http://greeting-service:8080") interface GreetingClient { @RequestMapping(value = "/greeting", method = arrayOf(RequestMethod.GET)) fun greeting(): Greeting }
![Page 15: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/15.jpg)
Master Service - Counter Client
@FeignClient(name = "counter", url = "http://counter-service:8080") interface CounterClient { @RequestMapping(value = “/counter”, method = arrayOf(RequestMethod.GET)) fun counter(): Counter }
![Page 16: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/16.jpg)
GreetingCounter
Master
Next Step: Dockerize Our Services
![Page 17: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/17.jpg)
Dockerfiles
FROM frolvlad/alpine-oraclejdk8:slim
ADD master-service-1.0.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
Base image
Add the app’s fat jar
Expose the port
Start the java app
![Page 18: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/18.jpg)
Build Docker Image with Gradle (Transmodo plugin)
buildscript { dependencies { classpath('se.transmode.gradle:gradle-docker:1.2') } } group = '<your docker group name>' apply plugin: 'docker' task buildDocker(type: Docker, dependsOn: build) { push = true applicationName = jar.baseName dockerfile = file('src/main/docker/Dockerfile') doFirst { copy { from jar into stageDir } } }
Gradle Docker plugin
Your Docker Hub ID
Build Docker task
![Page 19: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/19.jpg)
GreetingCounter
MasterGreetingCount
“Docker Composed” Services
Docker Compose
![Page 20: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/20.jpg)
docker-compose.ymlGreeting
Counter
Master
greeting-service: image: lorenc/greeting-service ports: - “8081:8080" counter-service: image: lorenc/counter-service ports: - "8082:8080" master-service: image: lorenc/master-service ports: - "8083:8080" links: - greeting-service - counter-service
![Page 21: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/21.jpg)
Integration Test Setup
@Rule public DockerComposeRule docker = DockerComposeRule.builder() .file("../docker-compose.yml") .build();
@Before public void setUp() throws Exception { docker.dockerCompose().up(); } @After public void tearDown() throws Exception { docker.dockerCompose().down(); }
![Page 22: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/22.jpg)
Health Checks & Logs
@Rule public DockerComposeRule docker = DockerComposeRule.builder() .file("../docker-compose.yml") .waitingForService("greeting-service", toRespondOverHttp(8080, TO_EXTERNAL_URI)) .waitingForService("counter-service", toRespondOverHttp(8080, TO_EXTERNAL_URI)) .waitingForService("master-service", toRespondOverHttp(8080, TO_EXTERNAL_URI)) .saveLogsTo("build/docker-logs") .build();
![Page 23: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/23.jpg)
![Page 24: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/24.jpg)
What could possibly go wrong?
@Test public void shouldReturnHolaWhenGreetingServiceDown(){ docker.dockerCompose().container("greeting-service").stop(); get("/info") .then().assertThat() .body("greeting", is("Hola!")); }
![Page 25: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/25.jpg)
What could possibly go wrong?
@Test public void shouldReturn42WhenCounterServiceDown() { docker.dockerCompose().container("counter-service").stop(); get("/info") .then().assertThat() .body("counter", is(42)); }
![Page 26: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/26.jpg)
@FeignClient(name = "greeting", url = "http://greeting-service:8080", fallback = DefaultGreeting::class) interface GreetingClient { @RequestMapping(value = "/greeting", method = arrayOf(RequestMethod.GET)) fun greeting(): Greeting }
@Component class DefaultGreeting : GreetingClient { override fun greeting(): Greeting { return Greeting("Hola!") } }
Master Service - Greeting Client
![Page 27: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/27.jpg)
Master Service - Counter Client@FeignClient(name = "counter", url = "http://counter-service:8080", fallback = DefaultCounter::class) interface CounterClient { @RequestMapping(value = “/counter”, method = arrayOf(RequestMethod.GET)) fun counter(): Counter }
@Component class DefaultCounter : CounterClient { override fun counter(): Counter { return Counter(42) } }
![Page 28: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/28.jpg)
Demo
![Page 29: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/29.jpg)
References https://github.com/d-lorenc/junit-docker-demo https://github.com/palantir/docker-compose-rule
![Page 30: Automated integration testing of distributed systems with Docker Compose and JUnit](https://reader031.fdocuments.in/reader031/viewer/2022020410/58eeca221a28ab4f0d8b4617/html5/thumbnails/30.jpg)