Rails
Vagrant

Railsコアテスト環境を作る

More than 1 year has passed since last update.

mwedアドベントカレンダー4日目の記事です。


はじめに

railsそのもののテスト環境を自PC(Mac)上に作る手順と、そのときに引っかかったポイントについて書いています。


ざっくりまとめ

中身は長ったらしいので、まとめると…。

VirtualBoxとVagrant、rails-dev-boxで仮想マシン上にrailsのテストが動く環境を作れる。

ハマるポイントとして、


  1. 共有しているホスト側のファイルシステムが大文字小文字を区別しないためのテスト失敗

  2. 共有ディスクへの高負荷による仮想マシンのカーネルパニック

があって、

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


参照

明日は@koheiSGさんの「読書会のはなし」です。