Browse code

Add test coverage to pkg/jsonlog

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Vincent Demeester authored on 2015/06/27 16:18:52
Showing 5 changed files
... ...
@@ -52,6 +52,17 @@
52 52
 //        buf.WriteString(`}`)
53 53
 //        return nil
54 54
 // }
55
+// @@ -81,9 +81,10 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
56
+//         if len(mj.Log) != 0 {
57
+// -                if first == true {
58
+// -                       first = false
59
+// -               } else {
60
+// -                       buf.WriteString(`,`)
61
+// -               }
62
+// +               first = false
63
+//                 buf.WriteString(`"log":`)
64
+//                 ffjson_WriteJsonString(buf, mj.Log)
65
+//         }
55 66
 
56 67
 package jsonlog
57 68
 
... ...
@@ -79,11 +90,7 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
79 79
 	)
80 80
 	buf.WriteString(`{`)
81 81
 	if len(mj.Log) != 0 {
82
-		if first == true {
83
-			first = false
84
-		} else {
85
-			buf.WriteString(`,`)
86
-		}
82
+		first = false
87 83
 		buf.WriteString(`"log":`)
88 84
 		ffjson_WriteJsonString(buf, mj.Log)
89 85
 	}
90 86
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+package jsonlog
1
+
2
+import (
3
+	"regexp"
4
+	"testing"
5
+)
6
+
7
+func TestJSONLogMarshalJSON(t *testing.T) {
8
+	logs := map[JSONLog]string{
9
+		JSONLog{Log: `"A log line with \\"`}:           `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":\".{20,}\"}$`,
10
+		JSONLog{Log: "A log line"}:                     `^{\"log\":\"A log line\",\"time\":\".{20,}\"}$`,
11
+		JSONLog{Log: "A log line with \r"}:             `^{\"log\":\"A log line with \\r\",\"time\":\".{20,}\"}$`,
12
+		JSONLog{Log: "A log line with & < >"}:          `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":\".{20,}\"}$`,
13
+		JSONLog{Log: "A log line with utf8 : 🚀 ψ ω β"}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":\".{20,}\"}$`,
14
+		JSONLog{Stream: "stdout"}:                      `^{\"stream\":\"stdout\",\"time\":\".{20,}\"}$`,
15
+		JSONLog{}:                                      `^{\"time\":\".{20,}\"}$`,
16
+		// These ones are a little weird
17
+		JSONLog{Log: "\u2028 \u2029"}:      `^{\"log\":\"\\u2028 \\u2029\",\"time\":\".{20,}\"}$`,
18
+		JSONLog{Log: string([]byte{0xaF})}: `^{\"log\":\"\\ufffd\",\"time\":\".{20,}\"}$`,
19
+		JSONLog{Log: string([]byte{0x7F})}: `^{\"log\":\"\x7f\",\"time\":\".{20,}\"}$`,
20
+	}
21
+	for jsonLog, expression := range logs {
22
+		data, err := jsonLog.MarshalJSON()
23
+		if err != nil {
24
+			t.Fatal(err)
25
+		}
26
+		res := string(data)
27
+		t.Logf("Result of WriteLog: %q", res)
28
+		logRe := regexp.MustCompile(expression)
29
+		if !logRe.MatchString(res) {
30
+			t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
31
+		}
32
+	}
33
+}
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"encoding/json"
6 6
 	"io/ioutil"
7 7
 	"regexp"
8
+	"strconv"
8 9
 	"strings"
9 10
 	"testing"
10 11
 	"time"
... ...
@@ -12,29 +13,123 @@ import (
12 12
 	"github.com/docker/docker/pkg/timeutils"
13 13
 )
14 14
 
