Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Software Testing in AWS IoT with The Power of P...

Software Testing in AWS IoT with The Power of Python

Serverless Meetup Tokyo #10 の登壇資料です。

Avatar for Koji Nakayama

Koji Nakayama

August 31, 2018
Tweet

More Decks by Koji Nakayama

Other Decks in Technology

Transcript

  1. Software Testing in AWS IoT with The Power of Python

    Serverless Meetup Tokyo #10 2018/08/31 Koji Nakayama 1
  2. IoT Rule;AWS IoT SQL • IoT Rule΅SQLΨڥአͭͼIoTϔϝαφ͡ΟᭆΟ΢ͼͣ͵ϔЄό Ψ඙̵֢ͭ஍姆΄AWSςЄϠφ΁ͳ΄ϔЄόΨჁͯͩ;͢ͽͣ Ρ SELECT

    *, topic(3) as deviceId, timestamp() as timestamp FROM '$aws/things/+/shadow/update' WHERE state.reported.temperature > 20 13
  3. αЀϓνϹЄτϴЀϓφϕΨͿͩͽΚΡ͡ • ϯϐμᔮϑЄϸ vs AWS΄䋚厏ह • ϯϐμᔮϑЄϸ(LocalStack/moto/etc...)ͽ䌏䖕ݢᚆ΀䁰ݳ΅च๜ͳ΢ ͽ亹ΔͱͼΡ • ϢΰЄϖϝϐμϸЄϤΨ㱢ض

    • ϯϐμᔮϑЄϸͽ΄αЀϓνϹЄτϴЀϓφϕΨग़ͥ䨗͚ͼ̵AWS 䋚厏हͽ΄αЀϓνϹЄτϴЀΨ੝΀ͥͯΡ䜐ኼ • IoT Rule΅ͳΘͳΘ๚䌏䖕΀Ξ͜΀΄ͽAWS΄䋚厏हͽ䋚ෞ 23
  4. ڥአͯΡϯυϲЄϸ • MQTTμ϶αίЀϕ: AWS IoT Device SDK for Python •

    ϓφϕϢϹЄϭϼЄμ: pytest • ͳ΄՜: • HTTPμ϶αίЀϕ: requests • Cognito;΄SRP: warrant • AWS IoT;΄Ϸϕ϶α㳌ቘ: tenacity 33
  5. ϓφϕϔЄό΄伛㯪 @pytest.mark.parametrize( 'publish_message', [ (({ 'state': { 'reported': { 'foo':

    'bar', 'baz': 'qux' } } })) ], indirect=True) def test_fetch_device_data(api_endpoint, token, publish_message): ... 34
  6. ᥴ抍 • pytest΅fixture;͚͜՛奲ΕͽϥϸϞ樛හΨ conftest.py ΁懿ᬿݢᚆ1 • ϓφϕξЄφ΄୚හ΁fixtureΨჁͭͼ̵ϓφϕڹ΁ͳ΢Ψ䋚ᤈͽͣΡ • ͩͩͽMQTTμ϶αЀϕ͡ΟϔЄό΄Publish;SRP扯戣Ψ亹Δͱͼͥ͠ •

    @pytest.mark.parametrize ͽϓφϕϔЄόΨϞ϶ϮЄό۸̵ͭ1ͺ΄ϓφϕξЄφͽ姜嬄௔ ΨṛΗΡͩ;͢ͽͣΡ2 • indirect=True ͭͼͥ͠;fixture΁ϓφϕϔЄόΨჁͯͩ;͢ͽͣΡ3 3 https://docs.pytest.org/en/latest/example/parametrize.html#apply-indirect-on-particular-arguments 2 https://docs.pytest.org/en/latest/parametrize.html 1 https://docs.pytest.org/en/latest/plugins.html 35
  7. MQTTμ϶αЀϕ͡Ο΄Publish from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient @pytest.fixture(scope='function') @retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, max=10)) def

    publish_message(request): ... mqtt = AWSIoTMQTTClient('my_thing_01') mqtt.configureEndpoint(..., 8883) mqtt.configureCredentials(...) mqtt.connect() for message in request.param: mqtt.publish(topic, json.dumps(message), 1) time.sleep(5) 36
  8. ᥴ抍 • fixture΅ϔπϹЄόͽ愢හ೰ਧͽͣΡ • pytest΅scope;͚͜՛奲ΕͽfixtureΨϓφϕξЄφ樌ͽوํͯΡͩ;͢ݢᚆ4 • ηϣυδμϕ΄ኞ౮΁πφϕ͢͡͡ΡfixtureΨوํͭͼͥ͠;ϞϢζЄϫЀφ͢ṛΔΡ • tenacity΄ retry

    ϔπϹЄόͽAWS IoTεЀϖϪαЀϕ;΄Ϸϕ϶α㳌ቘΨ懿ᬿ5 • pytest䰤伛΄ request fixtureͽϞ϶ϮЄό۸ͫ΢͵ϓφϕϔЄόΨ݇ᆙͭͼ͚Ρ6 6 https://docs.pytest.org/en/latest/reference.html#request 5 https://github.com/jd/tenacity 4 https://docs.pytest.org/en/latest/fixture.html#scope-sharing-a-fixture-instance-across-tests-in-a-class-module-or- session 37
  9. requestsϯυϲЄϸͽAPI΁ίμψφ import requests @pytest.mark.parametrize( 'publish_message', [ ... def test_fetch_device_data(api_endpoint, token,

    publish_message): response = requests.get(f'{api_endpoint}/devices/my_thing_01', headers={'Authorization': token}) body = response.json() assert response.status_code == 200 assert body['deviceId'] == 'my_thing_01' 38
  10. warrant΁ΞΡCognito΄SRP from warrant.aws_srp import AWSSRP @pytest.fixture(scope='session') def token(): config_abs_path =

    str(pathlib.Path(__file__).parent.joinpath('configs').resolve()) config = json.load(open(f'{config_abs_path}/config.json', 'r')) aws = AWSSRP(username=config['username'], password=config['password'], pool_id=config['pool_id'], client_id=config['client_id'], client=boto3.client('cognito-idp')) tokens = aws.authenticate_user() return tokens['AuthenticationResult']['AccessToken'] 39