ようへいの日々精進XP

よかろうもん

fake-s3 を使ってみた(ExUnit から利用してみる例)

この記事は...

qiita.com

初老丸 Advent Calendar 2017 18 日目の記事です.

はじめに

fake-s3 とは...

github.com

Amazon S3API レスポンスをお手軽に返してくれるサーバーで, gem で提供されていますが, 以下のようにコマンドラインからサーバーを起動することが出来るようです.

fakes3 -r /mnt/fakes3_root -p 4567

今回はコンテナで起動する予定なので, コマンドラインからの起動については触れない予定です.

コンテナで立ち上げられると良い(と思っている)

Docker イメージが提供されているので, 以下のようにコンテナを起動することで, お手軽に利用可能です.

docker run --name oreno-s3 -p 4569:4569 -d lphoward/fake-s3

curl でアクセスしてみると, 以下のように出力されました.

$ curl 127.0.0.1:4569
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>123</ID><DisplayName>FakeS3</DisplayName></Owner><Buckets><Bucket><Name>oreno-bucket-1</Name><CreationDate>2017-12-17T05:30:20.000Z</CreationDate></Bucket><Bucket><Name>oreno-bucket-2</Name><CreationDate>2017-12-17T05:30:42.000Z</CreationDate></Bucket><Bucket><Name>oreno-bucket-3</Name><CreationDate>2017-12-17T05:30:53.000Z</CreationDate></Bucket></Buckets></ListAllMyBucketsResult>

ex_aws から利用する

以下のように利用した

ex_aws からだと config/config.ex は以下のように設定することで利用出来ました. ちなみに, fake-s3 の wiki にも Elixir での利用方法が書かれていました.

config :ex_aws,
  s3: [
    scheme: "http://",
    region: "ap-northeast-1",
    access_key_id: "xxxxxxxxxxxxxxxxxxxxx",
    secret_access_key: "xxxxxxxxxxxxxxxxxxxxx",
    host: %{"ap-northeast-1" => "127.0.0.1"},
    port: 4569
  ],
  debug_requests: true

iex から ExAws.S3.listbucket を叩いてみると, 以下のように fake-s3 に作って置いたバケットの一覧を取得することが出来ました.

iex(9)> ExAws.S3.list_buckets |> ExAws.request! |> Map.get(:body) |> Map.get(:buckets) |> Poison.encode!
"[{\"name\":\"oreno-bucket-1\",\"creation_date\":\"2017-12-17T05:30:42.000Z\"},{\"name\":\"oreno-bucket-2\",\"creation_date\":\"2017-12-17T05:30:43.000Z\"},{\"name\":\"oreno-bucket-3\",\"creation_date\":\"2017-12-17T05:30:44.000Z\"}]"

いい感じです.

せっかくなので, ExUnit から利用する

とある関数を作った

defmodule S3Ope do
  def get_bucket_list do
    ExAws.S3.list_buckets
      |> ExAws.request!
      |> Map.get(:body)
      |> Map.get(:buckets)
      |> bucket_list([])
  end

  defp bucket_list([head | tail], names) do
    %{"name": json_name} = head
    added_names = [json_name] ++ names
    bucket_list(tail, added_names)
  end

  defp bucket_list([], names), do: names
end

バケットの一覧をリストで返す関数.

iex で実行すると以下のように出力されるだけです.

iex(1)> S3Ope.get_bucket_list
["oreno-bucket-3", "oreno-bucket-2", "oreno-bucket-1"]

fake-s3 を利用してテスト

以下のようなテストを書きました.

defmodule S3OpeTest do
  use ExUnit.Case

  setup_all do
    ExAws.S3.put_bucket('test-bucket', 'ap-northeast-1') |> ExAws.request!
    :ok
    # これが fake-s3 だと動かない...fake-s3 の delete_bucket がアレ
    on_exit fn ->
      ExAws.S3.delete_bucket('test-bucket') |> ExAws.request!
    end
  end

  test "バケット名が List 型で出力されること." do
    assert S3Ope.get_bucket_list() == ["test-bucket"]
  end
end

テストを実行

いい感じです.

$ mix test --trace

S3OpeTest
  * test バケット名が List 型で出力されること. (107.2ms)


Finished in 0.3 seconds
1 test, 0 failures

Randomized with seed 254576

以上

ちょっと気になる

バケットを削除しようとすると, エラーになるので色々と調べてみると, 以下のように見た目は削除に成功してもバケットリストを取得出来てしまうという状態を確認しています. 引続き調査しようと思っています.

とは言え

fake-s3 を使えば, 実際の S3 にアクセスすること無く, S3 を操作するツールの検証が出来るので一家に一台は入れておいて良いツールだと思います.