Top Banner
Making SoundCloud’s µ-services safe(r) to deploy Move Fast and Consumer-Driven- Contract-Test Things XP Days Ukraine 2017
81

Move fast and consumer driven contract test things

Jan 21, 2018

Download

Software

Alon Pe'er
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Move fast and consumer driven contract test things

Making SoundCloud’s µ-services safe(r) to deploy

Move Fast and Consumer-Driven-Contract-Test Things

XP Days Ukraine 2017

Page 2: Move fast and consumer driven contract test things

2.5 years @ SoundCloud Monetization Team Backend Engineer

@alonpeer

Page 3: Move fast and consumer driven contract test things

About SoundCloud

a cloud full of sounds

135M tracks, 175M listeners, 12 hours/minute

300+ services / 50+ teams

Page 4: Move fast and consumer driven contract test things

Agenda

● Testing, monolith style

● My first steps @ SoundCloud

● Introducing contract tests

● Pactifying our services

● Caveats

● QA Q&A

Page 5: Move fast and consumer driven contract test things

Testing, monolith style

Page 6: Move fast and consumer driven contract test things

● One service, one client

● API changes are easy

● One client team to sync with for migrations

● API deprecation is easy

Testing, monolith styleThe good ol’ days

Page 7: Move fast and consumer driven contract test things

● Different requirements per client

=> Code complexity increases

● Harder to deploy without breaking at least one client

Testing, monolith styleMo clients, mo problems

Page 8: Move fast and consumer driven contract test things

● More manual QA

expensive, slow, prone to human error,

doesn’t scale

● More end-to-end tests

Maintenance nightmare, flaky, slow,

creates bottlenecks

Testing, monolith styleMo clients, mo problems

Page 9: Move fast and consumer driven contract test things

My first steps @ SoundCloud

Page 10: Move fast and consumer driven contract test things

My first steps @ SoundCloud

Whoa, micro-services

Page 11: Move fast and consumer driven contract test things

My first steps @ SoundCloudTesting strategy

E2E

Unit

Integration

Page 12: Move fast and consumer driven contract test things

My first steps @ SoundCloudDigging into post-mortems

© ofsmallthings

Page 13: Move fast and consumer driven contract test things

My first steps @ SoundCloud

“A lack of trust in the acceptance tests caused us to largely ignore the warnings they generated.”

“We couldn’t figure out the impact of the broken acceptance tests, and assumed the only problem was the tests themselves, rather than the underlying code.”

“The commit went through as there weren't any tests for the serialisation from the client to the backend.”

Digging into post-mortems

© ofsmallthings

Page 14: Move fast and consumer driven contract test things

Introducing contract tests

Page 15: Move fast and consumer driven contract test things

Introducing contract testsMy daily routine

© LockeSteerpike

Page 16: Move fast and consumer driven contract test things

Introducing contract testsMy daily routine

© rickandmorty.com

Page 17: Move fast and consumer driven contract test things

Unit tests are not enoughIntroducing contract tests

“#cake” >> { result = call(“cake”) assert(result == “lie”)}

GET “/cake”: return “lie”

Page 18: Move fast and consumer driven contract test things

Unit tests are not enoughIntroducing contract tests

GET “/cake”: return “truth”

“#cake” >> { result = call(“cake”) assert(result == “lie”)}

Page 19: Move fast and consumer driven contract test things

Unit tests are not enoughIntroducing contract tests

import JsonLibFoo

GET “/cake”: return toJson(current_state)

// { “current_state” : “lie” }

import JsonLibFoo

“#cake” >> { result = fromJson(call(“cake”)) assert(result == “lie”)}

Page 20: Move fast and consumer driven contract test things

Unit tests are not enoughIntroducing contract tests

import JsonLibBar

GET “/cake”: return toJson(current_state)

// { “currentState” : “lie” }

import JsonLibBar

“#cake” >> { result = fromJson(call(“cake”)) assert(result == “lie”)}

Page 21: Move fast and consumer driven contract test things

Introducing contract testsHow this works?

Consumer Provider

End-to-End Test

Page 22: Move fast and consumer driven contract test things

Introducing contract testsHow this works?

Consumer Provider

Unit Test Unit Test

Page 23: Move fast and consumer driven contract test things

Introducing contract testsHow this works?

Consumer Provider

Unit Test Unit Test

Page 24: Move fast and consumer driven contract test things

Introducing contract testsHow this works?

➢ Requesting “/cake”.

➢ Expecting a JSON response

with a key “current_state”.

➢ Asserting deserialization

of the response succeeds.

import JsonLibFoo

GET “/cake”: return toJson(current_state)

// { “current_state” : “lie” }

Consumer

Provider

Page 25: Move fast and consumer driven contract test things

Pactifying our serviceshttp://pact.io

Page 26: Move fast and consumer driven contract test things

What’s Pact?Pactifying our services

● A family of frameworks designed for consumer driven

contract testing.

● Supports JSON over HTTP.

● Impl. for Java, Scala, Go, Ruby, .Net, Swift, JS etc.

