この記事は...
初老丸 Advent Calendar 2017 18 日目の記事です.
はじめに
fake-s3 とは...
Amazon S3 の API レスポンスをお手軽に返してくれるサーバーで, 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 を操作するツールの検証が出来るので一家に一台は入れておいて良いツールだと思います.