github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/api/v2/tso_test.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package v2 15 16 import ( 17 "bytes" 18 "context" 19 "encoding/json" 20 "net/http" 21 "net/http/httptest" 22 "testing" 23 "time" 24 25 "github.com/golang/mock/gomock" 26 mock_capture "github.com/pingcap/tiflow/cdc/capture/mock" 27 "github.com/pingcap/tiflow/cdc/model" 28 cerrors "github.com/pingcap/tiflow/pkg/errors" 29 "github.com/pingcap/tiflow/pkg/upstream" 30 "github.com/stretchr/testify/require" 31 "github.com/tikv/client-go/v2/oracle" 32 pd "github.com/tikv/pd/client" 33 ) 34 35 type mockPDClient4Tso struct { 36 pd.Client 37 err error 38 } 39 40 func (m *mockPDClient4Tso) GetTS(context.Context) (int64, int64, error) { 41 return oracle.GetPhysical(time.Now()), 0, m.err 42 } 43 44 func TestQueryTso(t *testing.T) { 45 t.Parallel() 46 47 mockPDClient := &mockPDClient4Tso{} 48 mockManager := upstream.NewManager4Test(mockPDClient) 49 50 queryTso := testCase{url: "/api/v2/tso", method: "POST"} 51 52 cp := mock_capture.NewMockCapture(gomock.NewController(t)) 53 helpers := NewMockAPIV2Helpers(gomock.NewController(t)) 54 cp.EXPECT().IsController().Return(true).AnyTimes() 55 cp.EXPECT().IsReady().Return(true).AnyTimes() 56 cp.EXPECT().GetUpstreamManager().Return(mockManager, nil).AnyTimes() 57 58 apiV2 := NewOpenAPIV2ForTest(cp, helpers) 59 router := newRouter(apiV2) 60 61 // case 1: json format mismatch 62 errUpConfig := struct { 63 ID string `json:"id"` // UpStream ID should be uint64 64 }{ID: "wrong-type"} 65 66 body, err := json.Marshal(&errUpConfig) 67 require.Nil(t, err) 68 w := httptest.NewRecorder() 69 req, _ := http.NewRequestWithContext(context.Background(), 70 queryTso.method, queryTso.url, bytes.NewReader(body)) 71 router.ServeHTTP(w, req) 72 require.Equal(t, http.StatusBadRequest, w.Code) 73 respErr := model.HTTPError{} 74 err = json.NewDecoder(w.Body).Decode(&respErr) 75 require.Nil(t, err) 76 require.Contains(t, respErr.Code, "ErrAPIInvalidParam") 77 78 // case 2: get tso failed 79 mockPDClient.err = cerrors.ErrAPIGetPDClientFailed 80 upConfig := struct { 81 ID uint64 `json:"id"` 82 }{ID: 0} 83 body, err = json.Marshal(&upConfig) 84 require.Nil(t, err) 85 86 w = httptest.NewRecorder() 87 req, _ = http.NewRequestWithContext(context.Background(), 88 queryTso.method, queryTso.url, bytes.NewReader(body)) 89 router.ServeHTTP(w, req) 90 require.Equal(t, http.StatusInternalServerError, w.Code) 91 respErr = model.HTTPError{} 92 err = json.NewDecoder(w.Body).Decode(&respErr) 93 require.Nil(t, err) 94 require.Contains(t, respErr.Code, "ErrInternalServerError") 95 96 // case3: success 97 mockPDClient.err = nil 98 w = httptest.NewRecorder() 99 req, _ = http.NewRequestWithContext(context.Background(), 100 queryTso.method, queryTso.url, bytes.NewReader(body)) 101 router.ServeHTTP(w, req) 102 resp := Tso{} 103 err = json.NewDecoder(w.Body).Decode(&resp) 104 require.Nil(t, err) 105 require.Equal(t, http.StatusOK, w.Code) 106 }