act_as_authenticated に自動生成された UserTest の test_should_reset_password が失敗するという現象が発生しています。具体的には以下のコードで失敗します。
# 前からこんな現象あったかなー???

def test_should_reset_password
  users(:quentin).update_attributes(:password => 'new password', 
    :password_confirmation => 'new password')
  assert_equal users(:quentin), User.authenticate('quentin', 'new password')
end

エラーの発生条件:RadRails 0.7.1 上で Run Unit Tests を実行する、rake test:units を実行する

ただし、上記テストメソッド単体を実行すると、テストは成功することから、他のテストメソッドの実行結果に影響されて失敗していることがわかります。DB の内容を見ると、users(:quentin) の login(ユーザ名)は 'quentin' ではなく 'quentin2' になっています。このことから、test_should_reset_password は、test_should_not_rehash_password に依存しているようです。

Ruby(と Rails)の UnitTest フレームワークの性質をよく知らないのですが、テストメソッドを実行するたびに DB の初期化が実行されればこういった問題は発生しないと考えられるので、DB の初期化を行うタイミング(=fixtures メソッドが呼ばれるタイミング)はテストクラスを読み込む一度きりということでしょう。

とはいえ、原因がわかっても、テストコードの修正は簡単ではありません。他のテストの実行の有無で結果が変わってしまうテストを変わらないコードにするというのはなかなか難しいことです。とりあえず以下のように考えてみました。

このテストのやりたいこと:レコード更新時にパスワードを変更する(:password_confirmation があるときは、パスワードを更新することを確認したい。※)

※ そういう意味では、更新時に :password のみを変更して :password_confirmation を変更しない or 間違っているテストが無いことは少し疑問です。もっとも、生成時のテストはあるからそれで問題はありませんが。

修正案1:レコード更新時に login も更新する
def test_should_reset_password
  users(:quentin).update_attributes(:login => 'quentin', 
    :password => 'new password', :password_confirmation => 'new password')
  assert_equal users(:quentin), User.authenticate('quentin', 'new password')
end

メリット:修正は簡単
デメリット:テストコードの意図がやや不明瞭になる

修正案2:更新したユーザのインスタンスから名前を取得して、認証を行う
def test_should_reset_password
  users(:quentin).update_attributes(:password => 'new password', 
    :password_confirmation => 'new password')
  assert_equal users(:quentin), User.authenticate(users(:quentin).login, 'new password')
end

メリット:テストの意図はそのまま
デメリット:元と比べてコードがわかりにくい?(というか、なんか気持ち悪い・・・)

とりあえず、修正案2で行きます。


Posted by あかさた
Kodougu で必要だったので、Rails アプリ上で Ruby の eval を使用したときの安全性を調査していました。ご存知のとおり、eval 関数は、文字列で渡された Ruby ソースコードを実行するものです。しかし、外部からスクリプトを渡して実行しようとすると、セキュリティの観点から危険な場合があります。以下のような例(外部から渡された script が DB を操作している)です。

script = <<-EOS
  # ActiveRecord を操作する
  @metaelement = Metaelement.new
  @metaelement.name = "execute_eval"
  @metaelement.save
EOS

Thread.start {
  # $SAFE = 4 <- このコメントアウトを外すと SecurityError 例外発生
  eval(script)
}.join

デフォルトでは上記のコードは動作します。安全ではない eval です。しかし、$SAFE = 4 にして上記のコードを実行すると、SecurityError 例外が発生します。Ruby のセキュリティモデル Level 4 には、「汚染されていないオブジェクトの状態の変更」を禁止するルールがあるので、これに引っかかったようです。Level 4 では以下のようなコードでも SecurityError 例外が発生します。

script = <<-EOS
  @metaelements = Metaelement.find(:all)
EOS

Thread.start {
  $SAFE = 4
  eval(script)
}.join

では、Rails でも Level 4 で eval すれば安全・・・というと、ちょっと自信がありません。たとえば以下のようなコードは動作してしまいます。

script = <<-EOS
  Metaelement.connection # DB のコネクションを取得。
EOS

Thread.start {
  $SAFE = 4
  eval(script)
}.join

