OSSのサーバテスト自動化ツール徹底検証 2016年版 〜Infrataster編――手間取るテストエビデンス作成をどう自動化するか〜実際に検証済み!OSS徹底比較(6)サーバテスト自動化【後編】(3/6 ページ)

» 2016年09月29日 05時00分 公開
[森元敏雄,TIS]

テストスクリプトの作成

1.テスト対象ホストの情報を登録

 spec_helper.rbにテスト対象のホストの情報を登録する。登録する情報は以下の通り。

  • ホスト名/IPアドレス
  • Vagrant上のサーバか?
  • ssh接続のホスト名、ユーザーID、パスワードor認証用の秘密鍵ファイル
  • mariadb(mysql)への接続情報

 さらに、テストスクリプトに記載された順番通りにテストが実施されるように記載する。

$ vi ~/infrataster/spec/spec_helper.rb
 Generated by `infrataster init`
require 'infrataster/rspec'
ENV['VAGRANT_CWD'] = File.dirname(__FILE__)
Infrataster::Server.define(
  :tissvv096,
  '10.255.202.96',
  vagrant: false,
  ssh: {host_name: 'tissvv096', user: 'maintain', keys: ['/home/maintain/.ssh/id_rsa.pem']},
  mysql: {user: 'maintain', password: 'HB-F1XDJ'},
)
Infrataster::Server.define(
  :tissvv097,
  '10.255.202.97',
  vagrant: false,
  ssh: {host_name: 'tissvv097', user: 'maintain', keys: ['/home/maintain/.ssh/id_rsa.pem']},
)
RSpec.configure do |config|
  treat_symbols_as_metadata_keys_with_true_values = false
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
#  config.order = 'random'
  config.order = 'define'
end

2.対話的コンソールを有効にする

 作成したテストスクリプトは以下となる。各処理のTIPSは後ほど、機能ごとに説明する。

