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

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

本解説は、Go言語プロジェクトにおけるコミット 6154f146af47d8e9dcf717b3dc59120b1997d36e の詳細な分析を提供します。このコミットは、Goのテスト実行スクリプト test/run が一時ファイルを生成する際に、TMPDIR 環境変数を尊重するように変更を加えるものです。これにより、ユーザーが指定した一時ディレクトリにテスト関連のファイルが作成されるようになり、システムの柔軟性と管理性が向上します。

コミット

  • コミットハッシュ: 6154f146af47d8e9dcf717b3dc59120b1997d36e
  • Author: Shenghou Ma minux.ma@gmail.com
  • Date: Sat Feb 18 16:15:12 2012 -0500
  • コミットメッセージ:
    test/run: honor $TMPDIR
    
    R=golang-dev, rsc
    CC=golang-dev
    https://golang.org/cl/5676094
    

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

https://github.com/golang/go/commit/6154f146af47d8e9dcf717b3dc59120b1997d36e

元コミット内容

test/run: honor $TMPDIR

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5676094

変更の背景

このコミットが行われる以前、Go言語のテスト実行スクリプトである test/run は、テスト中に生成される一時ファイル(gorun-*, gotest1-*, gotest2-* など)の保存先として、常に /tmp ディレクトリをハードコードしていました。

しかし、多くのUnix系システムでは、ユーザーは一時ファイルの保存場所を TMPDIR 環境変数で指定することが一般的です。例えば、ディスク容量の制約がある場合、セキュリティ上の理由、あるいは単に一時ファイルを特定の場所にまとめたい場合など、/tmp 以外のディレクトリを使用したいというニーズがあります。

test/run スクリプトが TMPDIR を尊重しない場合、以下のような問題が発生する可能性がありました。

  1. ディスク容量の圧迫: /tmp ディレクトリが小さいパーティションにマウントされている場合、大量のテスト実行によってディスク容量が枯渇し、システム全体の動作に影響を与える可能性がありました。
  2. セキュリティ上の懸念: 特定の環境では、/tmp ディレクトリへの書き込みが制限されていたり、セキュリティポリシーによって特定のディレクトリのみが一時ファイル用として許可されていたりする場合があります。
  3. 管理の不便さ: ユーザーが一時ファイルを一元的に管理したい場合でも、test/run が生成するファイルだけが /tmp に散らばってしまうため、クリーンアップやデバッグが煩雑になることがありました。

このコミットは、これらの問題を解決し、Goのテスト環境がより柔軟で、ユーザーの環境設定に適合するようにするために導入されました。

前提知識の解説

1. TMPDIR 環境変数

TMPDIR は、Unix系オペレーティングシステムで広く使用される環境変数です。この変数は、プログラムが一時ファイルを保存するためのディレクトリのパスを指定するために用いられます。多くのアプリケーションやシステムユーティリティは、この TMPDIR の値を参照して一時ファイルの場所を決定します。

  • 設定例:
    export TMPDIR=/var/tmp/my_temp_dir
    
    この設定により、TMPDIR を尊重するプログラムは /var/tmp/my_temp_dir に一時ファイルを生成するようになります。
  • デフォルトの動作: TMPDIR が設定されていない場合、多くのシステムでは /tmp または /var/tmp がデフォルトの一時ディレクトリとして使用されます。

2. Go言語のテスト実行と test/run スクリプト

Go言語には、標準で強力なテストフレームワークが組み込まれています。通常、Goのテストは go test コマンドを使用して実行されます。しかし、Goプロジェクトのルートディレクトリには、より複雑なテストシナリオや、特定の環境設定を必要とするテストを実行するためのシェルスクリプトが存在することがあります。このコミットで変更された test/run は、Goプロジェクトのテストスイート全体を実行するための主要なスクリプトの一つであり、Goのビルドシステムやテストインフラストラクチャの一部として機能していました。

3. シェルスクリプトと変数展開

test/run はシェルスクリプト(おそらくBash)で書かれています。シェルスクリプトでは、環境変数やユーザー定義変数を参照して動的なパスや設定を構築することが一般的です。

このコミットで特に重要なのは、Bashなどのシェルで利用できるデフォルト値付き変数展開の構文です。

  • ${parameter:-word}: この構文は、「parameter が設定されていて、かつnullでない場合はその値を使用し、そうでない場合は word をデフォルト値として使用する」という意味を持ちます。 例: echo ${TMPDIR:-/tmp}
    • TMPDIR/home/user/temp に設定されている場合、出力は /home/user/temp
    • TMPDIR が設定されていない場合、出力は /tmp

この構文を使用することで、スクリプトは TMPDIR が設定されていればそれを優先し、設定されていなければ安全なデフォルト値(この場合は /tmp)にフォールバックすることができます。

