vincit teatime 2015 - niko kurtti: case shopify: saas:n testaaminen, mihin unohtui toinen puolikas?

40
SaaS testaaminen Miksi testata vain puolet?

Upload: vincitoy

Post on 14-Jul-2015

171 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

SaaS testaaminenMiksi testata vain puolet?

Page 2: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Shopifacts

• Alunperin pelkkä verkkokauppa-alusta, nykyisin tarjoaa myös mahdollisuuden kivijalkamyyntiin.

• 150k kauppiasta, mm. Tesla, Github, LA Lakers, Wikipedia, Kith,...

• 300k RPM+, flash sales >1M RPM• Ruby on Rails, MySQL, Redis, Memcache, Elasticsearch,

Chef, Go, Podding, Multi-DC,...

Page 3: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?
Page 4: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?
Page 5: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Downtimeen ei ole varaa

Page 6: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Muutos on tästä huolimatta jatkuvaa

Pelkästään Shopify core deployataan kymmeniä kertoja päivässä.

Infrakoodia / muutoksia tämän lisäksi myös tusina+ päivässä

Ympärillä olevia sovelluksia kymmeniä, teema/sovelluskaupat, julkiwebbi, kuvaskaalain, maksujärjestelmä, jne...

Page 7: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Testauksesta

Page 8: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Ohjelmistokehityksessä arkipäivää

Moderniin kehitykseen kuuluu oleellisesti vähintäänkin yksikkötestaus ja integraatiotestaus CI-järjestelmässä.

Tämän lisäksi löytyy pitkälle kehitettyjä menetelmiä ja sovelluksia aina koodianalyysistä suorituskykytestaukseen.

..puhumattakaan TDD/BDD -leiristäTestaaminen on oletusarvo, ei poikkeus

Page 9: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Esimerkki Java-ohjelman testaamisesta

Ennen pushia:- Koodianalyysi, Findbugs- Yksikkö/integraatiotestaus, JUnit

Ennen deployta tuotantoon:- Järjestelmätestaus, Selenium- Suorituskykytestaus, JMeter

( - Manuaalinen hyväksymistestaus )

Page 10: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Testaus infrapuolella

Ennen pushia:- Mikä versiohallinta..?

Ennen deployta tuotantoon:- Luin Googlen viidennestä hitistä että näin se toimii ja kävin manuaalisesti testaamassa

Tai vaihtoehtoisesti:

Käyttöpalvelutarjoaja vastaa tästä osuudesta

Page 11: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?
Page 12: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Mutta me tehdään devopsia agilesti?

Vihjeellisissä yrityksissä käytössä CM tuotantoympäristöissä jotka jollain tavalla kiinni versiohallinnassa.

Ohjelmistokehittäjillä Vagrantit, Dockerit, Ansiblet ja devopsreactions auki selaimessa

Hyvistä lähtökohdista huolimatta inframuutoksien testaus kuitenkin harvinaista ja kevyttä happy case testausta omalla työasemalla.

Page 13: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Jos sammutan tämän koneen niin tuo toinen varmaan palvelee? Joo, näinhän se teki kun selaimessa F5:sta kliksuttelin— Senior Enterprise Devops Fullstack Consultant Architect

Page 14: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Päätökset tuotantoon liittyen useimmiten mututuntumalla

Googlen viides hitti, kaveri ja näin tämä edellisessäkin projektissa toimi.

Ei syvällistä ymmärrystä ratkaisujen toiminnasta tai vaikutuksista.

...istuntojen tila, inflight requestien kohtalo, käyttäjälle palautuvat ilmoitukset, MTTR jne

Page 15: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Onko täydelliselläkään koodilla arvoa jos käyttäjät eivät voi

siitä hyötyä?

Page 16: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?
Page 17: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Infratestauksen mahdollisuudet

Ennen pushia:- Koodianalyysi, Foodcritic- Yksikkö/integraatiotestaus, Chefspec/Serverspec/Test kitchen

