Skip to content

Commit

Permalink
Utilize a mock PD service discovery during testing
Browse files Browse the repository at this point in the history
Signed-off-by: JmPotato <[email protected]>
  • Loading branch information
JmPotato committed Mar 6, 2024
1 parent 6a45734 commit 3e2afa8
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 13 deletions.
15 changes: 10 additions & 5 deletions client/http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ func NewClient(
}
sd := pd.NewDefaultPDServiceDiscovery(ctx, cancel, pdAddrs, c.inner.tlsConf)
if err := sd.Init(); err != nil {
log.Error("[pd] init service discovery failed", zap.String("source", source), zap.Strings("pd-addrs", pdAddrs), zap.Error(err))
log.Error("[pd] init service discovery failed",
zap.String("source", source), zap.Strings("pd-addrs", pdAddrs), zap.Error(err))

Check warning on line 309 in client/http/client.go

View check run for this annotation

Codecov / codecov/patch

client/http/client.go#L308-L309

Added lines #L308 - L309 were not covered by tests
return nil
}
c.inner.init(sd)
Expand Down Expand Up @@ -382,9 +383,8 @@ func NewHTTPClientWithRequestChecker(checker requestChecker) *http.Client {
}
}

// newClientWithoutInitServiceDiscovery creates a PD HTTP client
// with the given PD addresses and TLS config without init service discovery.
func newClientWithoutInitServiceDiscovery(
// newClientWithMockServiceDiscovery creates a new PD HTTP client with a mock PD service discovery.
func newClientWithMockServiceDiscovery(
source string,
pdAddrs []string,
opts ...ClientOption,
Expand All @@ -395,7 +395,12 @@ func newClientWithoutInitServiceDiscovery(
for _, opt := range opts {
opt(c)
}
sd := pd.NewDefaultPDServiceDiscovery(ctx, cancel, pdAddrs, c.inner.tlsConf)
sd := pd.NewMockPDServiceDiscovery(pdAddrs, c.inner.tlsConf)
if err := sd.Init(); err != nil {
log.Error("[pd] init mock service discovery failed",
zap.String("source", source), zap.Strings("pd-addrs", pdAddrs), zap.Error(err))
return nil

Check warning on line 402 in client/http/client.go

View check run for this annotation

Codecov / codecov/patch

client/http/client.go#L398-L402

Added lines #L398 - L402 were not covered by tests
}
c.inner.init(sd)
return c
}
18 changes: 12 additions & 6 deletions client/http/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

func TestPDAllowFollowerHandleHeader(t *testing.T) {
re := require.New(t)
checked := 0
httpClient := NewHTTPClientWithRequestChecker(func(req *http.Request) error {
var expectedVal string
if req.URL.Path == HotHistory {
Expand All @@ -38,16 +39,19 @@ func TestPDAllowFollowerHandleHeader(t *testing.T) {
re.Failf("PD allow follower handler header check failed",
"should be %s, but got %s", expectedVal, val)
}
checked++
return nil
})
c := newClientWithoutInitServiceDiscovery("test-header", []string{"http://127.0.0.1"}, WithHTTPClient(httpClient))
c := newClientWithMockServiceDiscovery("test-header", []string{"http://127.0.0.1"}, WithHTTPClient(httpClient))
defer c.Close()
c.GetRegions(context.Background())
c.GetHistoryHotRegions(context.Background(), &HistoryHotRegionsRequest{})
c.Close()
re.Equal(2, checked)
}

func TestCallerID(t *testing.T) {
re := require.New(t)
checked := 0
expectedVal := atomic.NewString(defaultCallerID)
httpClient := NewHTTPClientWithRequestChecker(func(req *http.Request) error {
val := req.Header.Get(xCallerIDKey)
Expand All @@ -56,20 +60,23 @@ func TestCallerID(t *testing.T) {
re.Failf("Caller ID header check failed",
"should be %s, but got %s", expectedVal, val)
}
checked++
return nil
})
c := newClientWithoutInitServiceDiscovery("test-caller-id", []string{"http://127.0.0.1"}, WithHTTPClient(httpClient))
c := newClientWithMockServiceDiscovery("test-caller-id", []string{"http://127.0.0.1"}, WithHTTPClient(httpClient))
defer c.Close()
c.GetRegions(context.Background())
expectedVal.Store("test")
c.WithCallerID(expectedVal.Load()).GetRegions(context.Background())
c.Close()
re.Equal(2, checked)
}

func TestWithBackoffer(t *testing.T) {
re := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c := newClientWithoutInitServiceDiscovery("test-with-backoffer", []string{"http://127.0.0.1"})
c := newClientWithMockServiceDiscovery("test-with-backoffer", []string{"http://127.0.0.1"})
defer c.Close()

base := 100 * time.Millisecond
max := 500 * time.Millisecond
Expand All @@ -88,5 +95,4 @@ func TestWithBackoffer(t *testing.T) {
_, err = c.WithBackoffer(bo).GetPDVersion(timeoutCtx)
re.InDelta(3*time.Second, time.Since(start), float64(250*time.Millisecond))
re.ErrorIs(err, context.DeadlineExceeded)
c.Close()
}
74 changes: 74 additions & 0 deletions client/mock_pd_service_discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2024 TiKV Project Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pd

import (
"crypto/tls"
"sync"

"google.golang.org/grpc"
)

var _ ServiceDiscovery = (*mockPDServiceDiscovery)(nil)

type mockPDServiceDiscovery struct {
urls []string
tlsCfg *tls.Config
clients []ServiceClient
}

// NewMockPDServiceDiscovery creates a mock PD service discovery.
func NewMockPDServiceDiscovery(urls []string, tlsCfg *tls.Config) *mockPDServiceDiscovery {
return &mockPDServiceDiscovery{
urls: urls,
tlsCfg: tlsCfg,

Check warning on line 36 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L34-L36

Added lines #L34 - L36 were not covered by tests
}
}

// Init directly creates the service clients with the given URLs.
func (m *mockPDServiceDiscovery) Init() error {
m.clients = make([]ServiceClient, 0, len(m.urls))

Check warning on line 42 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L42

Added line #L42 was not covered by tests
for _, url := range m.urls {
m.clients = append(m.clients, newPDServiceClient(url, url, m.tlsCfg, nil, false))

Check warning on line 44 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L44

Added line #L44 was not covered by tests
}
return nil

Check warning on line 46 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L46

Added line #L46 was not covered by tests
}

// Close clears the service clients.
func (m *mockPDServiceDiscovery) Close() {
clear(m.clients)

Check warning on line 51 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L51

Added line #L51 was not covered by tests
}

// GetAllServiceClients returns all service clients init in the mock PD service discovery.
func (m *mockPDServiceDiscovery) GetAllServiceClients() []ServiceClient {
return m.clients

Check warning on line 56 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L56

Added line #L56 was not covered by tests
}

func (m *mockPDServiceDiscovery) GetClusterID() uint64 { return 0 }
func (m *mockPDServiceDiscovery) GetKeyspaceID() uint32 { return 0 }
func (m *mockPDServiceDiscovery) GetKeyspaceGroupID() uint32 { return 0 }
func (m *mockPDServiceDiscovery) GetServiceURLs() []string { return nil }
func (m *mockPDServiceDiscovery) GetServingEndpointClientConn() *grpc.ClientConn { return nil }
func (m *mockPDServiceDiscovery) GetClientConns() *sync.Map { return nil }
func (m *mockPDServiceDiscovery) GetServingAddr() string { return "" }
func (m *mockPDServiceDiscovery) GetBackupAddrs() []string { return nil }
func (m *mockPDServiceDiscovery) GetServiceClient() ServiceClient { return nil }

Check warning on line 67 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L59-L67

Added lines #L59 - L67 were not covered by tests
func (m *mockPDServiceDiscovery) GetOrCreateGRPCConn(addr string) (*grpc.ClientConn, error) {
return nil, nil

Check warning on line 69 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L69

Added line #L69 was not covered by tests
}
func (m *mockPDServiceDiscovery) ScheduleCheckMemberChanged() {}
func (m *mockPDServiceDiscovery) CheckMemberChanged() error { return nil }
func (m *mockPDServiceDiscovery) AddServingAddrSwitchedCallback(callbacks ...func()) {}
func (m *mockPDServiceDiscovery) AddServiceAddrsSwitchedCallback(callbacks ...func()) {}

Check warning on line 74 in client/mock_pd_service_discovery.go

View check run for this annotation

Codecov / codecov/patch

client/mock_pd_service_discovery.go#L71-L74

Added lines #L71 - L74 were not covered by tests
6 changes: 4 additions & 2 deletions client/pd_service_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,10 @@ type tsoAllocatorEventSource interface {
SetTSOGlobalServAddrUpdatedCallback(callback tsoGlobalServAddrUpdatedFunc)
}

var _ ServiceDiscovery = (*pdServiceDiscovery)(nil)
var _ tsoAllocatorEventSource = (*pdServiceDiscovery)(nil)
var (
_ ServiceDiscovery = (*pdServiceDiscovery)(nil)
_ tsoAllocatorEventSource = (*pdServiceDiscovery)(nil)
)

// pdServiceDiscovery is the service discovery client of PD/API service which is quorum based
type pdServiceDiscovery struct {
Expand Down

0 comments on commit 3e2afa8

Please sign in to comment.