|
|
@@ -1,3 +1,17 @@
|
|
|
+// Copyright 2019 The etcd Authors
|
|
|
+//
|
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+// you may not use this file except in compliance with the License.
|
|
|
+// You may obtain a copy of the License at
|
|
|
+//
|
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+//
|
|
|
+// Unless required by applicable law or agreed to in writing, software
|
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+// See the License for the specific language governing permissions and
|
|
|
+// limitations under the License.
|
|
|
+
|
|
|
package traceutil
|
|
|
|
|
|
import (
|
|
|
@@ -7,8 +21,6 @@ import (
|
|
|
"io/ioutil"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
- "regexp"
|
|
|
- "strings"
|
|
|
"testing"
|
|
|
"time"
|
|
|
|
|
|
@@ -29,7 +41,7 @@ func TestGet(t *testing.T) {
|
|
|
},
|
|
|
{
|
|
|
name: "When the context has trace",
|
|
|
- inputCtx: context.WithValue(context.Background(), "trace", traceForTest),
|
|
|
+ inputCtx: context.WithValue(context.Background(), CtxKey, traceForTest),
|
|
|
outputTrace: traceForTest,
|
|
|
},
|
|
|
}
|
|
|
@@ -38,43 +50,10 @@ func TestGet(t *testing.T) {
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
trace := Get(tt.inputCtx)
|
|
|
if trace == nil {
|
|
|
- t.Errorf("Expected %v; Got nil\n", tt.outputTrace)
|
|
|
+ t.Errorf("Expected %v; Got nil", tt.outputTrace)
|
|
|
}
|
|
|
if trace.operation != tt.outputTrace.operation {
|
|
|
- t.Errorf("Expected %v; Got %v\n", tt.outputTrace, trace)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func TestGetOrCreate(t *testing.T) {
|
|
|
- tests := []struct {
|
|
|
- name string
|
|
|
- inputCtx context.Context
|
|
|
- outputTraceOp string
|
|
|
- }{
|
|
|
- {
|
|
|
- name: "When the context does not have trace",
|
|
|
- inputCtx: context.TODO(),
|
|
|
- outputTraceOp: "test",
|
|
|
- },
|
|
|
- {
|
|
|
- name: "When the context has trace",
|
|
|
- inputCtx: context.WithValue(context.Background(), "trace", &Trace{operation: "test"}),
|
|
|
- outputTraceOp: "test",
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- for _, tt := range tests {
|
|
|
- t.Run(tt.name, func(t *testing.T) {
|
|
|
- ctx, trace := GetOrCreate(tt.inputCtx, "test")
|
|
|
- if trace == nil {
|
|
|
- t.Errorf("Expected trace object; Got nil\n")
|
|
|
- } else if trace.operation != tt.outputTraceOp {
|
|
|
- t.Errorf("Expected %v; Got %v\n", tt.outputTraceOp, trace.operation)
|
|
|
- }
|
|
|
- if ctx.Value("trace") == nil {
|
|
|
- t.Errorf("Expected context has attached trace; Got nil\n")
|
|
|
+ t.Errorf("Expected %v; Got %v", tt.outputTrace, trace)
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
@@ -94,16 +73,16 @@ func TestCreate(t *testing.T) {
|
|
|
}
|
|
|
)
|
|
|
|
|
|
- trace := New(op, fields[0], fields[1])
|
|
|
+ trace := New(op, nil, fields[0], fields[1])
|
|
|
if trace.operation != op {
|
|
|
- t.Errorf("Expected %v; Got %v\n", op, trace.operation)
|
|
|
+ t.Errorf("Expected %v; Got %v", op, trace.operation)
|
|
|
}
|
|
|
for i, f := range trace.fields {
|
|
|
if f.Key != fields[i].Key {
|
|
|
- t.Errorf("Expected %v; Got %v\n", fields[i].Key, f.Key)
|
|
|
+ t.Errorf("Expected %v; Got %v", fields[i].Key, f.Key)
|
|
|
}
|
|
|
if f.Value != fields[i].Value {
|
|
|
- t.Errorf("Expected %v; Got %v\n", fields[i].Value, f.Value)
|
|
|
+ t.Errorf("Expected %v; Got %v", fields[i].Value, f.Value)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -113,67 +92,38 @@ func TestCreate(t *testing.T) {
|
|
|
|
|
|
for i, v := range trace.steps {
|
|
|
if steps[i] != v.msg {
|
|
|
- t.Errorf("Expected %v, got %v\n.", steps[i], v.msg)
|
|
|
+ t.Errorf("Expected %v; Got %v", steps[i], v.msg)
|
|
|
}
|
|
|
if stepFields[i].Key != v.fields[0].Key {
|
|
|
- t.Errorf("Expected %v; Got %v\n", stepFields[i].Key, v.fields[0].Key)
|
|
|
+ t.Errorf("Expected %v; Got %v", stepFields[i].Key, v.fields[0].Key)
|
|
|
}
|
|
|
if stepFields[i].Value != v.fields[0].Value {
|
|
|
- t.Errorf("Expected %v; Got %v\n", stepFields[i].Value, v.fields[0].Value)
|
|
|
+ t.Errorf("Expected %v; Got %v", stepFields[i].Value, v.fields[0].Value)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func TestLog(t *testing.T) {
|
|
|
- test := struct {
|
|
|
- name string
|
|
|
- trace *Trace
|
|
|
- expectedMsg []string
|
|
|
- }{
|
|
|
- name: "When dump all logs",
|
|
|
- trace: &Trace{
|
|
|
- operation: "Test",
|
|
|
- startTime: time.Now().Add(-100 * time.Millisecond),
|
|
|
- steps: []step{
|
|
|
- {time: time.Now().Add(-80 * time.Millisecond), msg: "msg1"},
|
|
|
- {time: time.Now().Add(-50 * time.Millisecond), msg: "msg2"},
|
|
|
- },
|
|
|
- },
|
|
|
- expectedMsg: []string{
|
|
|
- "msg1", "msg2",
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- t.Run(test.name, func(t *testing.T) {
|
|
|
- logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-%d", time.Now().UnixNano()))
|
|
|
- defer os.RemoveAll(logPath)
|
|
|
-
|
|
|
- lcfg := zap.NewProductionConfig()
|
|
|
- lcfg.OutputPaths = []string{logPath}
|
|
|
- lcfg.ErrorOutputPaths = []string{logPath}
|
|
|
- lg, _ := lcfg.Build()
|
|
|
-
|
|
|
- test.trace.Log(lg)
|
|
|
- data, err := ioutil.ReadFile(logPath)
|
|
|
- if err != nil {
|
|
|
- t.Fatal(err)
|
|
|
- }
|
|
|
-
|
|
|
- for _, msg := range test.expectedMsg {
|
|
|
- if !bytes.Contains(data, []byte(msg)) {
|
|
|
- t.Errorf("Expected to find %v in log.\n", msg)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-func TestTraceFormat(t *testing.T) {
|
|
|
tests := []struct {
|
|
|
name string
|
|
|
trace *Trace
|
|
|
fields []Field
|
|
|
expectedMsg []string
|
|
|
}{
|
|
|
+ {
|
|
|
+ name: "When dump all logs",
|
|
|
+ trace: &Trace{
|
|
|
+ operation: "Test",
|
|
|
+ startTime: time.Now().Add(-100 * time.Millisecond),
|
|
|
+ steps: []step{
|
|
|
+ {time: time.Now().Add(-80 * time.Millisecond), msg: "msg1"},
|
|
|
+ {time: time.Now().Add(-50 * time.Millisecond), msg: "msg2"},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ expectedMsg: []string{
|
|
|
+ "msg1", "msg2",
|
|
|
+ },
|
|
|
+ },
|
|
|
{
|
|
|
name: "When trace has fields",
|
|
|
trace: &Trace{
|
|
|
@@ -203,45 +153,31 @@ func TestTraceFormat(t *testing.T) {
|
|
|
"stepKey1:stepValue1", "stepKey2:stepValue2",
|
|
|
},
|
|
|
},
|
|
|
- {
|
|
|
- name: "When trace has no field",
|
|
|
- trace: &Trace{
|
|
|
- operation: "Test",
|
|
|
- startTime: time.Now().Add(-100 * time.Millisecond),
|
|
|
- steps: []step{
|
|
|
- {time: time.Now().Add(-80 * time.Millisecond), msg: "msg1"},
|
|
|
- {time: time.Now().Add(-50 * time.Millisecond), msg: "msg2"},
|
|
|
- },
|
|
|
- },
|
|
|
- fields: []Field{},
|
|
|
- expectedMsg: []string{
|
|
|
- "Test",
|
|
|
- "msg1", "msg2",
|
|
|
- },
|
|
|
- },
|
|
|
}
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
+ logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-%d", time.Now().UnixNano()))
|
|
|
+ defer os.RemoveAll(logPath)
|
|
|
+
|
|
|
+ lcfg := zap.NewProductionConfig()
|
|
|
+ lcfg.OutputPaths = []string{logPath}
|
|
|
+ lcfg.ErrorOutputPaths = []string{logPath}
|
|
|
+ lg, _ := lcfg.Build()
|
|
|
+
|
|
|
for _, f := range tt.fields {
|
|
|
tt.trace.AddField(f)
|
|
|
}
|
|
|
- s := tt.trace.format(0)
|
|
|
- var buf bytes.Buffer
|
|
|
- buf.WriteString(`Trace\[(\d*)?\](.+)\(duration(.+)start(.+)\)\n`)
|
|
|
- for range tt.trace.steps {
|
|
|
- buf.WriteString(`Trace\[(\d*)?\](.+)Step(.+)\(duration(.+)\)\n`)
|
|
|
+ tt.trace.lg = lg
|
|
|
+ tt.trace.Log()
|
|
|
+ data, err := ioutil.ReadFile(logPath)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
}
|
|
|
- buf.WriteString(`Trace\[(\d*)?\](.+)End(.+)\n`)
|
|
|
- pattern := buf.String()
|
|
|
|
|
|
- r, _ := regexp.Compile(pattern)
|
|
|
- if !r.MatchString(s) {
|
|
|
- t.Errorf("Wrong log format.\n")
|
|
|
- }
|
|
|
for _, msg := range tt.expectedMsg {
|
|
|
- if !strings.Contains(s, msg) {
|
|
|
- t.Errorf("Expected to find %v in log.\n", msg)
|
|
|
+ if !bytes.Contains(data, []byte(msg)) {
|
|
|
+ t.Errorf("Expected to find %v in log", msg)
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
@@ -310,14 +246,15 @@ func TestLogIfLong(t *testing.T) {
|
|
|
lcfg.ErrorOutputPaths = []string{logPath}
|
|
|
lg, _ := lcfg.Build()
|
|
|
|
|
|
- tt.trace.LogIfLong(tt.threshold, lg)
|
|
|
+ tt.trace.lg = lg
|
|
|
+ tt.trace.LogIfLong(tt.threshold)
|
|
|
data, err := ioutil.ReadFile(logPath)
|
|
|
if err != nil {
|
|
|
t.Fatal(err)
|
|
|
}
|
|
|
for _, msg := range tt.expectedMsg {
|
|
|
if !bytes.Contains(data, []byte(msg)) {
|
|
|
- t.Errorf("Expected to find %v in log\n", msg)
|
|
|
+ t.Errorf("Expected to find %v in log", msg)
|
|
|
}
|
|
|
}
|
|
|
})
|