Assurer のプロジェクトサイト立ち上げました

Posted by Gosuke Miyashita Wed, 17 Jan 2007 16:19:51 GMT

irc#assurer@freenode での会話が盛り上がったので、勢いで ドメインを取得して、独立した trac と svn repos を立ち上げてみました。(最低限の体裁だけ。しかも plagger.org からコピペ。)

id:tokuhirom さんからの contribute で、テストプラグインも増えてます。また、信頼のおける Yappo さんから、Publish::File プラグインを提供してもらいました。感謝感謝。

IRC での会話の流れで、テストだけではなく監視もカバーする、という方向性で行くことになりました。会話の断片はこちらで参照できます。

なんか略称がヒドイことになってます…(その略称に OK を出したのは自分ですが…)

Assurer - サーバテスティングフレームワーク #4

Posted by Gosuke Miyashita Tue, 16 Jan 2007 15:10:40 GMT

Assurer (SVN) を修正。テストのターゲットとなるホストを、以下の3つのパターンのいずれかで指定できるようにしてみました。

config.yaml 中のテストプラグイン設定で直接指定

test:
  - module: HTTP
    config:
      host: svn.mizzy.org
      content: It works!

一番オーソドックスなパターンですね。

コマンドラインオプションで指定

test:
  - module: HTTP
    config:
      content: It works!

といった感じで config.yaml には host を書かずに、

$ ./assurer.pl --config=configy.yaml --host=svn.mizzy.org

とコマンド実行時に指定。同じテストを複数のホストに対して実行する場合、いちいち config.yaml を書き換えるよりも、こっちの方が楽ですね。

config.yaml でターゲットホストをリストで指定

test:
  - module: HTTP
    config:
      content: It works!

hosts:
  - svn.mizzy.org
  - trac.mizzy.org

2番目のパターンと同じ用に、テストプラグインの設定には host を記述しませんが、別なところにターゲットホストをリストアップしておきます。複数のホストに対して一気に実行するのであれば、この方法が楽ですね。

これの変形で、

test:
  - module: HTTP
    role: web
    config:
      contnet: It works!

  - module: MySQL
    role: mysql

hosts:
  web:
    - svn.mizzy.org
    - trac.mizzy.org
  mysql:
    - mysql.mizzy.org

といった感じで設定すると、HTTP のテストは svn.mizzy.org と trac.mizzy.org に、MySQL のテストは mysql.mizzy.org に対して実行される、という動作になります。(MySQL テスト用プラグインはまだ存在しませんが。)

複数の役割の異なるホストに対してテストを実行するには、このパターンで。

最後のやつは Archer からのインスパイヤです。

Assurer - サーバテスティングフレームワーク #3

Posted by Gosuke Miyashita Sun, 14 Jan 2007 07:04:11 GMT

Assurer (SVN) を修正。主な修正点は以下の通りです。

  • テスト結果を保持する Assurer::Results クラスを削除。代わりに Test::TAP::Model を使うようにした。
  • Format, Publish まわりを実装し、Format::Text, Format::HTML, Publish::Term を実装。
  • Assurer::Test でテスト結果をターミナルに表示していたのを、Publish::Term に分離。
format:
  - module: HTML
    config:
      css_uri: htmlmatrix.css

publish:
  - module: Term

といった設定をして、

$ ./assurer.pl -c examples/config.yaml > tap.html

と実行すると、こんな感じの HTML が得られます。

これで大枠はだいぶ整ってきた気がする。

Net::LDAPx::Simple と Catalyst::Model::LDAPx::Simple

Posted by Gosuke Miyashita Fri, 12 Jan 2007 14:31:57 GMT

Net::LDAP::Alterntive あらため Net::LDAP::Abstract ですが、この名前だと Net::LDAP の中のモジュールと区別がつかないし、パッと見何をやるモジュールなのか分からないので、Net::LDAPx::Simple (SVN) とまた名称を変更しました。DBIx::Simple からの連想です。 以下の様な感じで CRUD が一通りできるようになってます。

# Create
my $res = $ldap->create({
    dn => 'uid=mizzy, ou=people, o=southpark',
    objectclass => [ 'person', 'inetorgperson' ],
    sn => 'Miyashita',
    cn => 'Gosuke Miyashita',
    uid => 'mizzy',
});

# Retrieve
my $entries = $ldap->search({
    -or => {
        uid => 'miya',
        cn  => 'miyashita*',
        },
    }
});

# Update
my $entry = $entries->first;
$entry->telephonenumber('00-0000-0000');
$entry->update;

# Delete
$entry->delete;

