From 00d4c68404893678bb35602f9c1d072193548c6d Mon Sep 17 00:00:00 2001 From: Lonng Date: Mon, 13 May 2019 16:35:03 +0800 Subject: [PATCH] common: improve unit test coverage of 'common' package (#186) --- lightning/common/util_test.go | 112 +++++++++++++++++++++++++++++++ lightning/common/version_test.go | 50 ++++++++++++++ lightning/log/log.go | 2 +- 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 lightning/common/util_test.go create mode 100644 lightning/common/version_test.go diff --git a/lightning/common/util_test.go b/lightning/common/util_test.go new file mode 100644 index 000000000..83dd85bb1 --- /dev/null +++ b/lightning/common/util_test.go @@ -0,0 +1,112 @@ +// Copyright 2019 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package common_test + +import ( + "context" + "encoding/json" + "io" + "net" + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-sql-driver/mysql" + . "github.com/pingcap/check" + tmysql "github.com/pingcap/parser/mysql" + "github.com/pingcap/tidb-lightning/lightning/common" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type utilSuite struct{} + +func TestUtil(t *testing.T) { + TestingT(t) +} + +var _ = Suite(&utilSuite{}) + +func (s *utilSuite) TestDirNotExist(c *C) { + c.Assert(common.IsDirExists("."), IsTrue) + c.Assert(common.IsDirExists("not-exists"), IsFalse) +} + +func (s *utilSuite) TestGetJSON(c *C) { + type TestPayload struct { + Username string `json:"username"` + Password string `json:"password"` + } + var request = TestPayload{ + Username: "lightning", + Password: "lightning-ctl", + } + + // Mock success response + handle := func(res http.ResponseWriter, req *http.Request) { + res.WriteHeader(http.StatusOK) + err := json.NewEncoder(res).Encode(request) + c.Assert(err, IsNil) + } + testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + handle(res, req) + })) + defer testServer.Close() + response := TestPayload{} + err := common.GetJSON(http.DefaultClient, "http://not-exists", &response) + c.Assert(err, NotNil) + err = common.GetJSON(http.DefaultClient, testServer.URL, &response) + c.Assert(err, IsNil) + c.Assert(request, DeepEquals, response) + + // Mock `StatusNoContent` response + handle = func(res http.ResponseWriter, req *http.Request) { + res.WriteHeader(http.StatusNoContent) + } + err = common.GetJSON(http.DefaultClient, testServer.URL, &response) + c.Assert(err, NotNil) + c.Assert(err, ErrorMatches, ".*http status code != 200.*") +} + +func (s *utilSuite) TestIsRetryableError(c *C) { + c.Assert(common.IsRetryableError(context.Canceled), IsFalse) + c.Assert(common.IsRetryableError(context.DeadlineExceeded), IsFalse) + c.Assert(common.IsRetryableError(io.EOF), IsFalse) + c.Assert(common.IsRetryableError(&net.AddrError{}), IsFalse) + c.Assert(common.IsRetryableError(&net.DNSError{}), IsFalse) + c.Assert(common.IsRetryableError(&net.DNSError{IsTimeout: true}), IsTrue) + + // MySQL Errors + c.Assert(common.IsRetryableError(&mysql.MySQLError{}), IsFalse) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrUnknown}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrLockDeadlock}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrPDServerTimeout}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrTiKVServerTimeout}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrTiKVServerBusy}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrResolveLockTimeout}), IsTrue) + c.Assert(common.IsRetryableError(&mysql.MySQLError{Number: tmysql.ErrRegionUnavailable}), IsTrue) + + // gRPC Errors + c.Assert(common.IsRetryableError(status.Error(codes.Canceled, "")), IsFalse) + c.Assert(common.IsRetryableError(status.Error(codes.Unknown, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.DeadlineExceeded, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.NotFound, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.AlreadyExists, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.PermissionDenied, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.ResourceExhausted, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.Aborted, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.OutOfRange, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.Unavailable, "")), IsTrue) + c.Assert(common.IsRetryableError(status.Error(codes.DataLoss, "")), IsTrue) +} diff --git a/lightning/common/version_test.go b/lightning/common/version_test.go new file mode 100644 index 000000000..e94e8d002 --- /dev/null +++ b/lightning/common/version_test.go @@ -0,0 +1,50 @@ +// Copyright 2019 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package common_test + +import ( + . "github.com/pingcap/check" + "github.com/pingcap/tidb-lightning/lightning/common" +) + +func (s *utilSuite) TestVersion(c *C) { + common.ReleaseVersion = "ReleaseVersion" + common.BuildTS = "BuildTS" + common.GitHash = "GitHash" + common.GitBranch = "GitBranch" + common.GoVersion = "GoVersion" + + version := common.GetRawInfo() + c.Assert(version, Equals, `Release Version: ReleaseVersion +Git Commit Hash: GitHash +Git Branch: GitBranch +UTC Build Time: BuildTS +Go Version: GoVersion +`) + common.PrintInfo("test", func() { + common.ReleaseVersion = "None" + common.BuildTS = "None" + common.GitHash = "None" + common.GitBranch = "None" + common.GoVersion = "None" + }) + + version = common.GetRawInfo() + c.Assert(version, Equals, `Release Version: None +Git Commit Hash: None +Git Branch: None +UTC Build Time: None +Go Version: None +`) +} diff --git a/lightning/log/log.go b/lightning/log/log.go index bc280630c..92d85c5bd 100644 --- a/lightning/log/log.go +++ b/lightning/log/log.go @@ -70,7 +70,7 @@ type Logger struct { // logger for lightning, different from tidb logger. var ( appLogger = Logger{zap.NewNop()} - appLevel zap.AtomicLevel + appLevel = zap.NewAtomicLevel() ) // InitLogger initializes Lightning's and also the TiDB library's loggers.