結構長いこと悩まされていたエラーだったのですが、原因がわかりましたので共有します。
CircleCIが安定しない
テストは全て通っているのですが、時々というか結構な頻度で以下のようなエラーが出てCIがコケていました。
/home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/childprocess-1.0.1/lib/childprocess/abstract_process.rb:188:in
assert_started': process not started (ChildProcess::Error) 6: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/common/platform.rb:150:in
block in exit_hook'
5: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/common/service.rb:110:instop' 4: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/common/service.rb:110:in
ensure in stop'
3: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/common/service.rb:163:instop_process' 2: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/common/service.rb:180:in
process_exited?'
1: from /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/childprocess-1.0.1/lib/childprocess/unix/process.rb:31:inexited?' /home/circleci/project_name/vendor/bundle/ruby/2.6.0/gems/childprocess-1.0.1/lib/childprocess/abstract_process.rb:188:in
assert_started': process not started (ChildProcess::Error)
このエラーメッセージ等でググっていたのですが、解決方法が見当たらず…。時々失敗するけれど時々成功するため、ときどき調査しようとしては諦めていました。
他のエラーメッセージに気づく
弊社の他のプロジェクトでも同様の症状が出ており、同僚が調査していたのですが、そのときに見つけたメッセージがこれ。
Text file busy - /home/circleci/.webdrivers/chromedriver
私はエラーメッセージのほうばかりを見ていて気づいてなかったのですが、RSpecが落ちたテストをリトライするところに出ていました。
こちらでググると、Rails 6.0系のissueとPRがヒットしました。
Rails 6系ではデフォルトで並列テストをサポートするという認識ですが、弊社のCIもparallel_testsでテストを回していて、同じ症状のようです。
症状の詳細は、webdriversがchromedriverのアップデートをしようとするが、並列でそれが行われてしまい、片方のプロセスが起動できなかったということです。
そこで、並列テストが実行される前にchromedriverのアップデートをしておけば、この問題は発生しなくなると考えました。(上記のPRもそういうことをやっていますが)
修正方法
並列テストが実行される前にchromedriverを更新するよう.circleci/config.ymlを修正しました。parallel_tests等でテストを起動するとその時点で並列化されているから、その前にやっておきます。
steps:
# 略。ただし、DB作成後でないとrails runnerが失敗するので注意。
- run:
name: Update chromedriver
command: env RAILS_ENV=test bin/rails runner "Webdrivers::Chromedriver.update"
# 略。テストを実行
結果
10回連続で同じテストを実行しましたが、全部成功しました
もし並列テストが不安定だ〜という方はこれを追加してみましょう!