ついでに Catalyst::Model::LDAPx::Simple (SVN) もつくりました。Catalyst::Model::* つくるのはじめてなので、こんな感じでいいのかちょっと不安。もう少し他の Catalyst::Model::* のソースを読んでみる。

もうちょいエラーハンドリングちゃんとして、POD 書いたり Helper つくったりした後に CPAN に up 予定。

Assurer - サーバテスティングフレームワーク #2

Posted by Gosuke Miyashita Sun, 07 Jan 2007 16:19:00 GMT

Assurer (SVN) をまた修正。

プラグインの実行フェーズを、test, format, publish の3つにわけてみました。

test:
  - module: HTTP
    name: http://svn.mizzy.org/ #0
    config:
      url: http://svn.mizzy.org/
      match: It works!

format:
  - module: HTML

publish:
  - module: Mail

こんな感じで config.yaml を書くと、テスト結果を HTML でフォーマットしてメールで飛ばす、みないな動作になることを意図しています。(まだ Format::HTML や Publish::Mail はつくってないですが。)

format:
  - module: Text

publish:
  - module: File

とかやると、テキスト形式でファイルに吐き出すとか、そんな感じで。

単にターミナルに結果を表示するだけであれば、format と publish は必要ないです。

これにともなって、プラグインのネームスペースも、Plugin::Test::*, Plugin::Format::*, Plugin::Publish::* の3つに分割しています。

また、Assurer::Results というクラスも新たに追加しました。Plugin::Test::* によるテスト結果を保持しておいて、Plugin::Format::* に渡すためのクラスです。

こんな感じで遅々としてますが、少しづつ前進しています。

Assurer - サーバテスティングフレームワーク #1

Posted by Gosuke Miyashita Sat, 06 Jan 2007 12:22:47 GMT

typester さん が del.icio.us で「開発参加したい!」とおっしゃってくださったので、#assurer@freenode チャネルつくりました。まだおおまかな仕様すら固まっていない段階なので、いろいろご助言頂けると大変うれしいです。ご興味のある方はぜひ!

で、本題。Assurer (SVN) をちょっと修正しました。修正点は以下の通りです。

  • assurer.pl に Plagger の文字が残っていたので、修正しました。(はてブでコメント頂きました。ありがとうございます。)
  • Assurer::Test というクラスをつくりました。Assurer::Plugin::HTTP では最初、Test::More を使っていたのですが、代わりにこちらを使うようにしてます。
  • 他微修正。

今回追加した Assurer::Test というクラスは Test::Builder を利用していて、 Test::More の代わりとしてテスト用プラグインから利用することを想定しています。

なぜわざわざこのクラスを作ったかというと、テスト結果出力を色分けしたかったからです。実行するとこんな感じの出力になります。(RSS リーダだと色が見えないと思いますが…)

$ ./assurer.pl -c examples/config.yaml
[info] Testing http://svn.mizzy.org/ #0
ok 1 - Content of http://svn.mizzy.org/ matches 'It works!'
[info] Testing http://svn.mizzy.org/ #1
not ok 2 - Content of http://svn.mizzy.org/ matches 'It not works!'
#                   '<html><body><h1>It works!</h1></body></html>'
#     doesn't match '(?-xism:It not works!)'

また、

global:
  config:
    no_diag: 1

といった設定をすると、以下のように diag message を表示しなくなります。

$ ./assurer.pl -c examples/config.yaml
[info] Testing http://svn.mizzy.org/ #0
ok 1 - Content of http://svn.mizzy.org/ matches 'It works!'
[info] Testing http://svn.mizzy.org/ #1
not ok 2 - Content of http://svn.mizzy.org/ matches 'It not works!'

Assurer::Test は今後、 Assurer::Test::More とか Assurer::Test::Class といった感じでベースとなる Test::* に応じて細分化するかもしれません。

Assurer - サーバテスティングフレームワーク #0

Posted by Gosuke Miyashita Fri, 05 Jan 2007 15:44:44 GMT

構築したサーバがちゃんと動作するかどうかのテストを自動化したいなー、とスクリプトを書こうと思ったのですが、Perler としてはここはやはり、Plagger とか Archer みたく、プラガブルで YAML で設定書けば OK みたいのを作るべきだろう、ってことで、Assurer (SVN) というサーバテスティングフレームワークをでっちあげてみました。

テストのことを Quality Assurance とか言ったりするし、Plagger や Archer が er で終わってるので、それに倣って命名してます。

今のところ Plagger や Archer からコピペして、ごく簡単な HTTP テストプラグインをつくっただけでまだまだ未完成ですが、以下のような config.yaml で実行すると、HTTP GET して取得したコンテンツに「It works!」が含まれているかどうかテストする、といった感じで動作します。

