Funtoo Linux インストール講習会本番

まずは、当日の参加者の皆さん、会場を提供してくださったEngineYard様、ありがとうございました。

全員がブートまでは行けた前回に油断した結果、今回は何名かkernelのビルドが終わらないまま終了してしまいました。

前日の素振りでdebian-sourcesのbinaryフラグを付けた場合のビルド時間がやばいことには気付いていて、当日はCPUの割り当て数をなるべく多くしてもらったんですが、それでもマシンスペックによっては数時間コースになってしまい時間内に終わらず…

前回はgentoo-sourcesでカーネルのオプションもある程度整理したものをビルドしてもらっていたんですが、そうするとどうしてもブートしないマシンが出てきたりしてしまうので、今回はFuntoo Linux Installation ドキュメントをなぞることにしようとしたのが失敗といえば失敗ですね。

ただ、その長いビルド時間を利用して補足説明や、普段私達がどんな感じで使っているのかを紹介できたので(今までも軽くはやっていましたが)、今後のFuntooライフに役立ていただければと思います。

VirtualBoxコースを見ていてのメモ

BIOSでCPUの仮想化オプションが無効になっている場合があるので最初に確認してもらう インストールのときはなるべく多くのCPUを割り当ててもらう(コア数の半分くらい) debian-sourcesのbinaryフラグ付きビルドはディスクを大量に食うので20Gくらいは開けておく どうせみんな同じ環境なんだから、kernelのオプションを決めて自前でビルドしたほうがいい(準備の時間…)

もしかしたら次回があるかもしれないし、参加者の皆さんからは「普段の使い続け方についてもっと知りたい」という声もいただいたので、今後ともよろしくお願いします。

Sidekiqを使った非同期処理のテストについて

まとめ

sidekiqを2つのRailsアプリケーションで使ってみて、テストの書き方と残し方について思うところがあったので書いてみます。

特別な事情がなければsidekiq/testingを使うべき(sidekiq/testing/inlineは使わない) 非同期処理そのもののユニットテストはMyWorker.new.performで書けばよい 非同期処理をキックする側のユニットテストはMyWorker.jobs.sizeを検証するだけにする エンドツーエンドテストでは「全ての非同期ジョブを実行する」というようなstepやメソッドを作ってそれを呼ぶ sidekiq/testingとsidekiq/testing/inlineについて

sidekiqのwikiには、テストのための仕組みとしてsidekiq/testingとsidekiq/testing/inlineの2つがあり、**「どちらか選んで使え」**と書いてあります。

それぞれの実装を読んでもらえばわかりますが、

sidekiq/testingはジョブキューをArrayで潰して非同期処理が実行されなくする sidekiq/testing/inlineはワーカーの処理を同期実行する

という動きをします。

ぱっとみsidekiq/testingはユニットテスト、sidekiq/testing/inlineがエンドツーエンドテスト向き、のように見えますが、両方ともsidekiq/testingを使うべきだと私は感じました。

requireしただけで有効になってしまうのでspec_helperで切り分けるのが困難である 同期処理を前提としたテストを書けてしまう(実際に書くかどうかは別として) エンドツーエンドテストでは後述の仕組みを使って、明示的に非同期処理を走らせたほうがテストの意図を表現しやすい テストを書く上では非同期処理の先を気にしなくていい場合の方が圧倒的に多いのに、その全てでperformをstubするのが面倒だし意図が捕みにくい

というところで、sidekiq/testingを使ってどうやってテストを書いていけばよいか紹介します。

非同期処理の処理内容のテスト

非同期処理の処理内容は簡単で、testing-workers-directlyの項にあるように直接performを呼べばよいです。

describe S3UploadWorker do let(:worker) { S3UploadWorker.new } describe '#perfome' do it { expect { worker.perform() }.to change(...) } end end 非同期処理の実行をキックする方のテスト

非同期処理の実行をキックする側は、sidekiq/testingの流儀に従ってジョブキューに処理が入ったことだけを検証するようにしましょう。

例えばImage#uploadがS3UploadWorkerを使ってS3へのアップロードを非同期化していることを検証したい場合は以下のように書けばよいでしょう。

