0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go × PostgreSQL 15.9 で +Inf を扱ったらテストが落ちて、試行錯誤した話

Posted at

はじめに

初めまして、株式会社アクロネット(中部事業所)の超若手エンジニアの河野と申します。
会社情報👈絶賛エンジニア募集中です!

AWS RDS(PostgreSQL)のバージョンを 12.9 から 15.9 へアップグレードしました。
この記事では、互換性問題により既存のテストケースでどのような修正を行ったかを、開発環境で行った検証のエピソードを中心に、記したいと思います。
結果として、修正後のテストは全てパスし、最終的に本番環境も無事 15.9 で運用できています。
アップグレードの流れとしては、まず Docker 上で PostgreSQL をアップグレードし、テストを実行。問題がなければ本番環境へ反映するという段階的なプロセスで進めました。


目次

  1. 問題のテスト内容
  2. EOFエラーが発生
  3. 結論、どう解決したか

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)
}


0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?