ようへいの日々精進XP

よかろうもん

minio を CircleCI のジョブで利用する + 引き続き、shellspec を触っている 〜 週末やったこと (2) 〜

tl;dr

週末に細々と自分が気になることをやってみたのでメモっておきます。

全て、以下の Github リポジトリに集約しています。

github.com

minio とは

github.com

MinIO is a High Performance Object Storage released under Apache License v2.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads.

Amazon S3 API と互換性があるオブジェクトストレージで、個人的にメリットを感じているのは、Docker でシュッと起動出来る点と、専用のコマンドラインツールが提供されている点です。

モチベーション

一言で言うと、「S3 API を操作するスクリプトの動作確認をしたい」。

AWS CLI なり、AWS SDK で作った S3 API を操作するスクリプトをちょくちょく作ることがありますが、動作を確認するにあたり、これまでは、実際に S3 にバケットを作って動作確認していました。簡単にバケットを作れたり、オブジェクトを放り込めたりしますが、同時に消してはいけないオブジェクト等を消してしまう可能性も否めません。

ということで、手元で手軽に S3 の API を試せる環境を探していたところ、minio を見つけた次第です。

そして、動作確認を自動化するべく、CircleCI で minio を動かしつつ、動作確認 (インテグレーションテスト) を行おうと思った次第です。

簡単だった

先人のお知恵拝借ということで、ググっていたら、同じモチベーションの方がいらっしゃったので、その方のコードを利用させて頂きました。

version: 2.1

commands:
... 略 ...
  install_minio_client:
      steps:
        - run:
            name: Install minio client
            command: |
              mkdir ${HOME}/bin && \
                curl -sSL https://dl.minio.io/client/mc/release/linux-amd64/mc -o ${HOME}/bin/mc && \
                chmod +x ${HOME}/bin/mc

jobs:
  shellspec-test:
    docker:
      - image: cimg/base:stable
        environment:
          AWS_ACCESS_KEY_ID: EXAMPLEKEY123
          AWS_SECRET_ACCESS_KEY: EXAMPLESECRET123456
          AWS_DEFAULT_REGION: us-east-1
          AWS_REGION: us-east-1
          AWS_ENDPOINT: http://minio:9000
          AWS_DISABLE_SSL: true
          PARAM_BUCKET: 'example-bucket'
      - image: minio/minio:latest
        name: minio
        environment:
          MINIO_ACCESS_KEY: EXAMPLEKEY123
          MINIO_SECRET_KEY: EXAMPLESECRET123456
        command: ["server", "/data"]
    steps:
      - checkout
      - install_base_dependencies
      - install_shellspec
      - install_awscli
      - install_minio_client
      - run:
          name: Run shellspec test
          command: |
            cd src/sample
            shellspec -s bash --format document

workflows:
  version: 2
  shellspec-test:
    jobs:
      - shellspec-test:
          filters:
            branches:
              only:
                - master
                - main

minio 自体を起動している部分は、以下の通りと非常にシンプルです。

      - image: minio/minio:latest
        name: minio
        environment:
          MINIO_ACCESS_KEY: EXAMPLEKEY123
          MINIO_SECRET_KEY: EXAMPLESECRET123456
        command: ["server", "/data"]

そして、学びだったのが、一つのジョブの中に複数の Docker イメージの指定が出来ることでした。

動作確認

テスト対象

テストされる側のコード (シェルスクリプト) は以下の通りです。

sample1() {
  arg=""
  if [ -n "${1}" ];then
    arg="${1}"
    echo "Hello ${1}!"
  else
    echo "Hello world!"
  fi
}

sample2() {
  if [ -n "${AWS_ENDPOINT}" ];then
    res=$(aws --endpoint-url "${AWS_ENDPOINT}" s3api list-objects-v2 --bucket "${PARAM_BUCKET}")
    stat=$?
  else
    res=$(aws s3api list-objects-v2 --bucket "${PARAM_BUCKET}")
    stat=$?
  fi

  if [ -n "$res" -a "$stat" = "0" ];then
    echo $res | jq -r '[.Contents[].Key]|@tsv'
  else
    echo ""
  fi
}

sample2() の関数が minio を利用することを想定したコードです。環境変数 AWS_ENDPOINT が指定されている場合、 AWS CLIs3api list-object-v2--endoint-url オプションを付与して実行します。オブジェクトの一覧が TSV 形式で出力されることを期待しています。

ちなみに、sample1() は後述の shellspec の動作確認を行う為のコードです。

テストコード

テストコードは shellspec を使って記述しました。shellspec については、以下の記事で書かせて頂いています。

inokara.hateblo.jp

以下、テストコードを全文掲載しています。

Describe 'lib/sample.sh'
  Include lib/sample.sh

  setup() {
    ${HOME}/bin/mc config host add minio ${AWS_ENDPOINT} ${AWS_ACCESS_KEY_ID} ${AWS_SECRET_ACCESS_KEY} > /dev/null
    ${HOME}/bin/mc mb minio/example-bucket > /dev/null
    touch object1 object2
    for ob in object1 object2
    do
      ${HOME}/bin/mc cp $ob minio/example-bucket/$ob > /dev/null
    done
  }

  cleanup() { 
    ${HOME}/bin/mc rb --force minio/example-bucket > /dev/null
    rm -f object1 object2
  }

  BeforeCall 'setup'
  AfterCall 'cleanup'

... 略 ...

  It 'check output (minio check)'
    When call sample2
    The output should match pattern '*object*'
  End
End

setup() 関数では、minio 専用のクライアントである mc コマンドを使って、minio の初期設定やバケットの作成等を行っています。

そして、以下の部分で sample2() 関数の出力をテストしています。

  It 'check output (minio check)'
    When call sample2
    The output should match pattern '*object*'
  End

テスト結果

VS Code のターミナル上で shellspec を実行してみると、以下のように出力されました。

f:id:inokara:20210111171632p:plain

そして、CircleCI 上でも、以下のように出力されました。

f:id:inokara:20210111171747p:plain

やったね!

以上

週末にもくもくしたメモでした!

参考

以下の資料を参考にさせて頂きました。

github.com

github.com