describe Image do let(:image) { Image.new(...) } describe '#upload' do it { expect { image.upload }.to change(S3UploadWorker.jobs, :size).by(1) } end end

これだけだとジョブがいつまでも残ってしまうのでspec_helper等にclean_allを呼ぶコードを入れておきましょう。

config.before(:each) do Sidekiq::Worker.clear_all end エンドツーエンドテスト

では、非同期処理も含めたエンドツーエンドテストはどうすればいいでしょうか。

sidekiqのwikiを読むとdrainというクラスメソッドがあります。これを使います。

Sidekiq::Worker.drainは特定のワーカーのジョブキューに溜っているジョブを全て実行します Sidekiq::Worker.drain_allは全てのワーカーのジョブキューに溜っているジョブを全て実行します

request specsならばこれらを直接、cucumberやturnipであれば以下のようなステップを作って明示的に呼び出すようにします。

step 'バックグランド処理を全て実行する' do Sidekiq::Worker.drain_all end

この方法は、非同期処理の完了を待ち合わせをしたり、適当にsleepを入れたりしなくてもいい上に、テストの意図も表現しやすいのでお勧めです。

おわりに

今回のエントリは、実際にお仕事で別々のテスト戦略を選択したRailsアプリケーションに機能追加や修正をしてみたところ、sidekiq/testing/inlineは安易に選択しないほうがよさそうと思ったのがきっかけです。

sidekiq/testing/inlineを選択した場合は、以下のような問題が起きる可能性を考慮しなければなりません。

非同期処理がいらないところにすべてstubを仕込まないといけない 実行されてもされなくてもいいところでは全て実行されるので、スローテスト問題になりやすい 同期実行される前提でテストが書かれる可能性がある 非同期処理の先も含めてのユニットテストが書かれてしまったりする

「そんなの書かねーよ」と言われればそれまでですが、こういう書き方ができてしまう方法を選択しないほうがよいにこしたことはないと思います。

というわけでみなさん非同期処理のライブラリとしてsidekiqを選択する場合は以下のような方針でテストを書いみるのがよいのではないでしょうか。

特別な事情がなければsidekiq/testingを使うべき(sidekiq/testing/inlineは使わない) 非同期処理そのもののユニットテストはMyWorker.new.performで書けばよい 非同期処理をキックする側のユニットテストはMyWorker.jobs.sizeを検証するだけにする エンドツーエンドテストでは「全てのジョブを実行する」というstepやメソッドを作ってそれを呼ぶ

おわり。

GW後半終了のお知らせ

5/3にはプラレール博へ海浜幕張まで。3時くらいに着いた段階でも入場には10分くらいかかったかな。 中はそれはそれは大変な感じになっていて、とりあえず一周見てから、奥さんはお土産を買いに、私と息子は比較的空いてる広いスペースでひたすらプラレールを眺めていた。

(下の写真は閑散としているエボルタエリアの様子です)

丁度入場口が閉まるくらいの時間になったので、ためしに入口まで戻ったらだいぶ過疎っていたので、それからスタンプラリーを開始して、最後に一番空いているアトラクション(3つの箱の中から車両を一つずつ取って、おなじ車両だったら金メッキの車両がもらえるというビンゴゲーム)を1回やったが、息子に事前情報を与えすぎたため、中を覗きまくるという恥しい感じになってしまった…

「中を見ないで取って」としつこく言っていたら、ピカピカのプラレールが欲しかった奥さんにうるさいと言われたが、子供だからってルールを無視するのはよくないと思うんです!!1

あとは、幕張限定の連結バスにも乗れたので息子はだいぶ満足だったみたい。帰ったらみんな疲れ果ててすぐに寝てしまったのと、翌日(5/4)はだいたい死んでいた。

5/5は子供の日なので息子と外に出て、ヨーカドーの海老の大きさに比例して価格が決まる寿司(もちろんそれだけじゃないが、安い方だと海老が小さい)とオランダ家のケーキを買って帰宅。

そして今日は、たまには外でゆっくりしてこいと言われたので、お言葉に甘えて淡路町のスタバでもくもくしながらこれを買いているのであった。