Skip to main content
一部の拡張機能は、テスト中に外部のHTTPサーバーやその他のネットワークリスナーと通信する必要があります。たとえば、アウトバウンドHTTPリクエストを行う拡張機能では、それらを受け取るためのローカルのエコーサーバーが必要です。このページでは、それらのテストが--parallel=autoのもとで、また複数のオペレーティングシステムにわたって確実に実行されるように構成する方法を説明します。 ここで説明するパターンは、C++拡張機能とRust拡張機能の両方に等しく適用されます。どちらもcargo vsql testを介してテストランナーとしてMTRを使用します。

ハードコードされたポートが失敗する理由

MTRでは、2つの障害モードによってハードコードされたポートが信頼できないものになります。 --parallel下でのポートの競合。 MTRは各ワーカーに、その@@port値の周辺のポート範囲を割り当てます。その範囲外の固定ポート(たとえば18777)は、別のワーカーの予約済みブロックやシステムサービスと競合する可能性があり、高い並列度でのみ再現する断続的なEADDRINUSEを引き起こします。 OSレベルの変更。 新しいランナーイメージやOSバージョンでは、以前は機能していたポートを定期的に予約したり制限したりします。今日はローカルとCIでパスするポートが、明日にはサイレントにバインドに失敗する可能性があります。 どちらの場合も解決策は同じです。ポート0にバインドしてOSに利用可能なポートを割り当てさせ、その後、実際のポートをテストに伝えます。

パターンA: サーバー統合型リスナー

これは、ネットワークリスナーがMySQLプロセス内で実行される場合に使用します。たとえば、HTTPサーバーを埋め込む拡張機能です。 拡張機能内で、バインド後にバインドされたポートをステータス変数として公開します。
テスト内で、MTRのwait_condition.incを使用して、ステータス変数がゼロでなくなるまでポーリングし、その後、実際のポートをMTR変数にキャプチャします。UNINSTALL EXTENSION / INSTALL EXTENSIONのサイクルの後は再読み取りします。エフェメラルポートはバインドのたびに変わります。

パターンB: 外部プロセスリスナー

これは、リスナーがスタンドアロンのプロセスである場合に使用します。Pythonヘルパーサーバー、モックAPI、またはMTRが直接制御しない任意の外部プログラムです。
このパターンにはPATH上にpython3が必要です。GitHubホステッドランナーにはこれが含まれています。セルフホステッドランナーで使用する前に、利用可能かどうかを確認してください。

フォアグラウンドランチャー

サーバーを--exec ... &でバックグラウンド化してポートをポーリングするのではなく、次のことを行うフォアグラウンドランチャースクリプトを使用します。
  1. start_new_session=Trueでサブプロセス内にサーバーを起動する
  2. サーバーがバインドしてレディネスファイルを書き込むまでブロックする
  3. 終了して、MTRの続行を許可する
MTRはフォアグラウンドの--exec呼び出しでブロックするため、これによりSQLが実行される前にサーバーの準備が完了していることが保証されます。個別のポーラーやスリープは不要です。 launcher.py — これを--write_fileで記述します。
echo_server.py — 実際のサーバーで、サービスを提供する前にポートを書き込みます。

テスト内で

ランチャーを起動し(フォアグラウンド — MTRは終了までブロックします)、その後ポートファイルをソースします。

ポートを結果ファイルから除外する

結果ファイルは、記述されたとおりのSQLを記録します。URLにエフェメラルポート番号が含まれている場合、結果ファイルには実行ごとに異なる値が含まれることになり、テストはレコード/リプレイのたびに必ず失敗します。 ポートファイルをソースし、MySQLセッション変数の設定を--disable_query_logのもとでまとめて行い、let代入もエフェメラルポートも出力に現れないようにします。URLが必要な場所ではすべてセッション変数を使用します。

プロセス管理

ヘルパーの出力をログに記録する — 決して破棄しない。 上記のランチャーパターンは、サーバーのstderrをecho_server.logに書き込み、失敗時にそれを出力します。ヘルパーの出力を破棄すると、CIアーティファクトで不安定なテスト(フレーク)の原因が説明できなくなります。 名前ではなくPIDでkillする。 Linuxでは、pkill -f echo_server.py/proc/cmdlineを介してMTRプロセス自体に一致する可能性があります。ランチャーによって書き込まれたPIDファイルを使用します。
テストが終了する前に、すべての一時ファイルを削除する。 MTRのcheck-testcaseは、$MYSQLTEST_VARDIR/tmp/に残されたファイルをダーティ状態としてフラグ付けし、テストを失敗させます。
パターンBの完全でテスト済みの実装については、vsql-http/mysql-test/t/vsql_http_requests.testを参照してください。--write_fileからクリーンアップまで、テストのライフサイクル全体をカバーしています。

関連項目

  • C++テスト — MTRのセットアップ、スイートの実行、結果の記録、失敗のデバッグ
  • C++での拡張機能の作成 — エンドツーエンドのビルド手順とCMakeのセットアップ
  • C++開発 — VDFの作成、引数の型、結果の処理