Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10671] ファイルの概要

このコミットは、Go言語のリポジトリにおけるmisc/cgo/testsoディレクトリ内のテストスクリプトに関する改善です。具体的には、cgoを使用した共有ライブラリのテストにおいて、テスト実行後に生成される一時ファイルが残らないようにするための変更が行われました。これにより、テスト環境のクリーンアップが適切に行われ、テストの再現性と信頼性が向上します。

コミット

commit 692c31d60a1bba484bca6efb59619243bb93d483
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Fri Dec 9 11:00:49 2011 +1100

    misc/cgo/testso: do not leave out file behind

    R=golang-dev, dvyukov
    CC=golang-dev
    https://golang.org/cl/5461044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/692c31d60a1bba484bca6efb59619243bb93d483

元コミット内容

misc/cgo/testso: do not leave out file behind

このコミットの目的は、misc/cgo/testsoディレクトリにあるテストが、実行後に不要なファイル(outファイル)を残さないようにすることです。

変更の背景

Go言語のテストスイートは、様々な環境で実行されるため、テストの実行が環境に副作用を残さないことが重要です。特に、cgoのような外部Cコードとの連携を伴うテストでは、コンパイルされた共有ライブラリや実行ファイルが一時的に生成されることがあります。

このコミット以前は、misc/cgo/testsoのテストが実行された際に、生成された実行ファイル(out)がテストディレクトリに残ったままでした。これは、テストのクリーンアップが不完全であることを意味し、以下のような問題を引き起こす可能性があります。

  1. ディスクスペースの消費: 多数のテストが実行されるたびに不要なファイルが蓄積され、ディスクスペースを消費します。
  2. テストの再現性の低下: 以前のテスト実行で残されたファイルが、次のテスト実行に影響を与える可能性があります。例えば、古いoutファイルが残っていると、新しいビルドが正しく行われたかどうかの判断が難しくなる場合があります。
  3. CI/CD環境での問題: 継続的インテグレーション/継続的デリバリー (CI/CD) パイプラインでは、テスト環境が常にクリーンであることが求められます。残存ファイルは、ビルドやテストの失敗の原因となることがあります。

このコミットは、これらの問題を解決するために、テスト実行後に生成物を適切にクリーンアップするメカニズムを導入することを目的としています。

前提知識の解説

このコミットを理解するためには、以下の技術的背景知識が必要です。

  • Go言語のテスト: Go言語にはgo testコマンドによる組み込みのテストフレームワークがありますが、このコミットで扱われているのは、シェルスクリプト(test.bash, run.bash)を用いたより低レベルなテスト実行と管理です。これは、GoのビルドシステムやCgoの特定の挙動をテストするために用いられます。
  • Cgo: Go言語からC言語のコードを呼び出すためのメカニズムです。cgoを使用すると、Goプログラム内でCの関数を呼び出したり、Cのデータ構造を利用したりできます。このプロセスでは、Cコードのコンパイルとリンクが必要となり、共有ライブラリ(.soファイルなど)や実行ファイルが生成されることがあります。
  • 共有ライブラリ (Shared Library): 複数のプログラムから共有して利用できるライブラリです。Linuxでは.so(Shared Object)、macOSでは.dylib、Windowsでは.dllといった拡張子を持ちます。プログラムが実行時にこれらのライブラリをロードすることで、コードの再利用やメモリ効率の向上が図られます。
  • LD_LIBRARY_PATH: LinuxやUnix系システムで使用される環境変数で、動的リンカが共有ライブラリを検索するパスを指定します。プログラムが共有ライブラリをロードする際、まずこの環境変数で指定されたディレクトリを探し、次に標準のシステムディレクトリを探します。このコミットでは、カレントディレクトリ(.)を共有ライブラリの検索パスに追加することで、テストで生成された共有ライブラリを正しくロードできるようにしています。
  • gomake: Goプロジェクト内で使用されるMakefileを処理するためのツール、またはGoプロジェクトのビルドシステムを指すことがあります。この文脈では、Goのビルドプロセスを制御するためのコマンドとして使われています。gomake outはテスト用の実行ファイルをビルドし、gomake cleanはビルドによって生成された一時ファイルを削除するコマンドと推測されます。
  • シェルスクリプト (.bash): Unix系システムでコマンドを実行するためのスクリプト言語です。set -eは、スクリプト内でコマンドが失敗した場合(終了ステータスが0以外の場合)に即座にスクリプトを終了させる設定です。これにより、エラーが発生した際に不完全な状態での処理続行を防ぎます。
  • テストのクリーンアップ: テスト実行後に、テストによって生成された一時ファイルやディレクトリを削除し、テスト環境を元のクリーンな状態に戻すプロセスです。これは、テストの独立性と再現性を保証するために非常に重要です。

技術的詳細

このコミットの技術的な核心は、テストの実行とクリーンアップのロジックをsrc/run.bashからmisc/cgo/testso/test.bashという専用のシェルスクリプトに分離し、そのスクリプト内で完結させる点にあります。

変更前は、src/run.bashが直接misc/cgo/testsoディレクトリに移動し、gomake cleangomake outLD_LIBRARY_PATH=. ./outという一連のコマンドを実行していました。この方法では、./outの実行後にgomake cleanが明示的に呼び出されていませんでした。

