c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Testable readonly ETS. Mnemonics.ExMachina v0.1.0 ヾ(〃l _ l)ノ゙

  • 讀み取り専用
  • on-memory で高速
  • 再起動せずに新しい ver.の data へ入れ替へられる
  • 古い ver.で處理してゐた計算はそのまま古い ver.を讀み出し續けられる
  • heap 領域に cache できる。讀み出した data を snapshot として system 外に持ち運べる
  • parallel

これらを滿たしたMnemonicsと云ふ Elixir の library を以前に作った。無停止 upgrade 出來るActiveHashの樣なものだ。

Mnemonics を使った code を test しやうとする。test で使ふ data は、實働環境から独立である必要が在る、即ち test で使ふ data はは test 内に書かれてあるのが好い。又 test で使ふ data は、他の test からも独立である必要が在る、即ち或る test が書き換へた data が他の test に影響しないのが好い。PostgreSQL 等の DB を使った code を test するには 2 つの方法が在る。ひとつには DB と遣り取りする函數を mock して了ふ。もうひとつは test 毎に一意な data を DB に書き込む。test 毎に一意であればその data は他のどこからも讀み出せない。RDB であれば通常は、一意な primary key を test の外で生成して 與へ、與へられた key の data 以外には手を触れないと取り決めてやる。所謂 test factory だ。Rails/ActiveRecord だとFactoryBotが有名だ。Elixir/Ecto だとExMachinaが有名である。例へばこう使ふ。

defmodule Factory do
  use ExMachina.Ecto

  def user_factory do
    id = sequence("")
    %User{id: String.to_integer(id), name: "user" <> id}
  end
end

defmodule UserTest do
  import Factory

  use ExUnit.Case

  test "authorized?" do
    user = insert(:user)
    assert User.authorized?(user)
  end
end

some_factoryと云ふ函數を定義してやりuse ExMachina.Ectoとしてやると、build(:some)insert(:some)と云ふ函數が使へる樣に成る。

さて Mnemonics ではこれが出來ない。test 毎に一意な data を生成してやるのだが、readonly なので環境に書き込めない。

出來なかった。mock する手も在っただらうとは思ふものの、ETS をまるごと mock するのはダルいので、Mnemonics 側に書き込み出來る穴を空けてやった。この穴は table 毎に 1 つの GenServer であり parallel ではないので本番では使ってはならないが、test で使ふには充分速い。

Mnemonics.ExMachina

github.com

こう使ふ。

defmodule Factory do
  use Mnemonics.ExMachina

  def item_factory do
    id = sequence("")
    %Item{id: String.to_integer(id), name: "user" <> id}
  end
end

defmodule UserTest do
  import Factory

  use ExUnit.Case

  test "drop?" do
    user = insert(:item)
    assert Item.drop?(item)
  end
end

use ExMachina.Ectouse Mnemonics.ExMachinaに變はっただけ。一つの factory に兩方を use する事は出來ないので、併用する時は 2 つ factory を作ってやり、尚且つ import せず full qualified に module 名附きで呼んでやれば好い。

ヾ(〃l _ l)ノ゙