15
-func TestWriteLog(t *testing.T) {
15
+// Invalid json should return an error
16
+func TestWriteLogWithInvalidJSON(t *testing.T) {
17
+	json := strings.NewReader("Invalid json")
18
+	w := bytes.NewBuffer(nil)
19
+	if err := WriteLog(json, w, "json", time.Time{}); err == nil {
20
+		t.Fatalf("Expected an error, got [%v]", w.String())
21
+	}
22
+}
23
+
24
+// Any format is valid, it will just print it
25
+func TestWriteLogWithInvalidFormat(t *testing.T) {
26
+	testLine := "Line that thinks that it is log line from docker\n"
16 27
 	var buf bytes.Buffer
17 28
 	e := json.NewEncoder(&buf)
29
+	for i := 0; i < 35; i++ {
30
+		e.Encode(JSONLog{Log: testLine, Stream: "stdout", Created: time.Now()})
31
+	}
32
+	w := bytes.NewBuffer(nil)
33
+	if err := WriteLog(&buf, w, "invalid format", time.Time{}); err != nil {
34
+		t.Fatal(err)
35
+	}
36
+	res := w.String()
37
+	t.Logf("Result of WriteLog: %q", res)
38
+	lines := strings.Split(strings.TrimSpace(res), "\n")
39
+	expression := "^invalid format Line that thinks that it is log line from docker$"
40
+	logRe := regexp.MustCompile(expression)
41
+	expectedLines := 35
42
+	if len(lines) != expectedLines {
43
+		t.Fatalf("Must be %v lines but got %d", expectedLines, len(lines))
44
+	}
45
+	for _, l := range lines {
46
+		if !logRe.MatchString(l) {
47
+			t.Fatalf("Log line not in expected format [%v]: %q", expression, l)
48
+		}
49
+	}
50
+}
51
+
52
+// Having multiple Log/Stream element
53
+func TestWriteLogWithMultipleStreamLog(t *testing.T) {
18 54
 	testLine := "Line that thinks that it is log line from docker\n"
19
-	for i := 0; i < 30; i++ {
55
+	var buf bytes.Buffer
56
+	e := json.NewEncoder(&buf)
57
+	for i := 0; i < 35; i++ {
20 58
 		e.Encode(JSONLog{Log: testLine, Stream: "stdout", Created: time.Now()})
21 59
 	}
22 60
 	w := bytes.NewBuffer(nil)
23
-	format := timeutils.RFC3339NanoFixed
24
-	if err := WriteLog(&buf, w, format, time.Time{}); err != nil {
61
+	if err := WriteLog(&buf, w, "invalid format", time.Time{}); err != nil {
25 62
 		t.Fatal(err)
26 63
 	}
27 64
 	res := w.String()
28 65
 	t.Logf("Result of WriteLog: %q", res)
29 66
 	lines := strings.Split(strings.TrimSpace(res), "\n")
30
-	if len(lines) != 30 {
31
-		t.Fatalf("Must be 30 lines but got %d", len(lines))
67
+	expression := "^invalid format Line that thinks that it is log line from docker$"
68
+	logRe := regexp.MustCompile(expression)
69
+	expectedLines := 35
70
+	if len(lines) != expectedLines {
71
+		t.Fatalf("Must be %v lines but got %d", expectedLines, len(lines))
32 72
 	}
33
-	// 30+ symbols, five more can come from system timezone
34
-	logRe := regexp.MustCompile(`.{30,} Line that thinks that it is log line from docker`)
35 73
 	for _, l := range lines {
36 74
 		if !logRe.MatchString(l) {
37
-			t.Fatalf("Log line not in expected format: %q", l)
75
+			t.Fatalf("Log line not in expected format [%v]: %q", expression, l)
76
+		}
77
+	}
78
+}
79
+
80
+// Write log with since after created, it won't print anything
81
+func TestWriteLogWithDate(t *testing.T) {
82
+	created, _ := time.Parse("YYYY-MM-dd", "2015-01-01")
83
+	var buf bytes.Buffer
84
+	testLine := "Line that thinks that it is log line from docker\n"
85
+	jsonLog := JSONLog{Log: testLine, Stream: "stdout", Created: created}
86
+	if err := json.NewEncoder(&buf).Encode(jsonLog); err != nil {
87
+		t.Fatal(err)
88
+	}
89
+	w := bytes.NewBuffer(nil)
90
+	if err := WriteLog(&buf, w, "json", time.Now()); err != nil {
91
+		t.Fatal(err)
92
+	}
93
+	res := w.String()
94
+	if res != "" {
95
+		t.Fatalf("Expected empty log, got [%v]", res)
96
+	}
97
+}
98
+
99
+// Happy path :)
100
+func TestWriteLog(t *testing.T) {
101
+	testLine := "Line that thinks that it is log line from docker\n"
102
+	format := timeutils.RFC3339NanoFixed
103
+	logs := map[string][]string{
104
+		"":     {"35", "^Line that thinks that it is log line from docker$"},
105
+		"json": {"1", `^{\"log\":\"Line that thinks that it is log line from docker\\n\",\"stream\":\"stdout\",\"time\":.{30,}\"}$`},
106
+		// 30+ symbols, five more can come from system timezone
107
+		format: {"35", `.{30,} Line that thinks that it is log line from docker`},
108
+	}
109
+	for givenFormat, expressionAndLines := range logs {
110
+		expectedLines, _ := strconv.Atoi(expressionAndLines[0])
111
+		expression := expressionAndLines[1]
112
+		var buf bytes.Buffer
113
+		e := json.NewEncoder(&buf)
114
+		for i := 0; i < 35; i++ {
115
+			e.Encode(JSONLog{Log: testLine, Stream: "stdout", Created: time.Now()})
116
+		}
117
+		w := bytes.NewBuffer(nil)
118
+		if err := WriteLog(&buf, w, givenFormat, time.Time{}); err != nil {
119
+			t.Fatal(err)
120
+		}
121
+		res := w.String()
122
+		t.Logf("Result of WriteLog: %q", res)
123
+		lines := strings.Split(strings.TrimSpace(res), "\n")
124
+		if len(lines) != expectedLines {
125
+			t.Fatalf("Must be %v lines but got %d", expectedLines, len(lines))
126
+		}
127
+		logRe := regexp.MustCompile(expression)
128
+		for _, l := range lines {
129
+			if !logRe.MatchString(l) {
130
+				t.Fatalf("Log line not in expected format [%v]: %q", expression, l)
131
+			}
38 132
 		}
39 133
 	}
40 134
 }
... ...
@@ -21,11 +21,7 @@ func (mj *JSONLogBytes) MarshalJSONBuf(buf *bytes.Buffer) error {
21 21
 
22 22
 	buf.WriteString(`{`)
23 23
 	if len(mj.Log) != 0 {
24
-		if first == true {
25
-			first = false
26
-		} else {
27
-			buf.WriteString(`,`)
28
-		}
24
+		first = false
29 25
 		buf.WriteString(`"log":`)
30 26
 		ffjson_WriteJsonBytesAsString(buf, mj.Log)
31 27
 	}
32 28
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+package jsonlog
1
+
2
+import (
3
+	"bytes"
4
+	"regexp"
5
+	"testing"
6
+)
7
+
8
+func TestJSONLogBytesMarshalJSONBuf(t *testing.T) {
9
+	logs := map[*JSONLogBytes]string{
10
+		&JSONLogBytes{Log: []byte(`"A log line with \\"`)}:           `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":}$`,
11
+		&JSONLogBytes{Log: []byte("A log line")}:                     `^{\"log\":\"A log line\",\"time\":}$`,
12
+		&JSONLogBytes{Log: []byte("A log line with \r")}:             `^{\"log\":\"A log line with \\r\",\"time\":}$`,
13
+		&JSONLogBytes{Log: []byte("A log line with & < >")}:          `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":}$`,
14
+		&JSONLogBytes{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":}$`,
15
+		&JSONLogBytes{Stream: "stdout"}:                              `^{\"stream\":\"stdout\",\"time\":}$`,
16
+		&JSONLogBytes{Stream: "stdout", Log: []byte("A log line")}:   `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":}$`,
17
+		&JSONLogBytes{Created: "time"}:                               `^{\"time\":time}$`,
18
+		&JSONLogBytes{}:                                              `^{\"time\":}$`,
19
+		// These ones are a little weird
20
+		&JSONLogBytes{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":}$`,
21
+		&JSONLogBytes{Log: []byte{0xaF}}:            `^{\"log\":\"\\ufffd\",\"time\":}$`,
22
+		&JSONLogBytes{Log: []byte{0x7F}}:            `^{\"log\":\"\x7f\",\"time\":}$`,
23
+	}
24
+	for jsonLog, expression := range logs {
25
+		var buf bytes.Buffer
26
+		if err := jsonLog.MarshalJSONBuf(&buf); err != nil {
27
+			t.Fatal(err)
28
+		}
29
+		res := buf.String()
30
+		t.Logf("Result of WriteLog: %q", res)
31
+		logRe := regexp.MustCompile(expression)
32
+		if !logRe.MatchString(res) {
33
+			t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
34
+		}
35
+	}
36
+}