Ennen deployta tuotantoon:- Järjestelmätestaus, Minitest- Suorituskykytestaus, mysqlslap, memaslap, redis-benchmark jne.

( - Manuaalinen hyväksymistestaus )

Page 18: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Koodianalyysi, Foodcritic

Koodianalyysityökalu Chef cookbookeille

Todellinen arvo omissa säännöissä

Shopifylla cookbooks repossa 130 contributoria, joten mahdoton varmistua, että kaikki ovat tietoisia kaikista käytännöistä luontaisesti

Kevyt ajaa, ideaalinen integroida esim pre-commit hookkiin Gitissä

Page 19: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

rule 'SHOP003', 'Individual email address used; prefer team email addresses' do tags %w{style recipe shopify} cookbook do |path| whitelist = %w(ops admins data-engineering database stack-team ) recipes = Dir["#{path}/{#{standard_cookbook_subdirs.join(',')}}/**/*.rb"] recipes += Dir["#{path}/*.rb"] recipes.collect do |recipe| File.readlines(recipe).collect.with_index do |line, index| if line.match("^((?!#{whitelist.join('|')}|\#).)*@shopify.com") { :filename => recipe, :matched => recipe, :line => index+1, :column => 0 } end end.compact end.flatten endend

Page 20: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Chefspec (yksikkötestaus)

Testaa Chef :n tekemiä muutoksia muistinvaraisesti

CM -työkalut odottavat tietynlaisen tilan (lähtötila tai nykyinen) kun muutoksia ajetaan. Lokaali työasema ei yleensä samassa tilassa palvelinten kanssa.

Tarjoaa perinteisen tarkan yksikkötestaamisen, mutta tilallisuuden vuoksi vaatii paljon vaivaa arvojen mockkaukseen.

Vaikea myöskään pitää mockkeja ja palvelinten tiloja synkassa.

Page 21: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

execute "maybe-convert-btrfs-to-overlay" do only_if 'stat -c%T -f /u|grep btrfs' notifies :create, 'cookbook_file[/opt/convert-btrfs-to-overlay]', :immediatelyend

☁ cookbooks [master] stat -c%T -f /u

stat: illegal option -- cusage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]

stat on eri työkalu OSX:llä kuin Linuxilla. Eikä /u ole tietysti edes olemassa saati BTRFS omalla Macbookilla...

Page 22: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

context 'btrfs to overlay' do before(:each) do stub_command("stat -c%T -f /u|grep btrfs").and_return(true) end

it 'trigger btrfs conversion to overlay' do expect(chef_run).to run_execute('maybe-convert-btrfs-to-overlay') endend

Mitä tässä testataan? Jos ainoa järkevä testattava asia ( stat -c%T -f /u|grep btrfs ) mockataan mikä arvo jää testille?

Your mileage may vary, Chefspec on todella näppärä apu inhimillisten one-off/typo/if-unless tyyppisten virheiden huomaamiseen

Page 23: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Integraatiotestaus - Test Kitchen/Serverspec

Integraatiotestauksen ero yksikkötestaukseen on se, että yksittäisten ehtojen sijaan testataan tilaa.

Test kitchenissä integraatiot Vagrant, AWS, Docker ja tuki mm. RSpeccille ja Serverspeccille

Järkevää integroida samaan CI-järjestelmään jossa sovellus

Page 24: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

describe 'Base Packages' do %w( curl ... ).each do |package_name| describe package(package_name) do it { should be_installed } end endend

describe 'nginx status' do

it 'enables the nginx service' do expect(service 'nginx').to be_enabled end

it 'starts the nginx service' do expect(service 'nginx').to be_running end

it 'is listening on port 9005' do expect(port 9005).to be_listening end

end

describe nginx_version_is_correct(nginx_version) do its(:exit_status) { should eq 0 } its(:stdout) { should match(/nginx version\: nginx\/1\.7\.9/) }end

Page 25: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Järjestelmätestaus, Clusterfuck,

