テストに使う

ストレージと再起動

Calendarpit がデータを保存する場所、SQLite とインメモリモードの選び方、再起動やリセットの後に残るデータについて説明します。

Calendarpit は、デフォルトでワークスペースの状態をローカルの SQLite ファイルに保存します。使い捨てのテストセッションでは、インメモリに保存することもできます。

ストレージモードの選び方

Homebrew や単体実行ファイルでは、デフォルトで起動したディレクトリ内の .calendarpit/calendarpit.sqlite に保存します。プロジェクトのディレクトリから起動すると、プロジェクトごとにデータを保持できます。

保存先や :memory: は --database <path> または CALENDARPIT_DATABASE で指定します。CLI フラグは環境変数より優先されます。必要な環境と公開状況はインストールで確認してください。

# Temporary E2E session; no database files are written
calendarpit serve --database :memory: --port 0

# Choose a persistent workspace
calendarpit serve --database ./.calendarpit/manual.sqlite

モード

  • SQLite ファイル(デフォルト): 状態を変更するリクエストが終わるたびに、変更を保存します。Webhook の配信が終わったときにも保存します。相対パスは作業ディレクトリを基準に解決されます。
  • インメモリ(:memory:): データベースファイルもロックファイルも書き込みません。プロセスが終了すると、すべての状態が破棄されます。
  • Docker: イメージでは CALENDARPIT_DATABASE=/data/calendarpit.sqlite が設定されています。
    • コンテナを削除して作り直してもデータを残すには、-v calendarpit-data:/data で名前付きボリュームをマウントします。
    • 一時的なセッションには -e CALENDARPIT_DATABASE=:memory: を渡します。
    • Compose の例も名前付きボリュームを使います。docker compose down ではデータが残り、docker compose down -v では削除されます。

使用中のモードを確認する

使用中のストレージモードとパスは、次の 3 か所で確認できます。

  • 起動ログ: CLI は Data <absolute-path>(または Data :memory:)を出力します。サーバーのエントリが読み込まれた時点で Calendarpit data: <path or :memory:> も出力します。
  • 管理画面: サイドバーのフッターに SQLite または In-memory が表示されます。Settings → Test data には、モードの説明とパス(または :memory:)が表示されます。
  • 管理 API: GET /__calendarpit/health は storage: "sqlite" | "memory" を返します。GET /__calendarpit/state は storage: { mode, path? } を返します。

SQLite の再起動後に残るデータ

既存の SQLite ファイルを開き直すと、保存済みのデータが復元されます。短時間しか使わないフローの状態は破棄されます。

SIGINT または SIGTERM を受け取ると、Calendarpit は次の順に処理します。

  1. 処理中の Webhook 配信を中断します。
  2. 状態を保存します。
  3. データベースのロックを解放します。

再起動後の扱いは、状態の種類ごとに次のとおりです。

状態SQLite の再起動後の扱い
ユーザー、カレンダー、イベント、OAuth クライアント復元されます。イベント ID、タイムスタンプ、etag もそのまま残ります
カレンダーリストの設定復元されます。リセットまたは Fixture の読み込みで消去されます
リセット基準(起動時 Fixture)最初の初期データが保持されます
OAuth 接続(grant)、アクセストークン、リフレッシュトークン復元されます
watch チャネル下記の条件を満たす場合だけ復元されます
リクエスト履歴、配信ログ、通知それぞれ最新の 200 件が復元されます
キュー内または処理中の Webhook 配信cancelled になります。自動で再送されることはありません
同期トークン、カレンダーの削除済みレコード復元されます。リセットまたは Fixture の読み込みで消去されます
保留中の同意、認可コード、ページトークン破棄されます。フローまたは一覧の取得をやり直してください

一部の行の補足です。

  • カレンダーリストの設定には、ユーザーごとの上書き・色・非表示/選択状態・リマインダー・削除したエントリが含まれます。
  • リセット基準: --config または CALENDARPIT_CONFIG のファイルの内容は無視されます。
  • トークンと接続:
    • アクセストークンは元の有効期限のままです。
    • リフレッシュトークンは期限切れになりません。
    • 取り消した接続は取り消されたままです。
  • watch チャネルは、次のすべてを満たす場合に復元されます。復元されたチャネルはメッセージ番号も引き継ぎます。
    • 有効期限内である。
    • 接続が有効である。
    • コールバック先のホストが引き続き許可されている。
  • ページトークンは calendarList と events のカーソルです。

再起動後は、アプリ側でカレンダーの状態を再取得してください。停止によって中断されたwatch 通知の差分を取り込めます。

初期データ、Fixture、リセット

起動時Fixtureがデータを投入するのは、新しいデータベースのときだけです。起動時 Fixture は、--config、CALENDARPIT_CONFIG、または組み込みのデフォルトから読み込まれます。

  • 既存の SQLite ファイル: 保存済みのデータと、最初のリセット基準を開き直します。
    • --config または CALENDARPIT_CONFIG を設定していても、Fixture の内容は無視され、既存のデータベースは上書きされません。
    • ただし、指定したファイルが存在し、有効な JSON である必要があります。
  • インメモリモード: 起動するたびに新しいデータベースになります。そのため、起動時 Fixture は毎回適用され、省略した ID も毎回生成し直されます。
  • リセット(POST /__calendarpit/reset): 再起動をはさんでいても、起動時のリセット基準に戻します。
    • 接続・トークン・認可コード・同意・watch チャネル・カレンダーリストの設定・同期トークン・ページトークン・カレンダーの削除済みレコード・リクエスト履歴・通知・配信を消去します。
    • すぐに保存します。
    • SQLite ファイルを削除したり、Fixture のファイルを変更したりはしません。
  • Fixture の読み込み(POST /__calendarpit/fixtures): 現在のデータを置き換え、実行時の状態を消去します。リセット基準は変わりません。 その後にリセットしても、最初の初期データに戻ります。詳しくはテスト制御 APIを参照してください。

ロック、ファイル、並列実行

1 つのファイルに 1 プロセス

1 つの SQLite ファイルを同時に使えるのは、1 つの Calendarpit プロセスだけです。

  • Calendarpit は実行中、<db>.lock に排他ロックをかけます。
  • 同じファイルを使う 2 つ目のプロセスは、起動時に Database is already in use: <path>. Use a separate path or :memory:. というエラーで失敗します。CLI ではこの前に Calendarpit: が付きます。
  • ロックはプロセスの終了時に OS が解放します。クラッシュした場合も同じです。

テストを並列に実行する場合は、ワーカーごとに --database :memory: を使うか、別々の SQLite ファイルを指定してください。

補助ファイルとパーミッション

SQLite は WAL モードで動作します。Calendarpit は実行中、データベースと同じ場所に次の補助ファイルを作成します。

  • <db>-wal
  • <db>-shm
  • <db>.lock
  • <db>.lock-journal

データベース、-wal、-shm、.lock の各ファイルはモード 0600 になります。Calendarpit がデータベース用のディレクトリを作成した場合、そのディレクトリはモード 0700 になります。

実行中は補助ファイルをデータベースと同じ場所に置いたままにしてください。データベースファイルをコピーするときは、先にサーバーを停止してください。

データベースを Git に含めない

データベースにはローカルのテスト用認証情報とクライアントシークレットが入っています。Git には含めないでください。

このリポジトリでは、次のものが Git で無視されます。

  • .calendarpit/
  • *.sqlite、*.sqlite-wal、*.sqlite-shm、*.sqlite.lock のパターン
  • <db>.lock-journal(.calendarpit/ の中にある場合だけ)

目次