“a unit test would have caught this”...“a unit test would have caught this” fast and cheap...

29

Upload: others

Post on 27-Sep-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017
Page 2: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

“A Unit Test Would Have Caught This”Fast and cheap testing for production engineers

Andrew Ryan, Facebook Inc.SRECon Asia 2017

Page 3: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

def calc_5min_rate(pkts_now, pkts_5min):if pkts_now - pkts_5min > 0:

rate = (pkts_now – pkts_5min) / 300elif pkts_now - pkts_5min < 0:

rate = 0return rate

We all write buggy code sometimes…

But what if pkts_now == pkts_5min?

NameError: name 'rate' is not defined

Page 4: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

#!/bin/bashtmpdir=$(mktemp –d)

#... do some stuff

# Cleanup and exitrm –rf $tmp/*exit 0

…and some of those bugs are really bad#!/bin/bashtmpdir=$(mktemp –d)#...#... do some stuff#...# Cleanup and exitrm –rf /*exit 0

Page 5: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017
Page 6: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017
Page 7: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

• “It’s just a shell script”• “{I don’t have time/I don’t know how} to write tests”• “I’m not a software engineer”• “I ran it. It seems to work.”• “My code has too many external dependencies”

Why Production Engineers don’t testActual lame excuses I’ve personally used

Page 8: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

1. Shell scripts2. Tooling in Python/Perl/Ruby/Go/etc.3. Configuration management (Chef, Puppet, Ansible,

cfengine, etc.)

Code we write as Production Engineers

Page 9: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Testing Shell Scripts

Page 10: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

The best way to test shell scripts is not to write them

Page 11: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

#!/bin/bash –ue

If you must write shell scripts (1)

-u Error on unset variables-e Exit if any command exits non-zero

Protect yourself at runtime

Page 12: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

If you must write shell scripts (2)

Shellcheckhttp://shellcheck.net

Lint!

Page 13: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

If you must write shell scripts (3)

BATShttps://github.com/sstephenson/bats

Unit test!

shunit2https://github.com/kward/shunit2

Page 14: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Testing in Python

Page 15: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Lint!

yapfhttps://github.com/google/yapf

flake8http://flake8.pycqa.org/

pylinthttps://www.pylint.org

Page 16: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

def calc_5min_rate(pkts_now, pkts_5min):if pkts_now - pkts_5min > 0:

rate = (pkts_now – pkts_5min) / 300elif pkts_now - pkts_5min < 0:

rate = 0return rate

Unit testing

class testCalcRate(unittest.TestCase):def test_calc_5min_rate(self):self.assertEqual(calc_5min_rate(3300, 300), 10) #PASSself.assertEqual(calc_5min_rate(300, 600), 0) #PASSself.assertEqual(calc_5min_rate(600, 600), 0) #FAIL

Page 17: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Unit testing changes the way you write code

Page 18: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

def tmp_cleaner():subprocess.check_output(

"rm -rf /tmp/foo*", shell=True )

Mocks: taming external dependencies

@mock.patch('subprocess.check_output')def test_tmp_cleaner(self, mock_check_output):

tmp_cleaner()mock_check_output.assert_called_with(

"rm -rf /tmp/foo*", shell=True)

Page 19: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Testing in Chef

Page 20: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Configuration *is* code

Page 21: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Lint!

foodcritic: Chef-specific Ruby stylehttp://www.foodcritic.io

rubocop: general Ruby linterhttps://github.com/bbatsov/rubocop

Page 22: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Unit tests for Chef cookbooks

Examples: https://github.com/facebook/chef-cookbooks

Page 23: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Test on one or more servers

taste-tester: Test on 1-2 servershttps://github.com/facebook/taste-tester

Gate changes by host/rack/etc.if condition_met

# apply new chef policyend

Page 24: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Closing thoughts

Page 25: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017
Page 26: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

People come and go, but a good test lasts forever

Page 27: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017
Page 28: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017

Where to go from here

Integration with CI toolsJenkins, Travis CI, KitchenCI, Serverspec, etc.

Integration with code review toolsPhabricator, Review Board, etc.

Page 29: “A Unit Test Would Have Caught This”...“A Unit Test Would Have Caught This” Fast and cheap testing for production engineers Andrew Ryan, Facebook Inc. SREConAsia 2017