mwedアドベントカレンダー4日目の記事です。
はじめに
railsそのもののテスト環境を自PC(Mac)上に作る手順と、そのときに引っかかったポイントについて書いています。
ざっくりまとめ
中身は長ったらしいので、まとめると…。
VirtualBoxとVagrant、rails-dev-boxで仮想マシン上にrailsのテストが動く環境を作れる。
ハマるポイントとして、
- 共有しているホスト側のファイルシステムが大文字小文字を区別しないためのテスト失敗
- 共有ディスクへの高負荷による仮想マシンのカーネルパニック
があって、
1と2の問題を解決するために共有フォルダをrsyncにするのがポイントでした。
残っている課題
まだテストが全部グリーンになっていません…。
原因がわかったら、rails-dev-boxやrailsにプルリクを出そうと思います。
(追記)
@yahonda@github さんがこの記事を拾ってくれて、おなじように再現したということで、railsのissueを作り調査を進めてくれて、@y_yagi さんが修正してくれました。
ということで、今日時点ではこのrails-dev-boxでrailsのmasterのテストが通っています。
本文
Railsコア開発環境の構築
rails-dev-boxのREADMEのとおりにやっていきます。
事前準備
VirtualBoxとVagrantをインストールします。
VirtualBoxはx86仮想マシンを管理するソフトウェア。
Vagrantは仮想開発環境の構築ソフトウェア。
この2つを使って、rails-dev-boxはRailsコア開発環境を作ろうというわけです。
VirtualBox
$ brew cask install virtualbox
自分はすでにインストール済みだったので、reinstall
で最新版にしました。
Vagrant
$ brew cask install vagrant
brew install vagrant
とすると古いバージョンが入るので気をつけてください。
仮想マシン構築
rails-dev-boxはVagrantの仕組みを使って、
Ubuntuの仮想マシンイメージから仮想マシンを準備、必要なパッケージをインストールしています。
$ git clone https://github.com/rails/rails-dev-box.git
$ cd rails-dev-box
$ vagrant up
このあとvagrant ssh
すれば仮想マシンにログインできます。
自分は古いvagrantで最初やったので↓のようなエラーが出てできませんでした。
新しいvagrantを入れて、.vagrant
以下を削除してやり直しました。
The provider 'VirtualBox' could not be found, but was requested to
back the machine 'default'. Please use a provider that exists.
Rails開発環境構築
rails-dev-boxのディレクトリは仮想マシンの/vagrant
に共有ディスクとしてマウントされているので、
このディレクトリ内にrailsのリポジトリをクローンして、仮想マシン内で利用します。
$ git clone git@github.com:rails/rails.git
仮想マシンにログイン、railsのディレクトリでbundle
$ vagrant ssh
ubuntu@rails-dev-box:~$ cd /vagrant/rails
ubuntu@rails-dev-box:/vagrant/rails$ bundle
テスト実行
railsのディレクトリでbundle exec rake test
とすればテストができるのですが、たくさんのテストがあって時間がとてもかかることと、結果になにかあっても見過ごしてしまいそうなので、コンポーネントごとに実行すると少し見やすくなります。
$ cd actioncable
$ bundle exec rake test
このようにしてひとつずつテストを実行していくと…
-
actionview
のテストでファイル名の大文字小文字が違うためにmissing templateになるというテストでしたが、OS Xのデフォルトではファイル名の大文字小文字を区別しないためでテストが失敗していました -
railties
のテストでは仮想マシンがカーネルパニックを起こしました。おそらくvagrantの共有ディスクへのアクセスの負荷が高すぎたためだと思われます。
rsync
vagrantのファイル共有の方法にはいくつかありますが、それらのうちのrsyncで同期することにしました。
rsyncはホストPCのファイルシステムをそのまま共有せずに、ファイルのコピーによって同期するので、
仮想マシンではlinuxのext4が使われるのでファイル名の大文字小文字問題は解決されるし、
テスト実行時にrsyncをさせないでおけば、負荷が高くならないだろうという理由です。
Vagrantfileを下記のように修正します。
$ cat Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure('2') do |config|
# FIXME: When upgrading to a future version of Ubuntu check if the workaround
:
:
v.cpus = ENV.fetch('RAILS_DEV_BOX_CPUS', 2).to_i
end
config.vm.synced_folder '.', '/vagrant', type: 'rsync' # <- 共有方法にrsyncを指定
end$
Vagrantfileを修正した後に、vagrant rsync
とすれば同期されます。
ファイルの編集を頻繁にするときには vagrant rsync-auto
がわすれなくてよさそうです。
もう一度テスト実行
$ for f in actioncable actionmailer actionpack actionview activejob activemodel activerecord activestorage activesupport; do echo "+++++ $f +++++"; cd $f; time bundle exec rake test; echo "----- press enter -----"; read dmy; done
actionviewのテストは落ちなくなり、railstieのテストではカーネルパニックしなくなりました。
できていないかったこと
(追記) 今はテストがパスするようになっています。
現状で、railstieのtest/application/server_test.rb
でエラーが出ていて、中身を見ているところです。
rails-dev-boxかrailsへのプルリクチャンスだと思って調べているところです…。
/usr/bin/ruby2.4 -w -Itest -Ilib -I../activesupport/lib -I../actionpack/lib -I../actionview/lib -I../activemodel/lib test/application/server_test.rb
Run options: --seed 21299
# Running:
.F
Failure:
ApplicationTests::ServerTest#test_restart_rails_server_with_custom_pid_file_path [test/application/server_test.rb:48]:
"Inherited" expected, but got:
...
/usr/local/lib/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- rails/all (LoadError)
from /usr/local/lib/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:59:in `require'
from /tmp/d20171127-27190-zh42ve/app/config/boot.rb:1:in `<top (required)>'
from bin/rails:3:in `require_relative'
from bin/rails:3:in `<main>'
.
Expected "...\r\n/usr/local/lib/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:59:in `require': cannot load such file -- rails/all (LoadError)\r\n\tfrom /usr/local/lib/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:59:in `require'\r\n\tfrom /tmp/d20171127-27190-zh42ve/app/config/boot.rb:1:in `<top (required)>'\r\n\tfrom bin/rails:3:in `require_relative'\r\n\tfrom bin/rails:3:in `<main>'\r\n" to include "Inherited".
bin/rails test test/application/server_test.rb:35
Finished in 13.999023s, 0.1429 runs/s, 0.5715 assertions/s.
2 runs, 8 assertions, 1 failures, 0 errors, 0 skips
参照
- Railsコア開発環境の構築方法
- rails-dev-box
-
test_restart_rails_server_with_custom_pid_file_path fails
-Ensure to use repo's Gemfile in application
明日は@koheiSGさんの「読書会のはなし」です。