技術的詳細

このコミットの技術的な核心は、test/run シェルスクリプト内で一時ファイルパスを定義している箇所を、ハードコードされた /tmp から TMPDIR 環境変数を尊重する形式に変更した点にあります。

具体的には、以下の3つの変数定義が変更されました。

  • RUNFILE
  • TMP1FILE
  • TMP2FILE

変更前は、これらの変数は直接 /tmp/ をプレフィックスとして使用していました。

RUNFILE="/tmp/gorun-$$USER"
TMP1FILE="/tmp/gotest1-$$USER"
TMP2FILE="/tmp/gotest2-$$USER"

変更後、これらの変数は ${TMPDIR:-/tmp}/ をプレフィックスとして使用するようになりました。

RUNFILE="${TMPDIR:-/tmp}/gorun-$$USER"
TMP1FILE="${TMPDIR:-/tmp}/gotest1-$$USER"
TMP2FILE="${TMPDIR:-/tmp}/gotest2-$$USER"

この変更により、スクリプトの実行時に TMPDIR 環境変数が設定されている場合、その値が一時ファイルのベースディレクトリとして使用されます。もし TMPDIR が設定されていない場合、${TMPDIR:-/tmp} の構文によって /tmp がデフォルト値として使用されるため、スクリプトの既存の動作が維持されます。

これは、シェルスクリプトにおける堅牢性と柔軟性を高めるための一般的なプラクティスであり、ユーザーの環境設定を尊重しつつ、スクリプトが常に機能することを保証します。

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

--- a/test/run
+++ b/test/run
@@ -36,9 +36,9 @@ PATH=${GOBIN:-$GOROOT/bin}:`pwd`:/bin:/usr/bin:/usr/local/bin
 # TODO: We add the tool directory to the PATH to avoid thinking about a better way.
 PATH="$GOTOOLDIR:$PATH"
 
-RUNFILE="/tmp/gorun-$$-$USER"
-TMP1FILE="/tmp/gotest1-$$-$USER"
-TMP2FILE="/tmp/gotest2-$$-$USER"
+RUNFILE="${TMPDIR:-/tmp}/gorun-$$-$USER"
+TMP1FILE="${TMPDIR:-/tmp}/gotest1-$$-$USER"
+TMP2FILE="${TMPDIR:-/tmp}/gotest2-$$-$USER"
 
 # don't run the machine out of memory: limit individual processes to 4GB.
 # on thresher, 3GB suffices to run the tests; with 2GB, peano fails.

コアとなるコードの解説

上記のdiffは、test/run スクリプトの3つの行に対する変更を示しています。

  • -RUNFILE="/tmp/gorun-$$-$USER": 変更前の行です。RUNFILE という変数が定義されており、その値は /tmp/gorun- に現在のプロセスのPID ($$) と現在のユーザー名 ($USER) を連結したものでした。これにより、一時的な実行ファイル名が /tmp ディレクトリ内に生成されていました。

  • +RUNFILE="${TMPDIR:-/tmp}/gorun-$$-$USER": 変更後の行です。/tmp の部分が ${TMPDIR:-/tmp} に置き換えられています。

    • $TMPDIR: TMPDIR 環境変数の値を参照します。
    • :-/tmp: これはBashのパラメータ展開の機能で、「もし TMPDIR が設定されていないか、または空文字列である場合、デフォルト値として /tmp を使用する」という意味です。 この変更により、RUNFILETMPDIR が設定されていればそのディレクトリに、設定されていなければ /tmp に生成されるようになります。

同様の変更が、TMP1FILETMP2FILE の定義にも適用されています。

  • -TMP1FILE="/tmp/gotest1-$$-$USER"

  • +TMP1FILE="${TMPDIR:-/tmp}/gotest1-$$-$USER"

  • -TMP2FILE="/tmp/gotest2-$$-$USER"

  • +TMP2FILE="${TMPDIR:-/tmp}/gotest2-$$-$USER"

これらの変更は、Goのテスト実行スクリプトが一時ファイルを生成する際のパス決定ロジックを、より柔軟で環境に依存しないものに改善しています。これにより、ユーザーは TMPDIR 環境変数を設定することで、テスト関連の一時ファイルの保存場所を自由に制御できるようになりました。

関連リンク

このコミットのコミットメッセージには https://golang.org/cl/5676094 というChange List (CL) へのリンクが含まれています。しかし、Web検索の結果、このCLは「cmd/go: add -C to 'go run'」というタイトルであり、本コミットの「test/run: honor $TMPDIR」という内容とは直接的に一致しないようです。これは、CLの番号が異なる変更を指しているか、あるいは本コミットがより大きな変更セットの一部であった可能性を示唆しています。

参考にした情報源リンク