変更後は、src/run.bashは単に./test.bashを呼び出すだけになります。新しく作成されたmisc/cgo/testso/test.bashスクリプトは以下の処理を行います。

  1. set -e: コマンドが失敗した場合にスクリプトを即座に終了させます。これにより、ビルドやテストの途中でエラーが発生した場合に、不完全な状態でのクリーンアップを防ぎます。
  2. gomake out: テストに必要な実行ファイル(out)をビルドします。
  3. LD_LIBRARY_PATH=. ./out: ビルドされた実行ファイルoutを実行します。この際、LD_LIBRARY_PATHをカレントディレクトリに設定することで、cgoによって生成された可能性のある共有ライブラリを正しくロードできるようにします。
  4. gomake clean: テスト実行後、gomake outによって生成されたファイル(outファイルなど)を削除し、テスト環境をクリーンな状態に戻します。

この変更により、テストの実行とクリーンアップがtest.bashスクリプト内でカプセル化され、run.bashからはそのスクリプトを呼び出すだけで済むようになりました。これにより、テストロジックの管理がより明確になり、特にクリーンアップ処理がテスト実行の不可欠な一部として保証されるようになりました。

コアとなるコードの変更箇所

このコミットでは、以下の2つのファイルが変更されています。

  1. misc/cgo/testso/test.bash (新規作成)
  2. src/run.bash (修正)

misc/cgo/testso/test.bash の追加内容:

#!/bin/sh
# Copyright 2011 The Go Authors.  All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

set -e
gomake out
LD_LIBRARY_PATH=. ./out
gomake clean

src/run.bash の変更内容:

--- a/src/run.bash
+++ b/src/run.bash
@@ -78,8 +78,7 @@ gotest
 [ "$GOHOSTOS" == darwin ] ||
 (xcd ../misc/cgo/testso
  gomake clean
-gomake out
-LD_LIBRARY_PATH=. ./out
+./test.bash
 ) || exit $?

コアとなるコードの解説

misc/cgo/testso/test.bash

  • #!/bin/sh: このスクリプトがsh(Bourne Shell)で実行されることを指定するShebang行です。
  • # Copyright ...: Goプロジェクトの標準的な著作権表示です。
  • set -e: このコマンドは、スクリプト内で実行される任意のコマンドが非ゼロの終了ステータスを返した場合(つまり、エラーが発生した場合)に、スクリプトの実行を即座に終了させることを意味します。これにより、テストのビルドや実行が失敗した場合に、不完全な状態での後続処理(特にクリーンアップ)を防ぎ、エラーを早期に検出できます。
  • gomake out: misc/cgo/testsoディレクトリ内のMakefileを読み込み、outターゲットを実行します。これは通常、テスト用の実行ファイルをビルドするコマンドです。
  • LD_LIBRARY_PATH=. ./out: ビルドされた実行ファイル./outを実行します。LD_LIBRARY_PATH=.は、実行時に共有ライブラリを検索するパスにカレントディレクトリ(.)を追加する環境変数の設定です。cgoを使用しているため、テスト対象のGoプログラムがCの共有ライブラリに依存している場合、この設定によってそのライブラリが正しく見つけられ、ロードされるようになります。
  • gomake clean: テスト実行後、misc/cgo/testsoディレクトリ内のMakefilecleanターゲットを実行します。これは、gomake outによって生成された一時ファイル(out実行ファイルや中間オブジェクトファイルなど)を削除し、テストディレクトリをクリーンな状態に戻すための重要なステップです。

src/run.bash

  • [ "$GOHOSTOS" == darwin ] ||: この行は、現在のホストOSがmacOS(darwin)でない場合に続くブロックを実行するという条件分岐です。cgo/testsoのテストは、特定のOSでのみ実行されるか、あるいはmacOSでは異なる挙動をする可能性があるため、このような条件が設けられています。
  • (xcd ../misc/cgo/testso ... ) || exit $?: xcdはGoプロジェクト内で定義されたカスタム関数で、ディレクトリを移動し、その後のコマンドをサブシェルで実行します。ここでは../misc/cgo/testsoディレクトリに移動しています。
    • gomake clean: 以前の実行で残された可能性のあるファイルを削除するために、テスト実行前に一度クリーンアップを行います。
    • -gomake out-LD_LIBRARY_PATH=. ./out: 変更前は、これらのコマンドがrun.bash内で直接実行されていました。
    • +./test.bash: 変更後、上記の2つのコマンドが削除され、代わりに新しく作成されたtest.bashスクリプトが呼び出されるようになりました。これにより、テストのビルド、実行、そしてクリーンアップのロジック全体がtest.bashに委譲され、run.bashはよりシンプルになりました。
  • || exit $?: サブシェル内のコマンドが失敗した場合(非ゼロの終了ステータスを返した場合)に、run.bashスクリプト全体もその終了ステータスで終了することを保証します。

この変更により、test.bashがテストのライフサイクル(ビルド、実行、クリーンアップ)を完全に管理するようになり、run.bashはテストの呼び出し元としての役割に徹するようになりました。特に、gomake cleanがテスト実行後に必ず呼び出されるようになったことで、テストによって生成された一時ファイルが残される問題が解決されました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (cgo, テストに関する情報)
  • Unix/Linux シェルスクリプトの一般的な知識 (set -e, 環境変数など)
  • Makefileの一般的な知識 (cleanターゲットなど)