mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-25 06:36:03 +03:00
tests, more docs
This commit is contained in:
parent
d233fd4cf1
commit
983dbe7229
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestAPIClientAdapter(t *testing.T) {
|
func TestAPIClientAdapter(t *testing.T) {
|
||||||
log := newJSONBufferedLogger()
|
log := newJSONBufferedLogger(nil)
|
||||||
client := retailcrm.New("https://example.com", "test_key").WithLogger(APIClientAdapter(log.Logger()))
|
client := retailcrm.New("https://example.com", "test_key").WithLogger(APIClientAdapter(log.Logger()))
|
||||||
client.Debug = true
|
client.Debug = true
|
||||||
|
|
||||||
|
155
core/logger/attrs_test.go
Normal file
155
core/logger/attrs_test.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestErr(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
source interface{}
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
source: nil,
|
||||||
|
expected: "<nil>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: errors.New("untimely error"),
|
||||||
|
expected: "untimely error",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
val := Err(c.source)
|
||||||
|
assert.Equal(t, c.expected, func() string {
|
||||||
|
if val.String != "" {
|
||||||
|
return val.String
|
||||||
|
}
|
||||||
|
if val.Interface != nil {
|
||||||
|
return fmt.Sprintf("%s", val.Interface)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}())
|
||||||
|
assert.Equal(t, ErrorAttr, val.Key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandler(t *testing.T) {
|
||||||
|
val := Handler("handlerName")
|
||||||
|
assert.Equal(t, HandlerAttr, val.Key)
|
||||||
|
assert.Equal(t, "handlerName", val.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPStatusCode(t *testing.T) {
|
||||||
|
val := HTTPStatusCode(http.StatusOK)
|
||||||
|
assert.Equal(t, HTTPStatusAttr, val.Key)
|
||||||
|
assert.Equal(t, http.StatusOK, int(val.Integer))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPStatusName(t *testing.T) {
|
||||||
|
val := HTTPStatusName(http.StatusOK)
|
||||||
|
assert.Equal(t, HTTPStatusNameAttr, val.Key)
|
||||||
|
assert.Equal(t, http.StatusText(http.StatusOK), val.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBody(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
input interface{}
|
||||||
|
result interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
input: "",
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: nil,
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "ooga booga",
|
||||||
|
result: "ooga booga",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `{"success":true}`,
|
||||||
|
result: map[string]interface{}{"success": true},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: []byte{},
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: nil,
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: []byte("ooga booga"),
|
||||||
|
result: "ooga booga",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: []byte(`{"success":true}`),
|
||||||
|
result: map[string]interface{}{"success": true},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: newReaderMock(func(p []byte) (n int, err error) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}),
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: newReaderMockData([]byte{}),
|
||||||
|
result: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: newReaderMockData([]byte("ooga booga")),
|
||||||
|
result: "ooga booga",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
input: newReaderMockData([]byte(`{"success":true}`)),
|
||||||
|
result: map[string]interface{}{"success": true},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
val := Body(c.input)
|
||||||
|
assert.Equal(t, BodyAttr, val.Key)
|
||||||
|
|
||||||
|
switch assertion := c.result.(type) {
|
||||||
|
case string:
|
||||||
|
assert.Equal(t, assertion, val.String)
|
||||||
|
case int:
|
||||||
|
assert.Equal(t, assertion, int(val.Integer))
|
||||||
|
default:
|
||||||
|
assert.Equal(t, c.result, val.Interface)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type readerMock struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func newReaderMock(cb func(p []byte) (n int, err error)) io.Reader {
|
||||||
|
r := &readerMock{}
|
||||||
|
r.On("Read", mock.Anything).Return(cb)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func newReaderMockData(data []byte) io.Reader {
|
||||||
|
return newReaderMock(bytes.NewReader(data).Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *readerMock) Read(p []byte) (n int, err error) {
|
||||||
|
args := m.Called(p)
|
||||||
|
out := args.Get(0)
|
||||||
|
if cb, ok := out.(func(p []byte) (n int, err error)); ok {
|
||||||
|
return cb(p)
|
||||||
|
}
|
||||||
|
return args.Int(0), args.Error(1)
|
||||||
|
}
|
@ -29,8 +29,10 @@ type jSONRecordScanner struct {
|
|||||||
buf *bufferLogger
|
buf *bufferLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func newJSONBufferedLogger() *jSONRecordScanner {
|
func newJSONBufferedLogger(buf *bufferLogger) *jSONRecordScanner {
|
||||||
buf := newBufferLogger()
|
if buf == nil {
|
||||||
|
buf = newBufferLogger()
|
||||||
|
}
|
||||||
return &jSONRecordScanner{scan: bufio.NewScanner(buf), buf: buf}
|
return &jSONRecordScanner{scan: bufio.NewScanner(buf), buf: buf}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
89
core/logger/default_test.go
Normal file
89
core/logger/default_test.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestDefaultSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefault(t *testing.T) {
|
||||||
|
suite.Run(t, new(TestDefaultSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestNewDefault_OK() {
|
||||||
|
jsonLog := NewDefault("json", false)
|
||||||
|
consoleLog := NewDefault("console", true)
|
||||||
|
|
||||||
|
s.Assert().NotNil(jsonLog)
|
||||||
|
s.Assert().NotNil(consoleLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestNewDefault_Panic() {
|
||||||
|
s.Assert().PanicsWithValue("unknown logger format: rar", func() {
|
||||||
|
NewDefault("rar", false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestWith() {
|
||||||
|
log := newBufferLogger()
|
||||||
|
log.With(zap.String(HandlerAttr, "Handler")).Info("test")
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(items, 1)
|
||||||
|
s.Assert().Equal("Handler", items[0].Handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestWithLazy() {
|
||||||
|
log := newBufferLogger()
|
||||||
|
log.WithLazy(zap.String(HandlerAttr, "Handler")).Info("test")
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(items, 1)
|
||||||
|
s.Assert().Equal("Handler", items[0].Handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestForHandler() {
|
||||||
|
log := newBufferLogger()
|
||||||
|
log.ForHandler("Handler").Info("test")
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(items, 1)
|
||||||
|
s.Assert().Equal("Handler", items[0].Handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestForConnection() {
|
||||||
|
log := newBufferLogger()
|
||||||
|
log.ForConnection("connection").Info("test")
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(items, 1)
|
||||||
|
s.Assert().Equal("connection", items[0].Connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestDefaultSuite) TestForAccount() {
|
||||||
|
log := newBufferLogger()
|
||||||
|
log.ForAccount("account").Info("test")
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(items, 1)
|
||||||
|
s.Assert().Equal("account", items[0].Account)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyZapFields(t *testing.T) {
|
||||||
|
fields := AnyZapFields([]interface{}{zap.String("k0", "v0"), "ooga", "booga"})
|
||||||
|
require.Len(t, fields, 3)
|
||||||
|
assert.Equal(t, zap.String("k0", "v0"), fields[0])
|
||||||
|
assert.Equal(t, zap.String("arg1", "ooga"), fields[1])
|
||||||
|
assert.Equal(t, zap.String("arg2", "booga"), fields[2])
|
||||||
|
}
|
37
core/logger/gin_test.go
Normal file
37
core/logger/gin_test.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGinMiddleware(t *testing.T) {
|
||||||
|
log := newBufferLogger()
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
r := gin.New()
|
||||||
|
r.Use(GinMiddleware(log))
|
||||||
|
r.GET("/mine", func(c *gin.Context) {
|
||||||
|
c.JSON(http.StatusOK, gin.H{})
|
||||||
|
})
|
||||||
|
r.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/mine", nil))
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusOK, rr.Code)
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 1)
|
||||||
|
require.NotEmpty(t, items[0].Context)
|
||||||
|
assert.NotEmpty(t, items[0].Context["startTime"])
|
||||||
|
assert.NotEmpty(t, items[0].Context["endTime"])
|
||||||
|
assert.True(t, func() bool {
|
||||||
|
_, ok := items[0].Context["latency"]
|
||||||
|
return ok
|
||||||
|
}())
|
||||||
|
assert.NotEmpty(t, items[0].Context["remoteAddress"])
|
||||||
|
assert.NotEmpty(t, items[0].Context[HTTPMethodAttr])
|
||||||
|
assert.NotEmpty(t, items[0].Context["path"])
|
||||||
|
assert.NotEmpty(t, items[0].Context["bodySize"])
|
||||||
|
}
|
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
func TestMGTransportClientAdapter(t *testing.T) {
|
func TestMGTransportClientAdapter(t *testing.T) {
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
log := newJSONBufferedLogger()
|
log := newJSONBufferedLogger(nil)
|
||||||
client := v1.NewWithClient("https://mg.dev", "test_token", httpClient).
|
client := v1.NewWithClient("https://mg.dev", "test_token", httpClient).
|
||||||
WithLogger(MGTransportClientAdapter(log.Logger()))
|
WithLogger(MGTransportClientAdapter(log.Logger()))
|
||||||
client.Debug = true
|
client.Debug = true
|
||||||
|
18
core/logger/pool_test.go
Normal file
18
core/logger/pool_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPool(t *testing.T) {
|
||||||
|
p := NewPool[*uint8](func() *uint8 {
|
||||||
|
item := uint8(22)
|
||||||
|
return &item
|
||||||
|
})
|
||||||
|
|
||||||
|
val := p.Get()
|
||||||
|
assert.Equal(t, uint8(22), *val)
|
||||||
|
assert.Equal(t, uint8(22), *p.Get())
|
||||||
|
p.Put(val)
|
||||||
|
}
|
24
core/logger/writer_adapter_test.go
Normal file
24
core/logger/writer_adapter_test.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWriterAdapter(t *testing.T) {
|
||||||
|
log := newBufferLogger()
|
||||||
|
adapter := WriterAdapter(log, zap.InfoLevel)
|
||||||
|
|
||||||
|
msg := []byte("hello world")
|
||||||
|
total, err := adapter.Write(msg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, total, len(msg))
|
||||||
|
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 1)
|
||||||
|
assert.Equal(t, "hello world", items[0].Message)
|
||||||
|
assert.Equal(t, "INFO", items[0].LevelName)
|
||||||
|
}
|
@ -13,10 +13,10 @@ type zabbixCollectorAdapter struct {
|
|||||||
func (a *zabbixCollectorAdapter) Errorf(format string, args ...interface{}) {
|
func (a *zabbixCollectorAdapter) Errorf(format string, args ...interface{}) {
|
||||||
baseMsg := "cannot send metrics to Zabbix"
|
baseMsg := "cannot send metrics to Zabbix"
|
||||||
switch format {
|
switch format {
|
||||||
case "cannot send metrics to Zabbix: %v":
|
|
||||||
baseMsg = "cannot stop collector"
|
|
||||||
fallthrough
|
|
||||||
case "cannot stop collector: %s":
|
case "cannot stop collector: %s":
|
||||||
|
baseMsg = "cannot stop Zabbix collector"
|
||||||
|
fallthrough
|
||||||
|
case "cannot send metrics to Zabbix: %v":
|
||||||
var err interface{}
|
var err interface{}
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
err = args[0]
|
err = args[0]
|
||||||
|
25
core/logger/zabbix_collector_adapter_test.go
Normal file
25
core/logger/zabbix_collector_adapter_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestZabbixCollectorAdapter(t *testing.T) {
|
||||||
|
log := newBufferLogger()
|
||||||
|
adapter := ZabbixCollectorAdapter(log)
|
||||||
|
adapter.Errorf("highly unexpected error: %s", "unexpected error")
|
||||||
|
adapter.Errorf("cannot stop collector: %s", "app error")
|
||||||
|
adapter.Errorf("cannot send metrics to Zabbix: %v", errors.New("send error"))
|
||||||
|
|
||||||
|
items, err := newJSONBufferedLogger(log).ScanAll()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, items, 3)
|
||||||
|
assert.Equal(t, "highly unexpected error: unexpected error", items[0].Message)
|
||||||
|
assert.Equal(t, "cannot stop Zabbix collector", items[1].Message)
|
||||||
|
assert.Equal(t, "app error", items[1].Context[ErrorAttr])
|
||||||
|
assert.Equal(t, "cannot send metrics to Zabbix", items[2].Message)
|
||||||
|
assert.Equal(t, "send error", items[2].Context[ErrorAttr])
|
||||||
|
}
|
@ -26,6 +26,16 @@ type BufferedLogger interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BufferLogger is an implementation of the BufferedLogger.
|
// BufferLogger is an implementation of the BufferedLogger.
|
||||||
|
//
|
||||||
|
// BufferLogger can be used in tests to match specific log messages. It uses JSON by default (hardcoded for now).
|
||||||
|
// It implements fmt.Stringer and provides an adapter to the underlying buffer, which means it can also return
|
||||||
|
// Bytes(), can be used like io.Reader and can be cleaned using Reset() method.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// log := NewBufferedLogger()
|
||||||
|
// // Some other code that works with logger.
|
||||||
|
// fmt.Println(log.String())
|
||||||
type BufferLogger struct {
|
type BufferLogger struct {
|
||||||
logger.Default
|
logger.Default
|
||||||
buf LockableBuffer
|
buf LockableBuffer
|
||||||
|
Loading…
Reference in New Issue
Block a user