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

ScalaのUnitテストでDocker

 ScalaのUnitテストでDocker

キノコがDockerについて勉強する会
https://kinoko-hoge.connpass.com/event/88048/

サンプルコードはこちら。
https://github.com/yoshiyoshifujii/180623_using_docker_in_unit_test_of_scala

yoshiyoshifujii

June 30, 2018
Tweet

More Decks by yoshiyoshifujii

Other Decks in Technology

Transcript

  1. SCALA

    SCALA

    UNIT
    テスト
    UNIT
    テスト

    でDOCKER
    DOCKER
    @yoshiyoshifujii
    1

    View Slide

  2. こんにちは
    こんにちは
    Yoshitaka Fujii
    Software Engineer
    Scala / DDD / Microservices / Serverless / Agile
    @yoshiyoshifujii

    View Slide

  3. 2

    View Slide

  4. UNIT
    テスト
    UNIT
    テスト
    で毎回、苦労
    で毎回、苦労
    するところ
    するところ
    3

    View Slide

  5. データベースを操作するプログラムのテスト
    Mock
    とかにしちゃいがち
    ElasticSearch
    Amazon Simple Queue Service
    様々な外部サービス/
    ミドルウェア
    4

    View Slide

  6. 開発のとき
    開発のとき
    git clone
    して test
    ができない
    環境構築手順書が必要(Windows
    版、macOS
    版…)
    動かないスクリプト
    共通のサーバー
    5

    View Slide

  7. DEPLOY
    のとき
    DEPLOY
    のとき
    Jenkins Slave
    に事前にインストール
    インストールできない場合は接続できるように
    版が変わったらSlave
    の環境を更新
    職人の誕生
    開発環境と別で対応する必要がある
    開発環境と共存にすると、ルールでしばったり大変
    6

    View Slide

  8. 理想
    理想
    Unit
    テスト実行したら環境できて欲しい
    開発もCD/CI
    も実行したら環境できて欲しい
    git clone
    したら何も考えずに test
    実行したい
    7

    View Slide

  9. DOCKER
    ならできそう
    DOCKER
    ならできそう
    docker
    コマンドを実行したらimage
    取れるし
    docker
    コマンドを実行したら環境できるし
    Unit
    テストのbefore/after
    でなんとかなりそう
    8

    View Slide

  10. 探したらあっ
    探したらあっ


    whisklabs/docker-it-scala
    9

    View Slide

  11. SETUP
    SETUP
    libraryDependencies ++= Seq(
    "com.whisk" %% "docker-testkit-scalatest" % "0.9.5" % "test",
    "com.whisk" %% "docker-testkit-impl-spotify" % "0.9.5" % "test"
    )
    10

    View Slide

  12. ちなみに…
    ちなみに…
    は、
    は、 に

    依存しています。
    依存しています。
    は、Java
    ライブラリなので、こ
    は、Java
    ライブラリなので、こ
    れを使ってうまいことやれば、Java
    で出来る。
    れを使ってうまいことやれば、Java
    で出来る。
    (
    はずです。試してません…)
    (
    はずです。試してません…)
    whisklabs/docker-it-scala
    whisklabs/docker-it-scala spotify/docker-client
    spotify/docker-client
    spotify/docker-client
    spotify/docker-client
    11

    View Slide

  13. 今回はDynamoDB
    で試してみた
    今回はDynamoDB
    で試してみた
    libraryDependencies ++= Seq(
    "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.353"
    )
    12

    View Slide

  14. DockerSpecSupport.scala
    DockerSpecSupport.scala
    Spotify
    のDocker Client
    を使って
    Spotify
    のDocker Client
    を使って
    docker
    を操作する基底となる処理を書く。
    docker
    を操作する基底となる処理を書く。
    trait DockerSpecSupport extends DockerTestKit { this: Suite =>
    private val dockerClient: DockerClient =
    DefaultDockerClient.fromEnv().build()
    override implicit def dockerFactory: DockerFactory =
    new SpotifyDockerFactory(dockerClient)
    }
    13

    View Slide

  15. DockerDynamoDBSpecSupport.scala
    DockerDynamoDBSpecSupport.scala
    trait DockerDynamoDBSpecSupport extends DockerSpecSupport { this:
    protected val dynamoDBPort = RandomSocket.nextPort()
    protected val dynamoDBContainer =
    DockerContainer("fingershock/dynamodb-local:latest")
    .withPorts(8000 -> Some(dynamoDBPort))
    protected val dynamoDBClient: AmazonDynamoDB =
    AmazonDynamoDBClientBuilder.standard()
    .withEndpointConfiguration(
    new EndpointConfiguration(
    s"http://127.0.0.1:$dynamoDBPort", Regions.AP_NORTHEAST_
    )).build()
    }
    14

    View Slide

  16. DynamoDBSpec.scala
    DynamoDBSpec.scala
    class DynamoDBSpec extends FlatSpec with Matchers with DockerDynam
    private val TableName: String = "sample-table"
    override def dockerContainers: List[DockerContainer] =
    dynamoDBContainer :: super.dockerContainers
    override def beforeAll(): Unit = { ... }
    override def afterAll(): Unit = { ... }
    "DynamoDB" should "success" in { ... }
    }
    15

    View Slide

  17. DynamoDBSpec.scala #beforeAll
    DynamoDBSpec.scala #beforeAll
    override def beforeAll(): Unit = {
    super.beforeAll()
    val createTableRequest = new CreateTableRequest()
    .withTableName(TableName)
    .withAttributeDefinitions(
    new AttributeDefinition("id", ScalarAttributeType.S))
    .withKeySchema(
    new KeySchemaElement("id", KeyType.HASH))
    .withProvisionedThroughput(
    new ProvisionedThroughput(1L, 1L))
    dynamoDBClient.createTable(createTableRequest)
    }
    16

    View Slide

  18. DynamoDBSpec.scala #afterAll
    DynamoDBSpec.scala #afterAll
    override def afterAll(): Unit = {
    dynamoDBClient.deleteTable(TableName)
    super.afterAll()
    }
    17

    View Slide

  19. DynamoDBSpec.scala #DynamoDB should success
    DynamoDBSpec.scala #DynamoDB should success
    "DynamoDB" should "success" in {
    dynamoDBClient.putItem(
    TableName,
    Map(
    "id" -> new AttributeValue().withS("aaaaa")
    ).asJava
    ).getAttributes shouldBe null
    dynamoDBClient.getItem(
    TableName,
    Map(
    "id" -> new AttributeValue().withS("aaaaa")
    ).asJava
    ).getItem.asScala("id").getS shouldBe "aaaaa"
    }
    18

    View Slide

  20. run
    run
    21:31:58.171 [pool-5-thread-1] DEBUG com.spotify.docker.client.Do
    21:31:59.184 [pool-5-thread-1] DEBUG com.spotify.docker.client.Do
    21:32:01.330 [pool-7-thread-1] DEBUG com.spotify.docker.client.au
    java.lang.IllegalArgumentException: serverAddress=https://index.d
    at com.spotify.docker.client.DockerConfigReader.parseDock
    at com.spotify.docker.client.DockerConfigReader.fromConfi
    at com.spotify.docker.client.auth.ConfigFileRegistryAuthSu
    at com.spotify.docker.client.DefaultDockerClient.pull(Def
    at com.spotify.docker.client.DefaultDockerClient.pull(Def
    at com.whisk.docker.impl.spotify.SpotifyDockerCommandExecu
    at com.whisk.docker.impl.spotify.SpotifyDockerCommandExecu
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0
    at scala.concurrent.Future$.$anonfun$apply$1(Future.scala
    at scala.concurrent.Future$$$Lambda$3750/1704912779.apply
    at scala.util.Success.$anonfun$map$1(Try.scala:251)
    at scala util Success map(Try scala:209)
    19

    View Slide

  21. まとめ
    まとめ
    を使えば、
    を使えば、
    Unit
    テストからDocker Image
    を実行できる。
    Unit
    テストからDocker Image
    を実行できる。
    は、Java
    ライブラリなので、
    は、Java
    ライブラリなので、
    きっと同じことできる。
    きっと同じことできる。
    git clone
    したら test
    がすぐできる。
    git clone
    したら test
    がすぐできる。
    CD/CI
    のときも、環境作らなくて良い。
    CD/CI
    のときも、環境作らなくて良い。
    サンプルコードは、
    サンプルコードは、
    whisklabs/docker-it-scala
    whisklabs/docker-it-scala
    spotify/docker-client
    spotify/docker-client
    yoshiyoshifujii/180623_using_docker_in_unit_test_of
    yoshiyoshifujii/180623_using_docker_in_unit_test_of
    20

    View Slide

  22. 以上です
    以上です
    21

    View Slide