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  }