はじめに
初めまして、株式会社アクロネット(中部事業所)の超若手エンジニアの河野と申します。
会社情報👈絶賛エンジニア募集中です!
AWS RDS(PostgreSQL)のバージョンを 12.9 から 15.9 へアップグレードしました。
この記事では、互換性問題により既存のテストケースでどのような修正を行ったかを、開発環境で行った検証のエピソードを中心に、記したいと思います。
結果として、修正後のテストは全てパスし、最終的に本番環境も無事 15.9 で運用できています。
アップグレードの流れとしては、まず Docker 上で PostgreSQL をアップグレードし、テストを実行。問題がなければ本番環境へ反映するという段階的なプロセスで進めました。
目次
1.問題のテストケース
func TestGetFogeId_Overflow(t *testing.T) {
maxValue := math.MaxFloat64
overflowMaxValue := maxValue * 10 // +Inf になる
tt := struct {
name string
fogeId float64
wantBody api.ResGetFogeInfo
}{
name: "異常系: 最大値+1桁 (Inf)",
fogeId: overflowMaxValue,
wantBody: api.ResGetFogeInfo{
FogeId: 0,
LatestShoriDate: "",
LatestShoriDatetime: parsedTimeNoData,
FogeFlg: "",
FogeyosokuInfo: nil,
ZenkaiFogeInfo: nil,
FogeShiyoryo: nil,
},
}
// API 実行
w, r := httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil)
a.GetFogeId(w, r, tt.fogeId)
// レスポンス検証
var got api.ResGetKyokyusetsubiInfo
decoder := json.NewDecoder(w.Body)
err := decoder.Decode(&got)
assert.Equal(t, tt.wantBody, got)
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
}
// testhelper.go
func DecodeBody(t *testing.T, r io.Reader, v any) {
decoder := json.NewDecoder(r)
err := decoder.Decode(&v)
assert.NilError(t, err)
}
2. 15.9にバージョンアップ後、GoテストでEOFエラーが発生
以下、EOFエラーのログ
## テスト実行
go test -v ./handler/
testhelper.go:68: init ok: testdata/[MASK]/case01/insert_test_data_1.sql
testhelper.go:65: try: testdata/[MASK]/case01/insert_test_data_2.sql
testhelper.go:68: init ok: testdata/[MASK]/case01/insert_test_data_2.sql
testhelper.go:71: complete init dataset
testhelper.go:247: assertion failed: error is not nil: EOF ## EOFエラー発生
testhelper.go:125: complete truncate all tables
Go の encoding/json は NaN / +Inf / -Inf を JSON にエンコードできない仕様になっている。
API (a.GetFogeId) がそのまま +Inf を struct に入れて json.Marshal しようとすると、エラー json: unsupported value: +Inf が発生する。
3. 結論、どう解決したか
func TestGetFogeId_Overflow(t *testing.T) {
maxValue := math.MaxFloat64
overflowMaxValue := maxValue * 10 // +Inf になる
tt := struct {
name string
fogeId float64
wantBody api.ResGetFogeInfo
wantLogs []string
invalidFogeId bool
}{
name: "異常系: 最大値+1桁 (Inf)",
fogeId: overflowMaxValue,
wantBody: api.ResGetFogeInfo{
FogeId: 0,
LatestShoriDate: "",
LatestShoriDatetime: parsedTimeNoData,
FogeFlg: "",
},
wantLogs: []string{"EOF"}, // 期待ログ
invalidFogeId: true, // EOF 検証用フラグ
}
// API 実行
w, r := httptest.NewRecorder(), httptest.NewRequest("GET", "/", nil)
a.GetFogeId(w, r, tt.fogeId)
// レスポンス検証
var got api.ResGetFogeInfo
if !tt.invalidFogeId {
// 正常系: JSON をデコードして中身を比較
testhelper.DecodeBody(t, w.Body, &got)
assert.Equal(t, tt.wantBody, got)
} else {
// 異常系: EOF が返ってくることを期待
decoder := json.NewDecoder(w.Body)
err := decoder.Decode(&got)
logger.Info().Msg("Response is empty (EOF detected)")
assert.Equal(t, tt.wantLogs[0], err.Error())
}
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
}