Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add more coverage tests #2

Merged
merged 9 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ jobs:

- name: Test
run: |
go test -v -cover ./... -coverprofile coverage.out -coverpkg ./...
go test -v -cover ./... -coverprofile coverage.out
go tool cover -func coverage.out -o coverage.out
- name: Go Coverage Badge
uses: tj-actions/coverage-badge-go@v1
if: ${{ runner.os == 'linux' }}
with:
green: 70
green: 80
filename: coverage.out

- uses: stefanzweifel/git-auto-commit-action@v5
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
<img src="https://github.com/aliexpressru/gomemcached/raw/main/assets/logo.png" width="300"/>

[![License](https://img.shields.io/github/license/gogf/gf.svg?style=flat)](https://github.com/aliexpressru/gomemcached)

[![Gomemcached](https://goreportcard.com/badge/github.com/aliexpressru/gomemcached)](https://goreportcard.com/report/github.com/aliexpressru/gomemcached)
[![Godoc](https://godoc.org/github.com/aliexpressru/gomemcached?status.svg)](https://pkg.go.dev/github.com/aliexpressru/gomemcached)
![Coverage](https://img.shields.io/badge/Coverage-69.8%25-yellow)

[![Tag](https://img.shields.io/github/v/tag/aliexpressru/gomemcached?color=%23ff8936&logo=fitbit&style=flat-square)](https://github.com/aliexpressru/gomemcached/tags)
![Coverage](https://img.shields.io/badge/Coverage-90.9%25-brightgreen)
</div>

___
Expand Down
28 changes: 28 additions & 0 deletions consistenthash/hashring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,34 @@ func TestHashRing_RemoveInterface(t *testing.T) {
assert.Equal(t, 2, node.(*mockNode).id)
}

func Test_innerRepr(t *testing.T) {
type args struct {
node any
}
tests := []struct {
name string
args args
want string
}{
{
name: "localhost:11211",
args: args{node: "localhost:11211"},
want: fmt.Sprintf("%d:%v", prime, "localhost:11211"),
},
{
name: "127.0.0.1:11211",
args: args{node: "127.0.0.1:11211"},
want: fmt.Sprintf("%d:%v", prime, "127.0.0.1:11211"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out := innerRepr(tt.args.node)
assert.Equal(t, tt.want, out, "innerRepr: returned wrong format")
})
}
}

func getKeysBeforeAndAfterFailure(t *testing.T, prefix string, index int) (map[int]string, map[int]string) {
ch := NewHashRing()
for i := 0; i < keySize; i++ {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.46.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.16.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
Expand All @@ -30,6 +31,12 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
Expand All @@ -49,5 +56,6 @@ google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
30 changes: 18 additions & 12 deletions logger/zap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package logger

import (
"os"
"sync/atomic"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
Expand All @@ -10,7 +11,7 @@ import (
var (
// global logger instance.
global *zap.SugaredLogger
disableLogger bool
disableLogger atomic.Bool
defaultLevel = zap.NewAtomicLevelAt(zap.DebugLevel)
generationArgs = []any{"@gen", "1"}
)
Expand All @@ -31,7 +32,12 @@ func GetLogger() *zap.SugaredLogger {

// DisableLogger turn off all logs, globally.
func DisableLogger() {
disableLogger = true
disableLogger.Store(true)
}

// LoggerIsDisable checks the status of the logger (true - disabled, false - enabled)
func LoggerIsDisable() bool {
return disableLogger.Load()
}

func newSugaredLogger(level zapcore.LevelEnabler, options ...zap.Option) *zap.SugaredLogger {
Expand Down Expand Up @@ -75,70 +81,70 @@ func capitalLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {

// Debug ...
func Debug(args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Debug(args...)
}
}

// Debugf ...
func Debugf(format string, args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Debugf(format, args...)
}
}

// Info ...
func Info(args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Info(args...)
}
}

// Infof ...
func Infof(format string, args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Infof(format, args...)
}
}

// Warn ...
func Warn(args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Warn(args...)
}
}

// Warnf ...
func Warnf(format string, args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Warnf(format, args...)
}
}

// Error ...
func Error(args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Error(args...)
}
}

// Errorf ...
func Errorf(format string, args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Errorf(format, args...)
}
}

// Fatal ...
func Fatal(args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Fatal(args...)
}
}

// Fatalf ...
func Fatalf(format string, args ...any) {
if log := GetLogger(); !disableLogger {
if log := GetLogger(); !LoggerIsDisable() {
log.Fatalf(format, args...)
}
}
12 changes: 12 additions & 0 deletions memcached/constants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ func TestOpCode_changeOnQuiet(t *testing.T) {
args: args{def: GETQ},
want: GETQ,
},
{
name: GETQ.String(),
o: GETQ,
args: args{def: GETQ},
want: GETQ,
},
{
name: "unknown opcode",
o: OpCode(0x1b),
args: args{def: GETQ},
want: GETQ,
},
{
name: SET.String(),
o: SET,
Expand Down
26 changes: 22 additions & 4 deletions memcached/memcached.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type (
// It is safe for unlocked use by multiple concurrent goroutines.
Client struct {
ctx context.Context
nw *network
cfg *config

// opaque - a unique identifier for the request, used to associate the request with its corresponding response.
Expand Down Expand Up @@ -114,6 +115,12 @@ type (
authData []byte
}

network struct {
dial func(network string, address string) (net.Conn, error)
dialTimeout func(network string, address string, timeout time.Duration) (net.Conn, error)
lookupHost func(host string) (addrs []string, err error)
}

config struct {
// HeadlessServiceAddress Headless service to lookup all the memcached ip addresses.
HeadlessServiceAddress string `envconfig:"MEMCACHED_HEADLESS_SERVICE_ADDRESS"`
Expand Down Expand Up @@ -151,6 +158,13 @@ func InitFromEnv(opts ...Option) (*Client, error) {
opt(op)
}

if op.Client.nw == nil {
op.Client.nw = &network{
dial: net.Dial,
dialTimeout: net.DialTimeout,
lookupHost: net.LookupHost,
}
}
if op.Client.hr == nil {
op.Client.hr = consistenthash.NewHashRing()
}
Expand Down Expand Up @@ -181,6 +195,11 @@ func newForTests(servers ...string) (*Client, error) {
opaque: new(uint32),
hr: hr,
disableMemcachedDiagnostic: true,
nw: &network{
dial: net.Dial,
dialTimeout: net.DialTimeout,
lookupHost: net.LookupHost,
},
}

return cm, nil
Expand All @@ -190,7 +209,7 @@ func newFromConfig(op *options) (*Client, error) {
if op.cfg != nil && !(op.cfg.HeadlessServiceAddress != "" || len(op.cfg.Servers) != 0) {
return nil, fmt.Errorf("%w, you must fill in either MEMCACHED_HEADLESS_SERVICE_ADDRESS or MEMCACHED_SERVERS", ErrNotConfigured)
}
nodes, err := getNodes(op.cfg)
nodes, err := getNodes(op.nw.lookupHost, op.cfg)
if err != nil {
return nil, fmt.Errorf("%w, %s", ErrInvalidAddr, err.Error())
}
Expand All @@ -208,7 +227,6 @@ func newFromConfig(op *options) (*Client, error) {
if !mc.disableNodeProvider {
mc.initNodesProvider()
}

return mc, nil
}

Expand Down Expand Up @@ -379,7 +397,7 @@ func (cte *ConnectTimeoutError) Error() string {

func (c *Client) dial(addr net.Addr) (net.Conn, error) {
if c.netTimeout() > 0 {
nc, err := net.DialTimeout(addr.Network(), addr.String(), c.netTimeout())
nc, err := c.nw.dialTimeout(addr.Network(), addr.String(), c.netTimeout())
if err != nil {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
Expand All @@ -389,7 +407,7 @@ func (c *Client) dial(addr net.Addr) (net.Conn, error) {
}
return nc, nil
}
return net.Dial(addr.Network(), addr.String())
return c.nw.dial(addr.Network(), addr.String())
}

func (c *Client) getConnForNode(node any) (*conn, error) {
Expand Down
Loading