Chrono Mock
言語日本語

アプリをテストするためにシステム日付を変更する

これは昔からある最も古い手です。Windows の時計をテストしたい日付に合わせ、プログラムを実行し、時計を元に戻す。確かに効きます。ただし、時計を動かしている間は、マシン上のほかのすべても一緒に動いてしまいます。

時計と一緒に実際に動くもの

システム時計は、テスト中のプログラムだけのものではありません。マシン上のあらゆるプロセス、サービス、ネットワーク通信が同じ時計を読むため、1 つのテストのための変更は、すべてに対する変更になります。

時計を読むもの時計を動かすと起きること
ドメインへのサインインと共有フォルダーKerberos は既定で 5 分の時計のずれまで許容します。それを超えるとチケットが拒否され、サインインや共有へのアクセスが失敗します。
証明書と HTTPS証明書が有効かどうかは時計で決まります。証明書の有効期限の先に時計を進めると、それに頼るすべての接続が期限切れとして拒否されます。十分に戻すと、証明書はまだ有効になっていません。
Windows Time サービスドメインに参加したマシンはドメインコントローラーから時刻を取得し、既定ではずれの大きさにかかわらずサービスが時計を修正します。設定した日付が、まだテスト中に取り消されることがあります。
時刻を記録するものすべて時計を動かしている間に作られたファイル、ログ、データベースの行、送信したメールにはテストの日付が残り、時計を戻した後もそのままです。
見た中で最も新しい日付を覚えているソフトウェア時計が逆戻りすることを改ざんと見なすプログラムがあります。本物の日付に戻すときに起きるのが、まさにそれです。

日付が遠いほど、こうした問題に多く出会います。2038 年に設定したマシンは、今日発行されたすべての証明書を期限切れと見なします。それなしで 2038 年をテストする →

さらに、ほとんどのアカウントが持たない権限も必要です。システム時刻の変更は管理者の特権で、管理されているマシンでは自分が使えないことがよくあります。

時計を変更するのが正解になる場面

ほかの誰も使わない仮想マシンで、専用の時計同期をオフにしてあるなら、テスト用の環境として申し分ありません。使い終わったら捨てるので、そこに記録されたものは何も問題になりません。1 台あって、テストが 1 つの日付だけなら、それがうまくいく最も簡単な方法です。

問題が始まるのは、それが自分が作業しているマシン、ドメインに参加しているマシン、あるいは同時に何も気づいてはいけないものを動かしているマシンの場合です。

代わりに 1 つのプログラムの時計だけを動かす

ずらした時刻が見えるのは、1 つのプロセスと、そこから起動される子プロセスだけです。ドメインへのサインイン、証明書、Windows Update には決して見えないので、上の表のものは何も動かず、後で戻すものもありません。

# アプリには 2027 年 12 月 31 日 23:59:50 に見える。ほかはすべて本物の日付のまま。
chrono run "C:\apps\test.exe" --at 2027-12-31T23:59:50

# 午前 0 時の 10 分前から 60 倍速で実行 - 10 秒で年が変わる
chrono run "C:\apps\test.exe" --at 2027-12-31T23:50:00 --mode x60

1 つのプログラムのためにずらした日付が本当にそのプログラムに届いたかどうかは、思い込むことではありません。すべてのセッションは、判定と、プログラムが実際に読んだ時刻チャネルの一覧で終わります。効いたかどうか、どうやって分かるのか →

これが置き換えないもの

  • 時刻をサーバーに問い合わせるプログラムは、ローカルの置き換えが届く範囲の外にあります。セッションは、プログラムがネットワーク接続を開くのを見つけるとそれを知らせ、テストが通ったと思い込ませたままにはしません。
  • システムそのもののテスト、つまり本物の時計の変更に反応するサービス、スケジュールされたタスク、時計の変更前後の Windows の挙動には、時計を変更する以外に代わるものはありません。それも、犠牲にしてよいマシンで行ってください。

試してみる