LoginSignup
0
0

More than 1 year has passed since last update.

Test Kitchen で複数の suite をテストする場合の注意点

Last updated at Posted at 2021-06-16

業務で詰まっていたので展開します

環境背景

Test Kitchen & Ansible という構成の、サーバ構築自動化テストの仕組みがある。
具体的に言うと、Test Kitchen で仮想サーバ(vagrant)を作成し、
それに対して Ansible を走らせる、という仕組み。

テストは github の CI/CD で走らせていた。

Test Kitchen について

Test Kitchen は、Chef によるサーバ構築などのレシピを
効率よくテストするためのツール。
テスト用の VM 作成、レシピの適用、テスト実施、VM 削除を
一度に実行することができる。
基本、yaml ファイルでテストの定義を記述する。

公式サイト
※書き方次第では Ansible のテストにも使えます

環境構成

※業務に関係する情報であるため、本記事に関連する最低限の内容を記載

  • OS(Linux Distribution): CentOS Linux release 7.7
  • Test Kitchen: version 2.1.0
  • Vagrant: version 2.2.16

やろうとしたこと

以下の様なホストを作り、テストを通そうとした。

  • Instance 名(仮称)
    • ins-centos
    • stg-ins-centos
* .kitchen.yml テスト部分の抜粋
driver:
  name: vagrant
  pre_create_command: <構築前に実行するコマンド>

~中略~

suites:
  - name: ins-centos
    driver:
      vm_hostname: ins-centos.local
    provisioner:
      extra_vars: <vars file 名>
  - name: stg-ins-centos
    driver:
      vm_hostname: stg-ins-centos.local
    provisioner:
      extra_vars: <vars file 名>

起きたエラー

stg-ins-centos のテストは成功するが、
ins-centos のテストで毎回 fail する。

ERROR: Job failed: exit status 1

テストで実行しているコマンドは以下。
bundle exec kitchen test ins

Ansible の部分や、test spec では特にエラーが出ていなかった。

調査

CI/CD のログを確認

CI/CD の実行結果途中に以下の例外が出ていた。

>>>>>> ------Exception-------
>>>>>> Class: Kitchen::UserError
>>>>>> Message: Unknown lifecycle hook target {}
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

Exception 欄に、
Unknown lifecycle hook target {}
という kitchen のエラーが出ている。

エラー内容を確認

早速、このエラーを検索してみると、
github の test-kitchen の issue に同様の問題の記事を発見した。

  • https://github.com/test-kitchen/test-kitchen/issues/1498

どうやら、.kitchen.yml で定義している pre_create_command が原因らしい。
複数の suites(複数インスタンスへのテスト)を同時に実行する場合、
pre_create_command を指定するとエラーになるようだ。

* kitchen.yml の設定(再掲)
driver:
  name: vagrant
  pre_create_command: <構築前に実行するコマンド>
 ◆↑ここが問題の箇所

~中略~

suites:
  - name: ins-centos
    driver:
      vm_hostname: ins-centos.local
    provisioner:
      extra_vars: <vars file 名>
  - name: stg-ins-centos
    driver:
      vm_hostname: stg-ins-centos.local
    provisioner:
      extra_vars: <vars file 名>

ただ、今回の場合、
テストするインスタンス名を個々に指定していたにも関わらず、このエラーが出た。
(インスタンス毎にテストを実施しているので、エラーは出ないはず)

CI/CD のログを再確認

不思議に思ってログを見てみると、以下の記述を発見した。

$ bundle exec kitchen destroy ins
-----> Starting Kitchen (v2.1.0)
-----> Destroying <ins-centos>...
       Finished destroying <ins-centos> (0m0.00s).
-----> Destroying <stg-ins-centos>...  =>指定してないインスタンスがいる
       Finished destroying <stg-ins-centos> (0m0.00s).
-----> Kitchen is finished. (0m2.75s)

最後の destroy コマンドにて、
テストをした ins-centos の destroy だけでなく、
stg-ins-centos の destroy まで走っている。

どうやら、kitchen コマンドで指定するインスタンス名は
REGEX(正規表現)として扱われるようで、
ins が stg-ins-centos にも部分一致していたらしい。

その結果、テストが2台のインスタンスに対して実施され、
前述の pre_create_command を2台に適用しようとしてエラーになっていたようだ。

エラーの原因

エラーの原因は2つ

1. 直接の原因

複数の suites(複数インスタンスへのテスト)を同時に実行する場合、
pre_create_command を指定するとテストがエラーになる。
(kitchen create の時点でエラーになるようだ)

2. 間接的な原因(今回の真因)

今回、Test Kitchen で実行したコマンドは以下の通り。
bundle exec kitchen test ins

意図としては、ins(ins-centos)にだけテストを行う予定だったが、
kitchen コマンドで指定したインスタンス名は部分一致になるので、
このコマンドで実行されるインスタンスは以下の2台になる。

  • ins-centos
  • stg-ins-centos

さらに、本テストには pre_create_command が指定されていたので、
エラー原因1により、テストが失敗していた。

対策

1. インスタンス名が部分一致で被らないようにする(これが多分正解)

  • 例:インスタンス名を prd-ins-centos, stg-ins-centos の様にする
    • vagrant destroy prd-ins
    • vagrant destroy stg-ins

◆同じような名前のホストが多い場合は、接頭辞やホスト番号をちゃんとつける。

2. kitchen コマンドに渡すインスタンス名を正規表現で完全一致にする

  • 例:bundle exec kitchen destroy "^ins-centos$"

◆確実ではあるが、長いインスタンス名を毎回記述するのは面倒でもある

3. kitchen コマンドに渡すインスタンス名は省略しないで指定する(非推奨)

  • 例:bundle exec kitchen destroy ins-centos

◆上記の例の通りに実行しても、stg-ins-centos に後方一致してしまうため、結局解決にならない

教訓

ログの最後の部分にエラーが見つからなくても、
よーく途中経過を見てみると、想定外の挙動をしていることがある。
それをログから読み取ることが大事。
(UNIX の文字色でエラーを判断している場合は見逃しに注意)

今回で言うなら、
vagrant destroy でテスト対象外のホストを削除しようとしていた部分。
自分では kitchen コマンドに1台のインスタンスを指定したはずなのに、実は(正規表現で)2台指定されていた。
※気づくのに2時間かかりました;

番外:Test Kitchen で複数の suite をテストするメリット

本記事の趣旨とは違う為、深掘りはしませんが、
同じような構成の複数ホストに対してテスト行う際は、便利だと思います。

ただ、本記事の不具合の原因でもある、
pre_create_command での事前準備ができない、という欠点もあるため、
個人的には shell などで wrap し、
Test Kitchen を1 suite(ホスト)ずつ叩いた方が良いのではないか、
と思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0