● Tests run locally, no external dependencies.

Page 27: Move fast and consumer driven contract test things

What’s Pact?Pactifying our services

Step 1: Define consumer expectations

© pact.io

Page 28: Move fast and consumer driven contract test things

What’s Pact?Pactifying our services

Step 2: Verify expectations on provider

© pact.io

Page 29: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 30: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 31: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 32: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 33: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 34: Move fast and consumer driven contract test things

Consumer: client code (LikesClient)

Page 35: Move fast and consumer driven contract test things

Consumer: client unit test

Page 36: Move fast and consumer driven contract test things

Consumer: client unit test

Page 37: Move fast and consumer driven contract test things

Consumer: client unit test

Page 38: Move fast and consumer driven contract test things

Consumer: client unit test

Page 39: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 40: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 41: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 42: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 43: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 44: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 45: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 46: Move fast and consumer driven contract test things

Consumer: client contract unit test

Page 47: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 48: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 49: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 50: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 51: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 52: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 53: Move fast and consumer driven contract test things

Consumer: my-consumer-likes.json

Page 54: Move fast and consumer driven contract test things

Pactifying our servicesProvider side verification

● Collect pact files from consumers and verify them all.

● Keep your provider environment isolated.

○ Dockerized databases.

○ Test doubles for upstream services.

Page 55: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

Page 56: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

LikesApp

LikesDB

Page 57: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

Set state:“User 1000 has liked 2 tracks”

LikesApp

LikesDB

Page 58: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

INSERTlikes

Set state:“User 1000 has liked 2 tracks”

LikesApp

LikesDB

Page 59: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

INSERTlikes

Set state:“User 1000 has liked 2 tracks”

HTTP Request: GET /likes/1000

LikesApp

LikesDB

Page 60: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

HTTP Request: GET /likes/1000

HTTP Response: 200 OK

INSERTlikes

Set state:“User 1000 has liked 2 tracks”

LikesApp

LikesDB

Page 61: Move fast and consumer driven contract test things

Pactifying our servicesProvider states

LikesApp

LikesDB

HTTP Response: 200 OK

INSERTlikes

Set state:“User 1000 has liked 2 tracks”

HTTP Request: GET /likes/2000

HTTP Response: 404 Not Found

Set state:“User 2000 has liked no tracks”

HTTP Request: GET /likes/1000

DELETElikes

Page 62: Move fast and consumer driven contract test things

Pactifying our servicesPact broker

● Share pact files between projects.

● API for pact frameworks to fetch all pacts by provider.

● Support for versioning and tagging.

● Useful UI and visualization of the network.

Page 63: Move fast and consumer driven contract test things

Pactifying our servicesPact broker

© pact broker

Page 64: Move fast and consumer driven contract test things

Pactifying our servicesPact broker

© pact broker

Page 65: Move fast and consumer driven contract test things

Pactifying our servicesPact broker

© pact broker

Page 66: Move fast and consumer driven contract test things

Pactifying our servicesOur CI pipeline

Push new change

Generate consumer contracts

DeployUpload

pacts & tag with ‘prod’

Consumer pipeline

Page 67: Move fast and consumer driven contract test things

Pactifying our servicesOur CI pipeline

Push new change Deploy

Upload pacts & tag with ‘prod’

Consumer pipeline

Push new change

Verify all ‘prod’-tagged

pactsDeploy

Provider pipeline

Generate consumer contracts

Page 68: Move fast and consumer driven contract test things

● Communication is key.

Caveats

Page 69: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

Caveats

Page 70: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

● Learning curve per pact framework.

Caveats

Page 71: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

● Learning curve per pact framework.

● Frameworks are WIP.

Caveats

Page 72: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

● Learning curve per pact framework.

● Frameworks are WIP.

● Provider side setup is time consuming.

Caveats

Page 73: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

● Learning curve per pact framework.

● Frameworks are WIP.

● Provider side setup is time consuming.

● Automating consumer-triggered provider verification.

Caveats

Page 74: Move fast and consumer driven contract test things

● Communication is key.

● New moving parts.

● Learning curve per pact framework.

● Frameworks are WIP.

● Provider side setup is time consuming.

● Automating consumer-triggered provider verification.

● Adoption is essential.

Caveats

Page 75: Move fast and consumer driven contract test things

Recap

Page 76: Move fast and consumer driven contract test things

Recap

Write contract tests

Cons

umer

s

Page 77: Move fast and consumer driven contract test things

Recap

Write contract tests Generate pact files

Cons

umer

s

Page 78: Move fast and consumer driven contract test things

Recap

Write contract tests Generate pact files

Publish to broker

Cons

umer

s

Page 79: Move fast and consumer driven contract test things

Recap

Write contract tests Generate pact files

Publish to brokerVerify pacts

Cons

umer

s

Prov

iders

Page 80: Move fast and consumer driven contract test things

Recap

Write contract tests Generate pact files

Publish to brokerVerify pacts

Cons

umer

s

Prov

iders

Page 81: Move fast and consumer driven contract test things

QA Q&A

@alonpeer