Goのhttptestパッケージを使ってUNIX domain socketを使ったHTTPサーバのテストをする
Goが提供するHTTPのテストのためのユーティリティであるところのhttptestを使って、UNIX domain socketを使用するHTTPサーバのテストをするという内容についてのメモです。
import ( "log" "net" "net/http" "net/http/httptest" "os" "testing" ) func TestFoo(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) { _, err := w.Write([]byte("hello")) if err != nil { log.Printf("error: %s", err) w.WriteHeader(500) return } w.WriteHeader(200) }) tempSock, err := os.CreateTemp("", "sock") if err != nil { t.Fatal(err) } err = os.Remove(tempSock.Name()) if err != nil { t.Fatal(err) } listener, err := net.Listen("unix", tempSock.Name()) if err != nil { t.Fatal(err) } server := httptest.NewUnstartedServer(mux) server.Listener = listener server.Start() defer server.Close() // do something }
os.CreateTemp()
でtemporaryなファイルを作り、それを削除してファイル名だけを引っ張りつつ (削除せず実ファイルが残っているとbind(2)がEADDRINUSEを吐く)- それを
net.Listen()
に渡してlistenerを作り httptest.NewUnstartedServer()
でテスト用のサーバのインスタンスを作り- listenerをそのサーバのインスタンスに食わせ
- サーバスタート
- あとはUNIX domain socketを使ったクライアントを使ってテストを書く
という感じで使うことが可能です。簡単ですね。
もちろんtemp fileを使わずに任意のパスをソケットファイルとして与えても良い (server.Close()
が実行されるとそのソケットファイルも削除されるので) のですが、うっかりserver.Close()
が実行されないとゴミファイルが残ってしまったりしてダルいので、まあ保険のようなものです。