Hyvin yksinkertainen kehikko halutun kokonaisuuden (esim. HA klusteri) testaamiseen.

Fokus toiminnallisuudessa, ei tietyn työkalun toiminnassa. Esim vastaako palvelu requestiin eikä tekikö Chef muutoksen, tai onko palvelu x käynnissä.

• Vagrant - ohjaa virtuaalikoneita/containereita ja provisiointia

• Minitest - testaus

• Raketaskit + hieman Rubyliimaa - helperit

Valitettavasti ei Open Sourcea, mutta idea muutenkin projektia

Page 26: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Vagrantfile DNS-rekursoreita varten

# DNS recursors clusters["dns"].size.each do |i| machine = clusters["dns"].machines["dns#{i}"]

config.vm.define machine.id, primary: false do |config| initialize_machine(config,machine)

config.vm.provision :chef_solo do |chef| set_cookbook_dirs(chef)

# 1,2 are recursors, 3 just a normal node if i > 2 chef.add_role "vagrant-dns-client" else chef.add_role "vagrant-dns-recursor" end end

# dont overwrite resolv.conf with dhclient preserve_resolv = <<-EOF echo 'make_resolv_conf() { : ; }' > /etc/dhcp/dhclient-enter-hooks.d/zzz-preserve-resolv-conf chmod +x /etc/dhcp/dhclient-enter-hooks.d/zzz-preserve-resolv-conf EOF

config.vm.provision "shell", :inline => preserve_resolv end end

Page 27: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Esimerkkitestejä

def setup @io_ip = host_dns_lookup('shopify.io') @com_ip = host_dns_lookup('shopify.com')

for i in 1..CLUSTERS['dns'].machines.size start_pdnsd('start', "dns#{i}") flush_cache("dns#{i}") end

assert_equal @io_ip, test_dns('shopify.io') end

def test__outgoing_dns_block assert_equal @io_ip, test_dns('shopify.io') #warm cache for shopify.io begin block_dns_outgoing('dns3') do assert_equal @io_ip, test_dns('shopify.io') #test cached record refute_equal @com_ip, test_dns('shopify.com') #test record that is not cached end end assert_equal @com_ip, test_dns('shopify.com') #test that upstreams work after block end

Page 28: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Esimerkkejä helpereistä

def test_dns(name, machine='dns3') `#{ssh_command(machine)} -- "ruby -e \\"require 'socket'; puts Socket.getaddrinfo('#{name}', 80)[0][3]\\""`.chompend

def pdnsd_service(cmd, machine) `#{ssh_command(machine)} -- "sudo /etc/init.d/pdnsd #{cmd}"`end

def block_incoming_traffic(machines, &block) begin machines.each do |machine| block_traffic(machine, "53") end yield ensure machines.each do |machine| open_traffic(machine, "53") end endend

def iptables(machine,port,direction, action="-D") ['tcp', 'udp'].each do |proto| ['eth0', 'eth1'].each do |interf| `#{ssh_command(machine)} -- sudo iptables #{action} #{direction} -p #{proto} --dport #{port} -o #{interf} -j DROP >& /dev/null` end endend

Page 29: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Kertauksena

Findbugs <--> FoodcriticJUnit <--> Serverspec/RSpecJärjestelmätestaus <--> Minitest + liimaa

Lisäpisteitä:- SCM -integraatiot (git hookit jne)- CI-integraatiot

Page 30: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Mikä unohtui?

Page 31: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Järjestelmätestaus sovelluksen näkökulmasta

http://www.shopify.com/technology/16906928-building-and-testing-resilient-ruby-on-rails-applications

