trace_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package redis
  2. import (
  3. "context"
  4. "fmt"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "go-common/library/net/trace"
  8. )
  9. type mockTrace struct {
  10. tags []trace.Tag
  11. logs []trace.LogField
  12. perr *error
  13. operationName string
  14. finished bool
  15. }
  16. func (m *mockTrace) Fork(serviceName string, operationName string) trace.Trace {
  17. m.operationName = operationName
  18. return m
  19. }
  20. func (m *mockTrace) Follow(serviceName string, operationName string) trace.Trace {
  21. panic("not implemented")
  22. }
  23. func (m *mockTrace) Finish(err *error) {
  24. m.perr = err
  25. m.finished = true
  26. }
  27. func (m *mockTrace) SetTag(tags ...trace.Tag) trace.Trace {
  28. m.tags = append(m.tags, tags...)
  29. return m
  30. }
  31. func (m *mockTrace) SetLog(logs ...trace.LogField) trace.Trace {
  32. m.logs = append(m.logs, logs...)
  33. return m
  34. }
  35. func (m *mockTrace) Visit(fn func(k, v string)) {}
  36. func (m *mockTrace) SetTitle(title string) {}
  37. type mockConn struct{}
  38. func (c *mockConn) Close() error { return nil }
  39. func (c *mockConn) Err() error { return nil }
  40. func (c *mockConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
  41. return nil, nil
  42. }
  43. func (c *mockConn) Send(commandName string, args ...interface{}) error { return nil }
  44. func (c *mockConn) Flush() error { return nil }
  45. func (c *mockConn) Receive() (reply interface{}, err error) { return nil, nil }
  46. func (c *mockConn) WithContext(context.Context) Conn { return c }
  47. func TestTraceDo(t *testing.T) {
  48. tr := &mockTrace{}
  49. ctx := trace.NewContext(context.Background(), tr)
  50. tc := &traceConn{Conn: &mockConn{}}
  51. conn := tc.WithContext(ctx)
  52. conn.Do("GET", "test")
  53. assert.Equal(t, "Redis:GET", tr.operationName)
  54. assert.NotEmpty(t, tr.tags)
  55. assert.True(t, tr.finished)
  56. }
  57. func TestTraceDoErr(t *testing.T) {
  58. tr := &mockTrace{}
  59. ctx := trace.NewContext(context.Background(), tr)
  60. tc := &traceConn{Conn: MockErr{Error: fmt.Errorf("hhhhhhh")}}
  61. conn := tc.WithContext(ctx)
  62. conn.Do("GET", "test")
  63. assert.Equal(t, "Redis:GET", tr.operationName)
  64. assert.True(t, tr.finished)
  65. assert.NotNil(t, *tr.perr)
  66. }
  67. func TestTracePipeline(t *testing.T) {
  68. tr := &mockTrace{}
  69. ctx := trace.NewContext(context.Background(), tr)
  70. tc := &traceConn{Conn: &mockConn{}}
  71. conn := tc.WithContext(ctx)
  72. N := 2
  73. for i := 0; i < N; i++ {
  74. conn.Send("GET", "hello, world")
  75. }
  76. conn.Flush()
  77. for i := 0; i < N; i++ {
  78. conn.Receive()
  79. }
  80. assert.Equal(t, "Redis:Pipeline", tr.operationName)
  81. assert.NotEmpty(t, tr.tags)
  82. assert.NotEmpty(t, tr.logs)
  83. assert.True(t, tr.finished)
  84. }
  85. func TestTracePipelineErr(t *testing.T) {
  86. tr := &mockTrace{}
  87. ctx := trace.NewContext(context.Background(), tr)
  88. tc := &traceConn{Conn: MockErr{Error: fmt.Errorf("hahah")}}
  89. conn := tc.WithContext(ctx)
  90. N := 2
  91. for i := 0; i < N; i++ {
  92. conn.Send("GET", "hello, world")
  93. }
  94. conn.Flush()
  95. for i := 0; i < N; i++ {
  96. conn.Receive()
  97. }
  98. assert.Equal(t, "Redis:Pipeline", tr.operationName)
  99. assert.NotEmpty(t, tr.tags)
  100. assert.NotEmpty(t, tr.logs)
  101. assert.True(t, tr.finished)
  102. var isError bool
  103. for _, tag := range tr.tags {
  104. if tag.Key == "error" {
  105. isError = true
  106. }
  107. }
  108. assert.True(t, isError)
  109. }
  110. func TestSendStatement(t *testing.T) {
  111. tr := &mockTrace{}
  112. ctx := trace.NewContext(context.Background(), tr)
  113. tc := &traceConn{Conn: MockErr{Error: fmt.Errorf("hahah")}}
  114. conn := tc.WithContext(ctx)
  115. conn.Send("SET", "hello", "test")
  116. conn.Flush()
  117. conn.Receive()
  118. assert.Equal(t, "Redis:Pipeline", tr.operationName)
  119. assert.NotEmpty(t, tr.tags)
  120. assert.NotEmpty(t, tr.logs)
  121. assert.Equal(t, "event", tr.logs[0].Key)
  122. assert.Equal(t, "Send", tr.logs[0].Value)
  123. assert.Equal(t, "db.statement", tr.logs[1].Key)
  124. assert.Equal(t, "SET hello", tr.logs[1].Value)
  125. assert.True(t, tr.finished)
  126. var isError bool
  127. for _, tag := range tr.tags {
  128. if tag.Key == "error" {
  129. isError = true
  130. }
  131. }
  132. assert.True(t, isError)
  133. }
  134. func TestDoStatement(t *testing.T) {
  135. tr := &mockTrace{}
  136. ctx := trace.NewContext(context.Background(), tr)
  137. tc := &traceConn{Conn: MockErr{Error: fmt.Errorf("hahah")}}
  138. conn := tc.WithContext(ctx)
  139. conn.Do("SET", "hello", "test")
  140. assert.Equal(t, "Redis:SET", tr.operationName)
  141. assert.Equal(t, "SET hello", tr.tags[len(tr.tags)-1].Value)
  142. assert.True(t, tr.finished)
  143. }