Skip to content

Commit

Permalink
common: improve unit test coverage of 'common' package (pingcap#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
lonng authored May 13, 2019
1 parent 7bb11c2 commit 00d4c68
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 1 deletion.
112 changes: 112 additions & 0 deletions lightning/common/util_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
50 changes: 50 additions & 0 deletions lightning/common/version_test.go
Original file line number Diff line number Diff line change
@@ -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
`)
}
2 changes: 1 addition & 1 deletion lightning/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 00d4c68

Please sign in to comment.