From 7ea075ce9e72b3b58cca2e62ef226a8d1297e1bf Mon Sep 17 00:00:00 2001 From: Yehor Butko Date: Thu, 19 Jul 2018 22:41:29 +0300 Subject: [PATCH] Unit Tests for logging.go added (#148) * Unit Tests for logging.go added. * Unit Tests for logging.go added part 2 * Unit tests added for Utils package --- pkg/telemetry/client.go | 6 +- pkg/telemetry/client_test.go | 138 +++++++++++++++++++++++++++++ pkg/telemetry/mock_Context_test.go | 83 +++++++++++++++++ pkg/telemetry/mock_client_test.go | 43 +++++++++ pkg/telemetry/server_test.go | 44 +++++++++ pkg/telemetry/utils_test.go | 20 +++++ pkg/utils/logging.go | 10 ++- pkg/utils/logging_test.go | 69 +++++++++++++++ 8 files changed, 409 insertions(+), 4 deletions(-) create mode 100644 pkg/telemetry/client_test.go create mode 100644 pkg/telemetry/mock_Context_test.go create mode 100644 pkg/telemetry/mock_client_test.go create mode 100644 pkg/telemetry/server_test.go create mode 100644 pkg/telemetry/utils_test.go create mode 100644 pkg/utils/logging_test.go diff --git a/pkg/telemetry/client.go b/pkg/telemetry/client.go index 39aa97414..9c77e9657 100644 --- a/pkg/telemetry/client.go +++ b/pkg/telemetry/client.go @@ -21,6 +21,10 @@ const ( // DefaultPacketSize sets the target packet size. MTUs are often 1500, // though a good argument could be made for 512 DefaultPacketSize = 1000 + + // DefaultApplication is the default values for application name. Should be used + // when value in ClientOpts.Application is not set and len(os.Args) == 0 + DefaultApplication = "unknown" ) // ClientOpts allows you to set Client Options @@ -69,7 +73,7 @@ func NewClient(remoteAddr string, opts ClientOpts) (rv *Client, err error) { opts.Application = os.Args[0] } else { // what the actual heck - opts.Application = "unknown" + opts.Application = DefaultApplication } } if opts.Instance == "" { diff --git a/pkg/telemetry/client_test.go b/pkg/telemetry/client_test.go new file mode 100644 index 000000000..6f83ec263 --- /dev/null +++ b/pkg/telemetry/client_test.go @@ -0,0 +1,138 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. +package telemetry + +import ( + "errors" + "os" + "testing" + + "github.com/stretchr/testify/assert" + monkit "gopkg.in/spacemonkeygo/monkit.v2" +) + +func TestNewClient_IntervalIsZero(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + defer s.Close() + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "testapp", + Instance: "testinst", + Interval: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, client.interval, DefaultInterval) +} + +func TestNewClient_ApplicationAndArgsAreEmpty(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + oldArgs := os.Args + + defer func() { + s.Close() + os.Args = oldArgs + }() + + os.Args = nil + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "", + Instance: "testinst", + Interval: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, DefaultApplication, client.opts.Application) +} + +func TestNewClient_ApplicationIsEmpty(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + defer s.Close() + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "", + Instance: "testinst", + Interval: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, client.opts.Application, os.Args[0]) +} + +func TestNewClient_InstanceIsEmpty(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + defer s.Close() + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "qwe", + Instance: "", + Interval: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, client.opts.InstanceId, []byte(DefaultInstanceID())) + assert.Equal(t, client.opts.Application, "qwe") + assert.Equal(t, client.interval, DefaultInterval) +} + +func TestNewClient_RegistryIsNil(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + defer s.Close() + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "qwe", + Instance: "", + Interval: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, client.opts.InstanceId, []byte(DefaultInstanceID())) + assert.Equal(t, client.opts.Application, "qwe") + assert.Equal(t, client.interval, DefaultInterval) + assert.Equal(t, client.opts.Registry, monkit.Default) +} + +func TestNewClient_PacketSizeIsZero(t *testing.T) { + s, err := Listen("127.0.0.1:0") + assert.NoError(t, err) + defer s.Close() + + client, err := NewClient(s.Addr(), ClientOpts{ + Application: "qwe", + Instance: "", + Interval: 0, + PacketSize: 0, + }) + + assert.NotNil(t, client) + + assert.Equal(t, client.opts.InstanceId, []byte(DefaultInstanceID())) + assert.Equal(t, client.opts.Application, "qwe") + assert.Equal(t, client.interval, DefaultInterval) + assert.Equal(t, client.opts.Registry, monkit.Default) + assert.Equal(t, client.opts.PacketSize, DefaultPacketSize) +} + +func TestRun_ReportNoCalled(t *testing.T) { + client := &MockClient{} + + ctx := &MockContext{} + + ctx.On("Err").Return(errors.New("")).Once() + client.On("Report").Times(0) + client.On("Run", ctx).Once() + client.Run(ctx) + + ctx.AssertExpectations(t) +} diff --git a/pkg/telemetry/mock_Context_test.go b/pkg/telemetry/mock_Context_test.go new file mode 100644 index 000000000..619432591 --- /dev/null +++ b/pkg/telemetry/mock_Context_test.go @@ -0,0 +1,83 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +// Code generated by mockery v1.0.0. DO NOT EDIT. +package telemetry + +import ( + "time" + + mock "github.com/stretchr/testify/mock" +) + +// MockContext is an autogenerated mock type for the Cont type +type MockContext struct { + mock.Mock +} + +// Deadline provides a mock function with given fields: +func (_m *MockContext) Deadline() (time.Time, bool) { + ret := _m.Called() + + var r0 time.Time + if rf, ok := ret.Get(0).(func() time.Time); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(time.Time) + } + + var r1 bool + if rf, ok := ret.Get(1).(func() bool); ok { + r1 = rf() + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + +// Done provides a mock function with given fields: +func (_m *MockContext) Done() <-chan struct{} { + ret := _m.Called() + + var r0 <-chan struct{} + if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan struct{}) + } + } + + return r0 +} + +// Err provides a mock function with given fields: +func (_m *MockContext) Err() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Value provides a mock function with given fields: key +func (_m *MockContext) Value(key interface{}) interface{} { + ret := _m.Called(key) + + var r0 interface{} + if rf, ok := ret.Get(0).(func(interface{}) interface{}); ok { + r0 = rf(key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + return r0 +} diff --git a/pkg/telemetry/mock_client_test.go b/pkg/telemetry/mock_client_test.go new file mode 100644 index 000000000..690023601 --- /dev/null +++ b/pkg/telemetry/mock_client_test.go @@ -0,0 +1,43 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +// Code generated by mockery v1.0.0. DO NOT EDIT. +package telemetry + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// MockClient is an autogenerated mock type for the client type +type MockClient struct { + mock.Mock + client Client +} + +// Report provides a mock function with given fields: ctx +func (_m *MockClient) Report(ctx context.Context) error { + ret := _m.Called(ctx) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Run provides a mock function with given fields: ctx +func (_m *MockClient) Run(ctx context.Context) { + client, _ := NewClient("", ClientOpts{ + Application: "qwe", + Instance: "", + Interval: 2, + PacketSize: 0, + }) + + client.Run(ctx) +} diff --git a/pkg/telemetry/server_test.go b/pkg/telemetry/server_test.go new file mode 100644 index 000000000..aaf9b2468 --- /dev/null +++ b/pkg/telemetry/server_test.go @@ -0,0 +1,44 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +package telemetry + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestListen_NilOnBadAddress(t *testing.T) { + server, errListen := Listen("11") + defer func() { + if server != nil { + server.Close() + } + }() + + assert.Nil(t, server) + assert.Error(t, errListen) +} + +func TestServe_ReturnErrorOnConnFail(t *testing.T) { + server, _ := Listen("127.0.0.1:0") + defer func() { + if server != nil && server.conn != nil { + server.Close() + } + }() + + server.conn.Close() + server.conn = nil + + errServe := server.Serve(nil, nil) + + assert.EqualError(t, errServe, "telemetry error: invalid conn: ") +} + +func TestListenAndServe_ReturnErrorOnListenFails(t *testing.T) { + err := ListenAndServe(nil, "1", nil) + + assert.Error(t, err) +} diff --git a/pkg/telemetry/utils_test.go b/pkg/telemetry/utils_test.go new file mode 100644 index 000000000..931280bf9 --- /dev/null +++ b/pkg/telemetry/utils_test.go @@ -0,0 +1,20 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +package telemetry + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestJitter_NegativeDuration(t *testing.T) { + duration := time.Duration(-1) + expected := time.Duration(1) + + actual := jitter(duration) + + assert.Equal(t, expected, actual) +} diff --git a/pkg/utils/logging.go b/pkg/utils/logging.go index 5549bfc1b..3f89fd23f 100644 --- a/pkg/utils/logging.go +++ b/pkg/utils/logging.go @@ -9,14 +9,18 @@ import ( "go.uber.org/zap" ) +var zapNewDevelopment = zap.NewDevelopment +var zapNewProduction = zap.NewProduction +var zapNewNop = zap.NewNop + // NewLogger takes an environment and a set of options for a logger func NewLogger(e string, options ...zap.Option) (*zap.Logger, error) { switch strings.ToLower(e) { case "dev", "development": - return zap.NewDevelopment(options...) + return zapNewDevelopment(options...) case "prod", "production": - return zap.NewProduction(options...) + return zapNewProduction(options...) } - return zap.NewNop(), nil + return zapNewNop(), nil } diff --git a/pkg/utils/logging_test.go b/pkg/utils/logging_test.go new file mode 100644 index 000000000..be7033e46 --- /dev/null +++ b/pkg/utils/logging_test.go @@ -0,0 +1,69 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +package utils + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap" +) + +var errExpected = errors.New("error with initializing logger") + +func TestNewLoggerDev(t *testing.T) { + oldZapNewDevelopment := zapNewDevelopment + + defer func() { zapNewDevelopment = oldZapNewDevelopment }() + + zapNewDevelopment = func(options ...zap.Option) (*zap.Logger, error) { + return nil, errExpected + } + + _, err := NewLogger("dev") + + assert.NotNil(t, err) + assert.Equal(t, err, errExpected) + + _, err = NewLogger("development") + + assert.NotNil(t, err) + assert.Equal(t, err, errExpected) +} + +func TestNewLoggerProd(t *testing.T) { + oldZapNewProduction := zapNewProduction + + defer func() { zapNewProduction = oldZapNewProduction }() + + zapNewProduction = func(options ...zap.Option) (*zap.Logger, error) { + return nil, errExpected + } + + _, err := NewLogger("prod") + + assert.NotNil(t, err) + assert.Equal(t, err, errExpected) + + _, err = NewLogger("production") + + assert.NotNil(t, err) + assert.Equal(t, err, errExpected) +} + +func TestNewLoggerDefault(t *testing.T) { + oldZapNewNop := zapNewNop + + defer func() { zapNewNop = oldZapNewNop }() + + zapNewNop = func() *zap.Logger { + return nil + } + + client, err := NewLogger("default") + + assert.Nil(t, client) + assert.Nil(t, err) +}