上記のようなコードの動作を許可すると、DB のユーザ、パスワードとかを取れてしまいます。見られたくない情報です。eval の用途によっては非常に危険です。危険な例としては、ページ上で eval で評価した結果を表示する場合などが挙げられます。Rails の全メソッドに rb_secure(1) とかを仕込めばいいのでしょうかね。(^^; (ありとあらゆる面から論外でしょうけど。)

Ruby on Rails でサンドボックスというのはさすがに無理ですかね~。。。


Posted by あかさた
今日は未踏の千葉 PM とのミーティングに行ってきました。Kodougu については、細かな進捗というよりは、プロジェクトの根本的なリスクについて話し合ってきました。

話した内容は以下のとおりです。
・ 進捗
・ モデリング言語設計機能に関する実現方法と実現可能性について
・ プロジェクトというか、Kodougu が抱える根本的なリスク

進捗は・・・ぼちぼちでんなー、ということを話してました。(--; 実現可能性についてはさほど問題はなさそうという共通認識が PM と取れるようになってきました。ただし、仕様については割り切り重要。

Kodougu が抱えるリスクについてですが、指摘をまとめると、「Kodougu は一見するとモデリングツールっぽく使えるお絵かきツールに見えてしまうので、そうではない点を説明できる機能なり効果的なユースケースなりを示せるようにしてほしい」ということです。4 月末に中間発表があるので、そこである程度この問題点を解消したいと考えています。

今日発見したこと。
・ 千葉 PM 下 4 人の採択者のうち 2 人は私の家から結構近いところに住んでいる。(驚)

ローカルな話題でちょっと盛り上がってしまいました。(笑)

Posted by あかさた
Kodougu の表示が IE7 でおかしくなることを確認しました。IE6 では表示されるのに。orz

IE7 になって HTML のレンダリングエンジンが新しくなったらしく、このブログでも細かいところが、表示されなくなっています。Web アプリとしては、IE6 と IE7 を別物のブラウザとして考えて実装せよってことですかね。。。大変な世界だ。

Posted by あかさた
最近、PC の調子が悪くて(1時間に一回はハングする)困っています。4 年くらい使ったので、そろそろ寿命かも・・・とか思ったのですが少し延命措置を行ってみることにしました。

以下、PC の基本スペックです。

CPU:P4/2.8GHz(Northwood)
Memory:512MBx2 -> 1GBx2, 512MBx2
Mother:i865 系(Socket478)
VideoCard:Geforce2MX -> Geforce7600GS 256MB
HDD:120GBx2
DVD:DVD-ROMx10
電源:350W -> 450W

基本方針:マザーボードは変えない
(マザーボードが古すぎて入手が難しいことと、マザーを変えても、長く使うための延命措置は取れないと思うので、マザー帰るくらいなら PC 買い替えという覚悟で行きます。)

■ 作業履歴
1. 電源の変更
HDD を 2 台積んでいて、ビデオカードも消費電力が高めの物を使っているので電源がへたったのかもと思い、電源を変えてみました。ミドルタワーの電源としては、350W は決して多くないので、これまでもかなりぎりぎり限界の電力で稼動してきた可能性も高い(冷却ファンの音がすごかった)のかなと感じています。SilentKing5 450W を買って付け替えてみました。新しい電源は消費電力に余裕があるのか、音もかなり静かです。

2. BIOS の変更
動的に電圧を変更してパフォーマンスをあげるような類の機能をすべてオフにしました。つーか、こんなのオンにした記憶はないのになぁ・・・。ついでに、なぜか存在しない FDD を見に行く設定になっていたので、それも修正しました。

■ 成果
修正してから 4 時間ほど使っていますが、ハングはしなくなりました。パフォーマンス設定を下げたので、パフォーマンス低下が心配だったのですが、HDBench を実行してみたところ、巷の同クラスの PC 程度の性能は出ていたので、問題なしと判断しました。これで 1 年くらいもってくれるとうれしいかな・・・?

Posted by あかさた
平鍋さんのブログを読んでいたら、以下のような記述がありました。

JUDE 今期('06/4-'07/3)の販売目標 - An Agile Way より

チェンジビジョンの決算を迎える訳ですが、JUDE/Professional の有償版販売目標である、6千本を、もう少しで達成します。


保守更新を含まないでですよね? 私もこの手のツールのビジネスに関わっていたことがあるので、この本数が結構すごい(※)ことは承知しています。それでも、無償版が数十万本も出ていたことを考えると、思ったほど多くは無いなという感じを受けました。売り上げ的には保守更新もあるでしょうから、問題はなさそうですけど。

※ JUDE は無償版も結構使えてしまいますから、なおさら凄い。

Kodougu も近いといえば近い(遠いといえば遠い)ツールなので、こういうビジネス的な話題には思わず注目してしまいますね。(^^;

Posted by あかさた
以下の記事について非常に頷けるものがありました。

小野和俊のブログ:IT業界の大企業での生々しい話を5つほどより

1. 2ch へのアクセス禁止で開発効率が大幅に低下
<中略>
2. 人事評価制度の歪みを解消するためにあえて優秀でない人材を採用
<中略>
3. 社内では使われない自社パッケージ
<中略>
4. 競合他社への販売禁止を条件に出されパッケージ販売を断念
<中略>
5. IPAのプロジェクトで間接業務に忙殺される


1, 2, 3 については、私にも経験があります。1 についてですが、2ch はともかくとして、会社の枠を越えた(仕事に関係する)横のつながりを重視する人としない人とで意見が分かれてくると思います。少し文面の内容とはずれますが、プライベートはともかくとして、仕事面で会社で枠を作ってしまうことで、活動の幅を狭めている人は多い気がします。
(そういう人がわりと悪気なしにこういうコミュニケーションを阻害する仕組みを作ってしまうんですよね。)

2 ですが、優秀でない人材云々はともかくとして、人事評価は相対評価なので、仕方の無いことだと思います。ま、高く評価されない変わりに、低く評価もされないということです。私のように独りものならともかく、養わなくてはならない家族がいる人には、リスクが低いほうがいいと思うので、これはこれでアリなのかなと考えたりもします。

3 は・・・以下、まったくおっしゃるとおりです。(--;。

保守の問題があるから簡単には捨てることはできないかもしれないが、そんな状況なら少なくとも新規の販売は差し止めた方がよいのではないかと思う。自社でも使いたくない製品を買わされる側はたまったものではない。


5 について・・・未踏は恵まれてるんですね~。実際、未踏では間接業務に費やす時間はほとんどありません。その上、プロジェクト管理組織というある意味雑用を一手に引き受けてくれる方がいらっしゃるので、開発者は本当に楽です。

久々に IT 業界のどろどろとした話を思い出しました。(^^;

Posted by あかさた
私は Ruby の module のテストは以下のように行っています。

[code: def test_hoge

@dummy_object = Object.new
@dummy_object.extend(HogeModule)
assert ...hogehoge...
end]

他にも以下のような方法も考えられます。クラスを生成してからモジュールを拡張する方法です。

[code: def test_hoge

@new_class = Class.new
@dummy_object = @new_class.allocate
@dummy_object.extend(HogeModule)
assert ...hogehoge...
end]

コードとしては以下がわかりやすいかも。明示的にテスト用のクラスを作成する場合です。

[code: class Dummy

include HogeModule
end

def test_hoge
@dummy_object = Dummy.new
assert ...hogehoge...
end]

Ruby の module は Java や C# には無い概念なのでどういうテストをしたらいいのか悩みますね。

Posted by あかさた
Rails を動作させるプラットフォームとしては、scgi よりも Mongrel に力が入っているという話なので、Kodougu と同じくこのブログも Apache2.2 + Mongrel に変更しました。ついでに、Rails 1.2 に対応したのですが、ちゃんと動いているでしょうか・・・?

このブログについてはこちらを参照してください。ソースコードのチェックアウトなどもできます。テストもロクに書いていないひどいコードですが。

■ 2007/3/16 22:44 追記
従来はロードバランスしていなかったので、scgi サーバでは一つのコネクションしか処理できませんでした。アクセス数が少ないので、通常のブラウジングであればそれでも問題ないのですが、他のブログにトラックバック送信を行おうとすると問題になります。

送信先のブログが言及リンクチェックをする場合ですが、チェックのためにこちらのサーバに接続すると、ブログ投稿者がコネクションを占有してしまっているので、送信先のブログはコネクションが空くのを待つようになり、こちらのサーバは送信先のトラックバック完了待ちになって、デッドロック状態になります。投稿者の接続がタイムアウトすると、送信先の言及リンクチェックが完了し、トラックバックが完了します。

こんなばかばかしい現象も、ロードバランスをしたおかげで発生しなくなりました。

Posted by あかさた
最近私が実践している「くそエディタ」を立ち上げる方法について。

「くそエディタ」については以下を参照してください。

射撃しつつ前進 - The Joel on Software Translation Project
http://local.joelonsoftware.com/mediawiki/index.php/%E5%B0%84%E6%92%83%E3%81%97%E3%81%A4%E3%81%A4%E5%89%8D%E9%80%B2

このやり方は Windows にのみ対応しています。でも別に他の OS でも実践できるでしょう。[スタート]-[すべてのプログラム]-[スタートアップ]にエディタもしくは IDE のショートカットを追加します。すると、PC を起動すると、勝手にエディタが立ち上がってくれます。間違っても、スタートアップでメーラやブラウザを立ち上げないこと。

わーい、これでたくさんプログラムが打てるぞ!

Posted by あかさた