plugins:
  - module: HTTP
    config:
      url: http://svn.mizzy.org/
      match: It works!

これって、サーバのテストだけでなく、監視にも使えるよなー、と思ったところで、ライブドアテクノロジーセミナーで naoya さんが触れていた、Observer というはてな製監視フレームワークとかぶるんじゃないか、という気がしてきました。Plagger ライクって言っていたし。

ということは、はてなが Overver を公開してくれれば、自分で開発する必要がなくなって楽ができそう、ってことで、公開希望とここでつぶやいておきます。

Net::LDAP::Abstract #0

Posted by Gosuke Miyashita Tue, 02 Jan 2007 18:55:33 GMT

Net::LDAP のラッパモジュール Net::LDAP::AlternativeNet::LDAP::Abstract に変えて、少し修正しました。svn で取得するには以下のように実行して下さい。

svn co http://svn.mizzy.org/public/library/perl/trunk/Net-LDAP-Abstract/

名称を Alternative から Abstract に変えたのは、LDAP アクセスの処理を Net::LDAP の実装よりも更に抽象化しているから、というのと、検索フィルタを SQL::Abstract ライクに書けるから、という理由からです。

たとえば、Net::LDAP では

my $msg = $ldap->search(
    base   => 'o=southpark',
    filter => '(|(&(!(cn=*gosuke))(sn=miyashita))(uid=miya))',
);

とやたらと括弧の多いフィルタを自分で書かなければいけないところを、Net::LDAP::Abstract では

my $entries = $ldap->search({
    -or => {
        uid => 'miya',
        -and => {
            sn => 'miyashita',
            cn => { '!=' => '*gosuke' },
        }
    }
});

といった感じで書けます。これは超便利。

フィルタを組み立てるコードは、SQL::Abstract からそのまんまぱくってます。

Net::LDAP::Alternative

Posted by Gosuke Miyashita Sun, 31 Dec 2006 19:10:24 GMT

perl-ldap (Net::LDAP) のインターフェースがわかりにくくて、たまにこいつでプログラムを書こうとすると、いつもど忘れして perldoc と睨めっこするはめになるので、違うインターフェースで LDAP アクセスできるラッパモジュールを書いてます。とりあえずプロトタイプ版の Net::LDAP::Alternative を置いておきます。まだ未完成で pod すらちゃんと書いてないですが。

インターフェースがどんな風に違うかを例で示してみます。「特定の検索条件にマッチするエントリの電話番号を書き換える」という操作を、Net::LDAP で書くとこんな感じになります。

my $ldap = Net::LDAP->new(
    'kenny',
    port => 389,
);

$ldap->bind(
    'cn=Directory Manager',
    password => 'password',
);

my $msg = $ldap->search(
    base   => 'o=southpark',
    filter => '(&(uid=miya)(cn=gosuke*))',
);

for my $entry ( $msg->entries ) {
    print $entry->get_value('telephonenumber');
    $ldap->modify(
        $entry->dn,
        replace => { telephonenumber => '00-0000-0000' }
    );
}

これを Net::LDAP::Alternative で書くとこうなります。

my $ldap = Net::LDAP::Alternative->new({
    host    => 'kenny',
    port    => '389',
    bind_dn => 'cn=Directory Manager',
    bind_pw => 'password',
    base    => 'o=southpark',
});

my $entries = $ldap->search({
    uid => 'miya',
    cn  => 'gosuke*',
});

while ( my $entry = $entries->next ) {
    print $entry->telephonenumber;
    $entry->telephonenumber('00-0000-0000');
    $entry->update;
}

Net::LDAP と特に異なる点は、

  • bind は明示的にしない。(コンストラクタで bind してる。)
  • search を簡略化。LDAP 特有のフィルタ記法で書かなくて良い。
  • 検索して得られるエントリをイテレータにしてみた。
  • エントリの属性取得のアクセサメソッドを実装。(get_value をつかわなくてよい。)
  • エントリの属性変更もアクセサメソッド経由でできるので直感的にわかりやすい。

ってとこですね。

また、1件しか検索結果が返らないことがわかっている場合は、Net::LDAP であれば

my $msg = $ldap->search(
    base   => 'o=southpark',
    filter => '(&(uid=miya)(cn=gosuke*))',
);

my $entry = ($msg->entries)[0];

といった感じでエントリを取得するわけですが、Net::LDAP::Alternative では

my $entry = $ldap->search({
    uid => 'miya',
    cn  => 'gosuke*',
})->first;

といった感じでエントリ取得ができます。

こんな感じで、DBIx::Class のインターフェースを参考にして、直感的にわかりやすいようにしてます。

とりあえずなんとなくつくってみただけなので、これを発展させるかどうかはまだ未定。