github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/api/v2/capture_test.go (about)

     1  // Copyright 2023 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  	"context"
    18  	"encoding/json"
    19  	"net/http"
    20  	"net/http/httptest"
    21  	"testing"
    22  
    23  	"github.com/golang/mock/gomock"
    24  	mock_capture "github.com/pingcap/tiflow/cdc/capture/mock"
    25  	mock_controller "github.com/pingcap/tiflow/cdc/controller/mock"
    26  	"github.com/pingcap/tiflow/cdc/model"
    27  	"github.com/pingcap/tiflow/pkg/errors"
    28  	mock_etcd "github.com/pingcap/tiflow/pkg/etcd/mock"
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestListCaptures(t *testing.T) {
    33  	t.Parallel()
    34  
    35  	// case 1: get captures failed
    36  	{
    37  		ctrl := gomock.NewController(t)
    38  		cp := mock_capture.NewMockCapture(ctrl)
    39  		cp.EXPECT().IsReady().Return(true).AnyTimes()
    40  		cp.EXPECT().IsController().Return(true).AnyTimes()
    41  		statusProvider := mock_controller.NewMockController(ctrl)
    42  		cp.EXPECT().GetController().Return(statusProvider, nil)
    43  		statusProvider.EXPECT().GetCaptures(gomock.Any()).Return(nil, errors.New("fake"))
    44  
    45  		apiV2 := NewOpenAPIV2ForTest(cp, APIV2HelpersImpl{})
    46  		router := newRouter(apiV2)
    47  		w := httptest.NewRecorder()
    48  		req, _ := http.NewRequestWithContext(
    49  			context.Background(),
    50  			"GET",
    51  			"/api/v2/captures",
    52  			nil,
    53  		)
    54  		router.ServeHTTP(w, req)
    55  		respErr := model.HTTPError{}
    56  		err := json.NewDecoder(w.Body).Decode(&respErr)
    57  		require.Nil(t, err)
    58  		require.Contains(t, respErr.Error, "fake")
    59  		require.Equal(t, http.StatusInternalServerError, w.Code)
    60  	}
    61  
    62  	// case 2: capture Info failed.
    63  	{
    64  		ctrl := gomock.NewController(t)
    65  		cp := mock_capture.NewMockCapture(ctrl)
    66  		cp.EXPECT().IsReady().Return(true).AnyTimes()
    67  		cp.EXPECT().IsController().Return(true).AnyTimes()
    68  		statusProvider := mock_controller.NewMockController(ctrl)
    69  		cp.EXPECT().GetController().Return(statusProvider, nil)
    70  		statusProvider.EXPECT().GetCaptures(gomock.Any()).Return([]*model.CaptureInfo{}, nil)
    71  		cp.EXPECT().Info().Return(model.CaptureInfo{}, errors.New("fake info"))
    72  
    73  		apiV2 := NewOpenAPIV2ForTest(cp, APIV2HelpersImpl{})
    74  		router := newRouter(apiV2)
    75  		w := httptest.NewRecorder()
    76  		req, _ := http.NewRequestWithContext(
    77  			context.Background(),
    78  			"GET",
    79  			"/api/v2/captures",
    80  			nil,
    81  		)
    82  		router.ServeHTTP(w, req)
    83  		respErr := model.HTTPError{}
    84  		err := json.NewDecoder(w.Body).Decode(&respErr)
    85  		require.Nil(t, err)
    86  		require.Contains(t, respErr.Error, "fake info")
    87  		require.Equal(t, http.StatusInternalServerError, w.Code)
    88  	}
    89  
    90  	// case 3: success
    91  	{
    92  		ctrl := gomock.NewController(t)
    93  		cp := mock_capture.NewMockCapture(ctrl)
    94  		cp.EXPECT().IsReady().Return(true).AnyTimes()
    95  		cp.EXPECT().IsController().Return(true).AnyTimes()
    96  		statusProvider := mock_controller.NewMockController(ctrl)
    97  		cp.EXPECT().GetController().Return(statusProvider, nil)
    98  		statusProvider.EXPECT().GetCaptures(gomock.Any()).Return([]*model.CaptureInfo{
    99  			{
   100  				ID:            "owner-id",
   101  				AdvertiseAddr: "add1",
   102  			},
   103  			{
   104  				ID:            "capture-id",
   105  				AdvertiseAddr: "add2",
   106  			},
   107  		}, nil)
   108  		cp.EXPECT().Info().Return(model.CaptureInfo{
   109  			ID: "owner-id",
   110  		}, nil)
   111  		etcdClient := mock_etcd.NewMockCDCEtcdClient(ctrl)
   112  		etcdClient.EXPECT().GetClusterID().AnyTimes().Return("cdc-cluster-id")
   113  		cp.EXPECT().GetEtcdClient().AnyTimes().Return(etcdClient)
   114  
   115  		apiV2 := NewOpenAPIV2ForTest(cp, APIV2HelpersImpl{})
   116  		router := newRouter(apiV2)
   117  		w := httptest.NewRecorder()
   118  		req, _ := http.NewRequestWithContext(
   119  			context.Background(),
   120  			"GET",
   121  			"/api/v2/captures",
   122  			nil,
   123  		)
   124  		router.ServeHTTP(w, req)
   125  		respCaptures := &ListResponse[Capture]{}
   126  		err := json.NewDecoder(w.Body).Decode(&respCaptures)
   127  		require.Nil(t, err)
   128  		require.Equal(t, 2, respCaptures.Total)
   129  		require.Equal(t, 2, len(respCaptures.Items))
   130  		require.Equal(t, http.StatusOK, w.Code)
   131  		for _, item := range respCaptures.Items {
   132  			if item.ID == "owner-id" {
   133  				require.True(t, item.IsOwner)
   134  				require.Equal(t, "add1", item.AdvertiseAddr)
   135  				require.Equal(t, "cdc-cluster-id", item.ClusterID)
   136  			} else {
   137  				require.False(t, item.IsOwner)
   138  				require.Equal(t, "add2", item.AdvertiseAddr)
   139  				require.Equal(t, "cdc-cluster-id", item.ClusterID)
   140  			}
   141  		}
   142  	}
   143  }