新增 pkg/mockwriter 用于测试其它使用 Writer 接口的代码

pull/2/head
q191201771 5 years ago
parent 1fb1a840b7
commit 23806813af

@ -19,11 +19,11 @@ func TestWriteTimeout(t *testing.T) {
go func() { go func() {
conn, _ := l.Accept() conn, _ := l.Accept()
defer conn.Close() defer conn.Close()
<- ch <-ch
}() }()
conn, err := net.Dial("tcp", ":10027") conn, err := net.Dial("tcp", ":10027")
c := New(conn, Config{ c := New(conn, Config{
WriteTimeoutMS:1000, WriteTimeoutMS: 1000,
}) })
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
b := make([]byte, 128) b := make([]byte, 128)

@ -47,9 +47,9 @@ const (
type Config struct { type Config struct {
Level Level `json:"level"` // 日志级别,大于等于该级别的日志才会被输出 Level Level `json:"level"` // 日志级别,大于等于该级别的日志才会被输出
// 文件输出和控制台输出可同时打开控制台输出主要用做开发时调试支持level彩色输出以及源码文件、行号
Filename string `json:"filename"` // 输出日志文件名,如果为空,则不写日志文件。可包含路径,路径不存在时,将自动创建 Filename string `json:"filename"` // 输出日志文件名,如果为空,则不写日志文件。可包含路径,路径不存在时,将自动创建
IsToStdout bool `json:"is_to_stdout"` // 是否以stdout输出到控制台 IsToStdout bool `json:"is_to_stdout"` // 是否以stdout输出到控制台
// 文件输出和控制台输出可同时打开控制台输出主要用做开发时调试支持level彩色输出以及源码文件、行号
RotateMByte int `json:"rotate_mbyte"` // 日志大小达到多少兆后翻滚如果为0则不翻滚 RotateMByte int `json:"rotate_mbyte"` // 日志大小达到多少兆后翻滚如果为0则不翻滚
} }
@ -175,7 +175,7 @@ func (l *logger) Outputf(level Level, calldepth int, format string, v ...interfa
msg := fmt.Sprintf(format, v...) msg := fmt.Sprintf(format, v...)
if l.stdoutLogger != nil { if l.stdoutLogger != nil {
l.stdoutLogger.Output(calldepth, levelToColorString[level]+msg) _ = l.stdoutLogger.Output(calldepth, levelToColorString[level]+msg)
} }
if l.fileLogger != nil { if l.fileLogger != nil {
if l.c.RotateMByte > 0 { if l.c.RotateMByte > 0 {
@ -187,14 +187,14 @@ func (l *logger) Outputf(level Level, calldepth int, format string, v ...interfa
if fi.Size() > int64(l.c.RotateMByte)*1024*1024 { if fi.Size() > int64(l.c.RotateMByte)*1024*1024 {
newFileName := l.c.Filename + "." + time.Now().Format("20060102150405") newFileName := l.c.Filename + "." + time.Now().Format("20060102150405")
if err := os.Rename(l.c.Filename, newFileName); err == nil { if err := os.Rename(l.c.Filename, newFileName); err == nil {
l.fp.Close() _ = l.fp.Close()
l.fp, _ = os.Create(l.c.Filename) l.fp, _ = os.Create(l.c.Filename)
l.fileLogger.SetOutput(l.fp) l.fileLogger.SetOutput(l.fp)
} }
} }
} }
} }
l.fileLogger.Output(calldepth, levelToString[level]+msg) _ = l.fileLogger.Output(calldepth, levelToString[level]+msg)
} }
} }
@ -205,7 +205,7 @@ func (l *logger) Output(level Level, calldepth int, v ...interface{}) {
msg := fmt.Sprint(v...) msg := fmt.Sprint(v...)
if l.stdoutLogger != nil { if l.stdoutLogger != nil {
l.stdoutLogger.Output(calldepth, levelToColorString[level]+msg) _ = l.stdoutLogger.Output(calldepth, levelToColorString[level]+msg)
} }
if l.fileLogger != nil { if l.fileLogger != nil {
if l.c.RotateMByte > 0 { if l.c.RotateMByte > 0 {
@ -217,14 +217,14 @@ func (l *logger) Output(level Level, calldepth int, v ...interface{}) {
if fi.Size() > int64(l.c.RotateMByte)*1024*1024 { if fi.Size() > int64(l.c.RotateMByte)*1024*1024 {
newFileName := l.c.Filename + "." + time.Now().Format("20060102150405") newFileName := l.c.Filename + "." + time.Now().Format("20060102150405")
if err := os.Rename(l.c.Filename, newFileName); err == nil { if err := os.Rename(l.c.Filename, newFileName); err == nil {
l.fp.Close() _ = l.fp.Close()
l.fp, _ = os.Create(l.c.Filename) l.fp, _ = os.Create(l.c.Filename)
l.fileLogger.SetOutput(l.fp) l.fileLogger.SetOutput(l.fp)
} }
} }
} }
} }
l.fileLogger.Output(calldepth, levelToString[level]+msg) _ = l.fileLogger.Output(calldepth, levelToString[level]+msg)
} }
} }

