読者です 読者をやめる 読者になる 読者になる

Ansible向けのコードカバレッジツールKirbyを作りました

Ansible

PythonJavaでコードを書く場合、コードカバレッジの測定は、よくやりますよね。最近、Ansibleでもコードカバレッジを測りたくなったのですが、それらしいツールがなかったので、作ってみました。名前はKirbyです。今回はKirbyがどんなツールなのか紹介してみます。

ks888/kirby · GitHub

どんなことができるのか

Kirbyは、AnsibleのPlaybookやRoleに対して、タスクレベルのカバレッジを測定するツールです。

例えば、次のようなPlaybookと、Serverspecのテストがあったとします。Playbookでは2つのタスクを実行しています。Serverspecのテストでは、Playbookの一つ目のタスク(create dir1)に対するテストをしています。

~/src/kirby_demo% cat create_2dirs.yml
---
- hosts: localhost
  gather_facts: no
  tasks:
    - name: create dir1
      file: path=./dir1 state=directory

    - name: create dir2
      file: path=./dir2 state=directory
~/src/kirby_demo% cat spec/localhost/sample_spec.rb 
require 'spec_helper'

describe file('./dir1') do
  it { should be_directory }
end

Kirbyをインストールした状態でAnsibleを動かすと、次のような結果が返ってきます。

~/src/kirby_demo% ansible-playbook create_2dirs.yml -i "localhost," -c local

PLAY [localhost] ************************************************************** 

TASK: [create dir1] *********************************************************** 
changed: [localhost]
tested by: 
- rspec ./spec/localhost/sample_spec.rb:4 # File "./dir1" should be directory

TASK: [create dir2] *********************************************************** 
changed: [localhost]
tested by: 

PLAY RECAP ******************************************************************** 
*** Kirby Results ***
Coverage  : 50% (1 of 2 tasks are tested)
Not tested:
 - create dir2
*** Kirby End *******
localhost                  : ok=2    changed=2    unreachable=0    failed=0   

*** Kirby Results ***の下の行を見ると、カバレッジが50%であることと、テストされていないタスクはcreate dir2であることがわかります。

このように、Kirbyを使うと、AnsibleのPlaybookやRoleがどれぐらいテストされているか、また、テストされていないタスクはどれか、を知ることができます。

インストール手順

(2015/09/22追記:実際にKirbyを動かしてみたいけど、Playbookとテストが手元にないという場合は、Playbookとテストのサンプルを利用したチュートリアルが良いかもです)

Kirbyのダウンロード

Playbookのあるディレクトリで、以下のコマンドを実行します。

mkdir callback_plugins
cd callback_plugins
wget https://raw.githubusercontent.com/ks888/kirby/master/callback_plugins/kirby.py

設定

Playbookのあるディレクトリで、kirby.cfgというファイルを作成し、以下の内容を書き込みます。

[defaults]
enable = yes

serverspec_dir = ./
serverspec_cmd = bundle exec rake spec

serverspec_cmdは、Serverspecを走らせるためのコマンド、serverspec_dirは、そのコマンドを実行するディレクトリを指定します。環境に応じて変更して下さい。

使い方

実行

いつもどおりansible-playbookコマンドを動かします。できればAnsibleのターゲットとなるホストはクリーンな状態(まだ一度もAnsibleをかけていない状態)の方が、うまくカバレッジを出せます。

実行結果の確認

例えば以下のような結果が得られたとします。

~/src/kirby_demo% ansible-playbook create_2dirs.yml -i "localhost," -c local

PLAY [localhost] ************************************************************** 

TASK: [create dir1] *********************************************************** 
changed: [localhost]
tested by: 
- rspec ./spec/localhost/sample_spec.rb:4 # File "./dir1" should be directory

TASK: [create dir2] *********************************************************** 
changed: [localhost]
tested by: 

PLAY RECAP ******************************************************************** 
*** Kirby Results ***
Coverage  : 50% (1 of 2 tasks are tested)
Not tested:
 - create dir2
*** Kirby End *******
localhost                  : ok=2    changed=2    unreachable=0    failed=0   
  • タスクが実行されるたびに、tested byという行が表示されます。

    • もしtested byの次の行が空だった場合、タスクはテストされていません(create dir2がこれに該当します)。
    • 空ではない場合、タスクはテストされています(create dir1がこれに該当します)。
    • tested byという行が表示されていない場合、Kirbyはそのタスクをカバレッジから外しています。タスクがホストの状態を変更しなかった場合(タスクの結果がchangedではなかった場合)に、これが当てはまります。
  • Playbookの実行後に、カバレッジとテストされていないタスクの一覧が表示されます。

カバレッジの改善

基本的には、テストされていないタスクのテストを書くことでカバレッジを改善します。

ただ、例えば以下のようなタスクについては、テストがいらないかもしれません。

  • commandモジュールからlsコマンドを呼ぶ場合(ホストの状態を変更していないため)
  • パッケージをインストールするための準備作業として、パッケージをダウンロードする場合(インストール成否のテストで十分そうなため)

そのような場合には、以下の方法でタスクをカバレッジの対象から外すことができます。

  • changed_whenをつかう

    Kirbyはホストの状態を変更しないタスク(実行結果がchangedでないタスク)はカバレッジに含めません。もしchangedなタスクが実際にはターゲットのホストを変更していない場合、Ansibleのchanged_whenが使えます。例えば以下のように書くと、タスクの実行結果がchangedではなくなります。

- command: ls
  changed_when: False
  • coverage_skipをつかう

    Kirbyはcoverage_skipというキーワードがタスクの名前に含まれている場合、そのタスクをカバレッジに含めません。例えば以下のように書くと、タスクはカバレッジの対象外になります。

- name: create dir2 [coverage_skip]
  file: path=./dir2 state=directory

まとめ

Ansible向けのコードカバレッジツールKirbyを紹介しました。これから色々改善しようと思っているので、感想やご意見があれば、GitHubTwitterを通して教えていただけると嬉しいです。よろしくお願いします。

(2015/09/22追記:Kirbyをちょっと試してみたいという方向けに、チュートリアルを作成しました。よろしければそちらもご参照下さい)