$ vi infrataster/spec/tissvv096_spec.rb
# Generated by `infrataster init`
require 'spec_helper'
require 'infrataster-plugin-mysql'
require 'infrataster-plugin-firewall'
describe server(:tissvv096) do
  mysql_root_pass='FM11AD2+'
  wp_dir='/var/www/wordpress'
  wp_os_user='root'
  wp_os_group='root'
  wp_db_name='WordPress'
  wp_db_user='wp_admin'
  wp_db_pass='HB-F1XDJ'
  wp_uniqe_phrse='FX702PFX801PPB100FX860PPB700PB500PB750PAI1000'
  wp_version='4.5.2'
  hostname='tissvv096'
  # yum update check
  it 'yum update check' do
    result = current_server.ssh_exec('yum check-update 2>&1 > /dev/null; echo $?')
    expect(result.chomp).to eq('0')
  end
  # mariadb-server/httpd/php/php-mysql insall check
  %w{ mariadb-server httpd php php-mysql }.each do |pkg|
    it "#{pkg} install check" do
      result = current_server.ssh_exec("rpm -qa | grep -e '#{pkg}-[0-9]'")
      expect(result.chomp).to match /#{pkg}/
    end
  end
  # mariadb service running/enable check
  it 'mariadb service running/enable check' do
    result = current_server.ssh_exec('systemctl status mariadb')
    expect(result).to match /service; enabled/
    expect(result).to match /active \(running\)/
  end
  # mariadb remote login check
  describe mysql_query('show databases') do
    it 'mariadb remote login check' do
      row = results.find {|r| r['Database'] == 'mysql' }
      expect(row['Database']).to eq('mysql')
    end
  end
  # mariadb root login check
  it 'mariadb root login check' do
    result = current_server.ssh_exec("mysqlshow -u root -p#{mysql_root_pass}")
    expect(result.chomp).to match /Database/
  end
  # mariadb root no password login check
  it 'mariadb root no password login check' do
    result = current_server.ssh_exec('su root -c mysqlshow')
    expect(result.chomp).to match /Database/
  end
  # mysqladmin ping execute check
  it 'mysqladmin ping execute check' do
    result = current_server.ssh_exec('su root -c "mysqladmin ping"')
    expect(result.chomp).to match /mysqld is alive/
  end
  # mariadb logrotation check
  before :all do
    @already_rotate = current_server.ssh_exec('su root -c "ls -1 /var/log/mariadb/*.gz | wc -l"').to_i
  end
  it 'mariadb logrotation check' do
    if @already_rotate == 0 then
      check_cmd = '/sbin/logrotate -vf /etc/logrotate.d/mariadb'
      match_prm = 'running postrotate script'
    else
      check_cmd = '/sbin/logrotate -vd /etc/logrotate.d/mariadb'
      match_prm = 'log does not need rotating'
    end
    result = current_server.ssh_exec("su root -c \"#{check_cmd}\"")
    expect(result).to match /#{match_prm}/
  end
 after :all do
    @already_rotate = nil
  end
  # WordPress version check
  describe http("http://#{hostname}/readme.html") do
    it 'WordPress Version check' do
      expect(response.body).to match /Version #{wp_version}/
    end
  end
  # mariadb WordPress user login check
  it 'mariadb WordPress user login check' do
    result = current_server.ssh_exec("mysqlshow -u #{wp_db_user} -p#{wp_db_pass} #{wp_db_name}")
    expect(result.chomp).to match /#{wp_db_name}/
  end
  # WordPress file user/group check
  it 'WordPress file user/group check' do
    result = current_server.ssh_exec("find #{wp_dir} -not -user #{wp_os_user} -or -not -group #{wp_os_group} | wc -l")
    expect(result.chomp).to eq('0')
  end
  # wp-config.php paramaters check
  it 'wp-config.php paramaters check' do
    result = current_server.ssh_exec("cat #{wp_dir}/wp-config.php")
    expect(result).to match /define\('DB_NAME',.*'#{wp_db_name}'\);/
    expect(result).to match /define\('DB_USER',.*'#{wp_db_user}'\);/
    expect(result).to match /define\('DB_PASSWORD',.*'#{wp_db_pass}'\);/
    expect(result).to match /define\('AUTH_KEY',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('SECURE_AUTH_KEY',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('LOGGED_IN_KEY',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('NONCE_KEY',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('AUTH_SALT',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('SECURE_AUTH_SALT',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('LOGGED_IN_SALT',.*'#{wp_uniqe_phrse}'\);/
    expect(result).to match /define\('NONCE_SALT',.*'#{wp_uniqe_phrse}'\);/
  end
  # wordpress.conf check
  it 'wordpress.conf check' do
wordpress_conf = <<"EOT"
<VirtualHost *:80>
  ServerName #{hostname}
  DocumentRoot #{wp_dir}
  <Directory "#{wp_dir}">
    AllowOverride All
    Options -Indexes
  </Directory>
  <Files wp-config.php>
    order allow,deny
    deny from all
  </Files>
</VirtualHost>
EOT
    result = current_server.ssh_exec("cat /etc/httpd/conf.d/wordpress.conf")
    expect(result).to match "#{wordpress_conf}"
  end
  # httpd.conf ServerName check
  it 'httpd.conf ServerName check' do
    result = current_server.ssh_exec('cat /etc/httpd/conf/httpd.conf')
    expect(result).to match /ServerName #{hostname}/
  end
  # httpd service running/enable check
  it 'httpd service running/enable check' do
    result = current_server.ssh_exec('systemctl status httpd')
    expect(result).to match /active \(running\)/
    expect(result).to match /service; enabled/
  end
  # WordPress site access check
  describe http("http://#{hostname}/wp-admin/install.php") do
    it 'WordPress site access check' do
      expect(response.body).to match /WordPress/
    end
  end
  # firewall http/ssh/mysql port open check
  it 'firewall http/ssh/mysql port open check' do
   result = current_server.ssh_exec('firewall-cmd --list-all --zone=public')
    expect(result).to match /services:.*http/
    expect(result).to match /services:.*ssh/
    expect(result).to match /services:.*mysql/
    expect(result).to match /ports: $/
  end
end
describe server(:tissvv097) do
  # firewall open port check
  describe firewall(server(:tissvv096)) do
    it { is_expected.to be_reachable }
    it { is_expected.to be_reachable.dest_port(80).ack(:only) }
  end
end

テストスクリプトの実行

1.テストスクリプトの実行

 以下のコマンドでInfratasterのテストスクリプトが実行される。結果は標準出力に出力されるため、teeコマンドを利用し、ファイルにも保存している。パラメータに実行するテストスクリプトファイルを指定した場合、そのファイルのみのテストが実行される。指定がない場合、specフォルダ以下の全テストスクリプトファイル(*_spec.rb)が順次実行される。

$ /usr/local/bin/rspec -f d spec/tissvv096_spec.rb | tee tissvv096_test.log

 '-f'オプションはログ出力の形式を定義している。使用できるオプションはrspec --helpで表示される。

-f, --format FORMATTER  Choose a formatter.
                        [p]rogress (default - dots)
                        [d]ocumentation (group and example names)
                        [h]tml
                        [j]son
                        custom formatter class name

 今回はエビデンスとして利用するため、'-f d'を使用している。

2.ログ出力

 テストスクリプトの実行により、以下の結果が出力される。

Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
server 'tissvv096'
  yum update check
  mariadb-server install check
  httpd install check
  php install check
  php-mysql install check
  mariadb service running/enable check
  mariadb root no password login check
  mysqladmin ping execute check
  mariadb logrotation check
  mariadb WordPress user login check
  WordPress file user/group check
  wp-config.php paramaters check
  wordpress.conf check
  httpd.conf ServerName check
  httpd service running/enable check
  firewall http/ssh/mysql port open check
  mysql 'show databases' with []
    mariadb root login check
  http 'http://tissvv096/readme.html' with {:params=>{}, :method=>:get, :headers=>{}}
    WordPress Version check
  http 'http://tissvv096/wp-admin/install.php' with {:params=>{}, :method=>:get, :headers=>{}}
    WordPress site access check
server 'tissvv097'
  via firewall
    should reach to server 'tissvv096'
    should reach to server 'tissvv096' dest_port: 80 (FAILED - 1)
Failures:
  1) server 'tissvv097' via firewall should reach to server 'tissvv096' dest_port: 80
     Failure/Error: it { is_expected.to be_reachable.dest_port(80).ack(:only) }
       expected to reach to server 'tissvv096' dest_port: 80, but did not.
     # ./spec/tissvv096_w_fw_spec.rb:168:in `block (3 levels) in <top (required)>'
Finished in 3.48 seconds (files took 0.43954 seconds to load)
21 examples, 1 failure
Failed examples:
rspec ./spec/tissvv096_w_fw_spec.rb:168 # server 'tissvv097' via firewall should reach to server 'tissvv096' dest_port: 80

 テスト自体は4秒弱で完了している。1件のテスト項目がエラーとなっているが、原因は次ページのTIPSで別途解説する。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。