@ -6,9 +6,9 @@ import (
) )
type MockAcceptServer struct { type MockAcceptServer struct {
l net.Listener l net.Listener
conns []net.Conn conns []net.Conn
m sync.Mutex m sync.Mutex
} }
func (s *MockAcceptServer) Run(addr string) (err error) { func (s *MockAcceptServer) Run(addr string) (err error) {
@ -34,4 +34,3 @@ func (s *MockAcceptServer) Dispose() {
} }
s.m.Unlock() s.m.Unlock()
} }

@ -29,4 +29,4 @@ func (s *MockListenServer) Run(addr string) (err error) {
func (s *MockListenServer) Dispose() { func (s *MockListenServer) Dispose() {
_ = s.l.Close() _ = s.l.Close()
} }

@ -23,7 +23,7 @@ func TestMockAcceptServer(t *testing.T) {
var conns []net.Conn var conns []net.Conn
go s.Run(addr) go s.Run(addr)
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
c, err := net.DialTimeout("tcp", addr, time.Duration(1000) * time.Millisecond) c, err := net.DialTimeout("tcp", addr, time.Duration(1000)*time.Millisecond)
if err != nil { if err != nil {
break break
} }

@ -0,0 +1,58 @@
package mockwriter
import (
"bytes"
"errors"
)
// TODO chef: 可以添加一个接口,获取内部 buffer 的内容
type WriterType uint8
const (
WriterTypeDoNothing WriterType = iota
WriterTypeReturnError
WriterTypeIntoBuffer
)
var (
mockWriterErr = errors.New("mockwriter: a mock error")
)
type MockWriter struct {
t WriterType
ts map[uint32]WriterType
count uint32
b bytes.Buffer
}
func NewMockWriter(t WriterType) *MockWriter {
return &MockWriter{
t: t,
}
}
// 为某些写操作指定特定的类型,次数从 0 开始计数
func (w *MockWriter) SetSpecificType(ts map[uint32]WriterType) {
w.ts = ts
}
func (w *MockWriter) Write(b []byte) (int, error) {
t, exist := w.ts[w.count]
w.count++
if !exist {
t = w.t
}
switch t {
case WriterTypeDoNothing:
return len(b), nil
case WriterTypeReturnError:
return 0, mockWriterErr
//case WriterTypeIntoBuffer:
// return w.b.Write(b)
}
return w.b.Write(b)
//panic("never reach here.")
}

@ -0,0 +1,72 @@
package mockwriter
import (
"github.com/q191201771/nezha/pkg/assert"
"testing"
)
func TestNewMockWriter(t *testing.T) {
_ = NewMockWriter(WriterTypeDoNothing)
}
func TestMockWriter_Write(t *testing.T) {
var (
w *MockWriter
n int
err error
b = []byte("hello")
)
w = NewMockWriter(WriterTypeDoNothing)
n, err = w.Write(b)
assert.Equal(t, 5, n)
assert.Equal(t, nil, err)
w = NewMockWriter(WriterTypeReturnError)
n, err = w.Write(b)
assert.Equal(t, 0, n)
assert.Equal(t, mockWriterErr, err)
w = NewMockWriter(WriterTypeIntoBuffer)
n, err = w.Write(b)
assert.Equal(t, 5, n)
assert.Equal(t, nil, err)
}
func TestMockWriter_SetSpecificType(t *testing.T) {
var (
w *MockWriter
n int
err error
b = []byte("hello")
)
w = NewMockWriter(WriterTypeDoNothing)
w.SetSpecificType(map[uint32]WriterType{
0: WriterTypeReturnError,
2: WriterTypeReturnError,
4: WriterTypeDoNothing,
})
expectedLen := map[int]int{
0: 0,
1: 5,
2: 0,
3: 5,
4: 5,
5: 5,
}
expectedErr := map[int]error{
0: mockWriterErr,
1: nil,
2: mockWriterErr,
3: nil,
4: nil,
5: nil,
}
for i := 0; i < 6; i++ {
n, err = w.Write(b)
assert.Equal(t, expectedLen[i], n)
assert.Equal(t, expectedErr[i], err)
}
}
Loading…
Cancel
Save