Storehouse.Memory (Storehouse v0.2.0)

Copy Markdown View Source

A Storehouse.Adapter that keeps files in memory, for tests: every callback, the optional ones too, with no disk, no bucket and no container, and each test's files its own, as Ecto's sandbox keeps each test's rows.

# test/test_helper.exs
{:ok, _pid} = Storehouse.Memory.start_link()
ExUnit.start()

# config/test.exs
config :storehouse, adapter: Storehouse.Memory

# in a test, or a case template's setup
setup do
  Storehouse.Memory.checkout()
end

Whose files

A process that has called checkout/0 owns the files it stores, and sees only those: two tests run with async: true never see each other's files, even under the same key. The processes it starts with Task see them too (they carry it in $callers), and any other process once allow/2 lets it. A file a process stores before any checkout goes to a space every such process shares. An owner's files go when it exits.

Uploads straight to the store

presign_upload/3 gives an upload whose URL no server takes: in a test, make the browser's part of it with put_upload/2, which takes the bytes as the store would, of the signed type and size only.

Failures

fail_next/2 makes the next call of a callback give an error, for the tests of an app's error paths:

Storehouse.Memory.fail_next(:delete, :unavailable)
assert {:error, :unavailable} = Storehouse.delete(key)

See Storehouse.Test for assertions on what was stored.

Summary

Functions

Lets pid see and store the files of owner (a process that checked out).

Makes the calling process the owner of the files it stores from now on, and of no others. Its files go when it exits. Gives :ok, for a setup block.

The next call of callback (:put, :delete, :read_range, …) by the calling process's owner gives {:error, reason}, or raises for the callbacks that do not return errors (url/1).

The file stored under key: its :body, its :content_type and its :modified_at, or nil.

The keys of the files the calling process's owner has, in order.

The browser's part of an upload presign_upload/3 signed: stores body under its key when it is of the signed size, and gives the status a bucket would (200, or 403 for another size, other bytes than the checksum signed, or an upload that expired).

Starts the store (its tables), once, in test_helper.exs.

Functions

allow(owner, pid)

@spec allow(pid(), pid()) :: :ok

Lets pid see and store the files of owner (a process that checked out).

checkout()

@spec checkout() :: :ok

Makes the calling process the owner of the files it stores from now on, and of no others. Its files go when it exits. Gives :ok, for a setup block.

fail_next(callback, reason)

@spec fail_next(atom(), term()) :: :ok

The next call of callback (:put, :delete, :read_range, …) by the calling process's owner gives {:error, reason}, or raises for the callbacks that do not return errors (url/1).

get(key)

@spec get(Storehouse.Adapter.key()) :: map() | nil

The file stored under key: its :body, its :content_type and its :modified_at, or nil.

keys()

@spec keys() :: [Storehouse.Adapter.key()]

The keys of the files the calling process's owner has, in order.

put_upload(map, body)

@spec put_upload(Storehouse.Adapter.upload(), binary()) :: 200 | 403

The browser's part of an upload presign_upload/3 signed: stores body under its key when it is of the signed size, and gives the status a bucket would (200, or 403 for another size, other bytes than the checksum signed, or an upload that expired).

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the store (its tables), once, in test_helper.exs.