引きこもり

1日中、雨降りだったのでテストコードを書いてた。

Trac のクロスリファレンスプラグインのバグ修正

前のアルバイト先の社員さんがバグ報告してくれた。

チケット間のリファレンス情報は ticket_custom テーブルにテキストでもっている。ticket テーブルを操作しないので、チケット編集時のトランザクション管理をどうすれば良いのかを調べられてなかった。

同時編集のバリデーションチェックに Trac 側では、ticket テーブルの "changetime" フィールドをリクエストオブジェクトの中に保持していて、チケット更新前に対象チケットの "changetime" が変更されていないかをチェックしている。

Trac の ticket テーブル内の日時情報は integer で持っていて、リクエストオブジェクト内の "changetime" は、日時情報を以下のような文字列で保持している。

2012-03-24 02:44:56.966902+00:00

チケット間のリファレンス情報を更新したときに ticket_change テーブルにはその履歴を書き込んでいるので、ticket_change の "time" とリクエストオブジェクトの日時情報を比較すれば、簡単にバリデーションチェックできるかなと、当初は考えた。しかし、この日時情報にあるタイムゾーンを考慮するのが面倒だと分かり、プラグイン内でバリデーションチェクを記述するのを諦めた。

もう1つの手段として、ticket テーブルの "changetime" を更新して Trac 側のバリデーションチェックで制御するように修正した。ついでに ticket_change の履歴情報の内容が正しくなかった不具合も修正してリリースした。

Trac プラグインユニットテスト

PyCon でテストの講演をたくさん聞いたのもあり、Trac プラグインユニットテストを書くことにした。

trac.test.EnvironmentStub を使ってユニットテストを書く。プラグインを有効にするための前処理は以下のコードを参考にした。

ユニットテストを書いていて、Trac のチケットのトランザクション管理がどうなっているかが少し分かった。

TracTicketReferencePlugin では、直接 DB のテーブルに SQL で更新をかけてコミットしている。参考にしたプラグインがそうやっていたのと、Trac のチケットのトランザクション管理を調べてなかったからだ。

おそらくは Ticket.save_changes() を呼び出すと ticket_custom テーブルも更新してくれるようなので、わざわざ自分で更新処理を書かなくても良いように見える。先の "changetime" も自前で更新しなくて良い。最初からユニットテストを書いてれば、自分で SQL を記述する必要もなく、もっとスマートなコードになっただろうなと思う。