Toxiproxy ( https://github.com/Shopify/toxiproxy )

Simuloidaan alla oleva infraa ja sen ongelmaskenaarioita.

Ei ota kantaa toteuttaviin teknologioihin (TCP-proxy)

Testit osana sovelluksen testisuitea

Page 32: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

test "reconnects on next request after a connection timeout" do old_connect_timeout = ActiveRecord::Base.connection_pool.spec.config[:connect_timeout] assert old_connect_timeout begin ActiveRecord::Base.connection_pool.spec.config[:connect_timeout] = 2 ActiveRecord::Base.clear_all_connections! duration = Benchmark.realtime do assert_statsd_increment("Shopify.mysql.connection_error") do assert_raise(Mysql2::Error) do Toxiproxy[:shopify_test_mysql_master].downstream(:latency, latency: 5000).apply do Sharding.master_connection end end end end assert duration.between?(2, 4) assert_equal 1, Sharding.master_connection.select_value("SELECT 1") ensure ActiveRecord::Base.connection_pool.spec.config[:connect_timeout] = old_connect_timeout ActiveRecord::Base.clear_all_connections! end end

Page 33: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Game Day

Otetaan tutkittavaksi yksittäinen osa palvelusta, esim. Elasticsearch -klusteri tai tietovarastot.

Tarkoituksena löytää tutkittavasta kokonaisuudesta vikoja ja erityisesti ymmärtää miten oma palvelu käyttäytyy vikatilanteissa.

Käytännössä toimii parhaiten mutujen ja oletuksien rikkojana (kahvat, timeoutit, kapasiteetti, palautumisnopeus, palautetut ilmoitukset jne.)

Page 34: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Game Dayn perusteet

Game day on järkevintä suorittaa yhdessä tilassa ja riittävästi aikaa (4-8h) varaten. Paikalle kannattaa kutsua n. 6-12 henkilöä esim seuraavalla jaolla:

• Järjestelmän parhaiten tuntevat (dev/ops/devops/opsdev)

• Järjestelmästä kiinnostuneet ja/tai sen kanssa välillisesti työskentelevät

Dedikoitu fasilisaattori helpottaa tilaisuuden läpivetoa sekä purkua.

Page 35: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Aloitus

1. Piirtäkää yhdessä karkea arkkitehtuurikuva järjestelmästä (riippuvuudet, toimijat jne.)

2. Keksikää yhdessä mahdollisia failureskenaarioita, kone kaatuu/verkossa ongelmia jne.

3. Kirjoittakaa ylös kunkin skenaarion kohdalle mikä vaikutus ongelmalla tulisi olla järjestelmään

• Esimerkiksi "IP siirtyy masterilta slavelle, sovellus palauttaa alle 2 sekunnin ajan 500:ia ja toiminta palautuu"

Page 36: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?
Page 37: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Testaus

Äänestäkää skenaarioista 5-7 mielenkiintoisinta testattavaksi ja aloittakaa testaus helpoimmasta

Kunkin testin kohdalla kirjatkaa ylös mitä tapahtui

"IP siirtyi masterilta slavelle, mutta slave ei hyväksynyt kirjoituksia. Sovellus ei myöskään palauttanut kahvoja ja jumiutui vapaiden kantakahvojen puutteeseen"

Älkää jääkö tässä kohtaa pohtimaan miksei oletukset toteutuneet

Page 38: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Tulokset

Testauksen tulokset on järkevää käydä läpi välittömästi.

Mahdolliset parannusehdotukset ja -ideat kannattaa myös samassa tilaisuudessa kirjata projektin tikettijärjestelmään.

Tilaisuuden jälkeen on hyvä kirjata yhteenveto tapahtuneesta ja jakaa se vähintään osallistujille. Bonuspisteitä esim. blogikirjoituksen tjsp tekemisestä

Page 39: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

tl;drPerinteisen ohjelmistokehityksen tasoiseen kehitykseen infrapuolella ei ole mitään estettä. Työkalut ja metodit ovat lähes identtiset.

Käyttäjän kannalta on merkityksetöntä onko palvelu saavuttamattomissa javabugin vaiko palvelinongelman vuoksi

Page 40: Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin unohtui toinen puolikas?

Kysyttävää?ps. http://www.shopify.com/careers