| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package bundler |
| 6 |
| 7 import ( |
| 8 "fmt" |
| 9 "strings" |
| 10 "testing" |
| 11 "time" |
| 12 |
| 13 "github.com/luci/luci-go/common/logdog/protocol" |
| 14 . "github.com/smartystreets/goconvey/convey" |
| 15 ) |
| 16 |
| 17 type textTestCase struct { |
| 18 title string |
| 19 delimiter string |
| 20 source []string |
| 21 limit int |
| 22 increment time.Duration |
| 23 allowSplit bool |
| 24 closed bool |
| 25 out []textTestOutput |
| 26 } |
| 27 |
| 28 type textTestOutput struct { |
| 29 seq int64 |
| 30 lines []string |
| 31 increment time.Duration |
| 32 } |
| 33 |
| 34 func (o *textTestOutput) testLines() protocol.Text { |
| 35 t := protocol.Text{} |
| 36 for _, line := range o.lines { |
| 37 delim := "" |
| 38 switch { |
| 39 case strings.HasSuffix(line, windowsNewline): |
| 40 delim = windowsNewline |
| 41 case strings.HasSuffix(line, posixNewline): |
| 42 delim = posixNewline |
| 43 } |
| 44 |
| 45 t.Lines = append(t.Lines, &protocol.Text_Line{ |
| 46 Value: line[:len(line)-len(delim)], |
| 47 Delimiter: delim, |
| 48 }) |
| 49 } |
| 50 return t |
| 51 } |
| 52 |
| 53 func TestTextParser(t *testing.T) { |
| 54 Convey(`Using a parser test stream`, t, func() { |
| 55 s := &parserTestStream{ |
| 56 now: time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)
, |
| 57 prefixIndex: 1337, |
| 58 } |
| 59 |
| 60 for _, tst := range []textTestCase{ |
| 61 { |
| 62 title: `Standard parsing with funky newline.`, |
| 63 source: []string{"foo\nbar\r\nbaz\n"}, |
| 64 out: []textTestOutput{ |
| 65 {lines: []string{"foo\n", "bar\r\n", "ba
z\n"}}, |
| 66 }, |
| 67 }, |
| 68 |
| 69 { |
| 70 title: `Will not parse an undelimited line when
not truncating.`, |
| 71 source: []string{"foo\nbar\nbaz"}, |
| 72 out: []textTestOutput{ |
| 73 {lines: []string{"foo\n", "bar\n"}}, |
| 74 }, |
| 75 }, |
| 76 |
| 77 { |
| 78 title: `Will not parse dangling \r when tru
ncating but not closed.`, |
| 79 source: []string{"foo\r\nbar\r\nbaz\r"}, |
| 80 allowSplit: true, |
| 81 out: []textTestOutput{ |
| 82 {lines: []string{"foo\r\n", "bar\r\n", "
baz"}}, |
| 83 }, |
| 84 }, |
| 85 |
| 86 { |
| 87 title: `Will parse dangling \r when truncat
ing and closed.`, |
| 88 source: []string{"foo\r\nbar\r\nbaz\r"}, |
| 89 allowSplit: true, |
| 90 closed: true, |
| 91 out: []textTestOutput{ |
| 92 {lines: []string{"foo\r\n", "bar\r\n", "
baz\r"}}, |
| 93 }, |
| 94 }, |
| 95 |
| 96 { |
| 97 title: `Will not increase sequence for part
ial lines.`, |
| 98 source: []string{"foobar\rbaz\nq\nux"}, |
| 99 limit: 3, |
| 100 allowSplit: true, |
| 101 out: []textTestOutput{ |
| 102 {lines: []string{"foo"}}, |
| 103 {lines: []string{"bar"}}, |
| 104 {lines: []string{"\rba"}}, |
| 105 {lines: []string{"z\n", "q"}}, |
| 106 {seq: 1, lines: []string{"\n", "ux"}}, |
| 107 }, |
| 108 }, |
| 109 |
| 110 { |
| 111 title: `Will obey the limit if it yields a line
but truncates the next.`, |
| 112 source: []string{"foo\nbar\nbaz"}, |
| 113 limit: 5, |
| 114 out: []textTestOutput{ |
| 115 {lines: []string{"foo\n"}}, |
| 116 {seq: 1, lines: []string{"bar\n"}}, |
| 117 }, |
| 118 }, |
| 119 |
| 120 { |
| 121 title: `Can parse unicode strings.`, |
| 122 source: []string{"TEST©\r\n©\r\n©"}, |
| 123 allowSplit: true, |
| 124 closed: true, |
| 125 out: []textTestOutput{ |
| 126 {lines: []string{"TEST©\r\n", "©\r\n", "
©"}}, |
| 127 }, |
| 128 }, |
| 129 |
| 130 { |
| 131 title: `Unicode string with a split two-byt
e character should split across boundary.`, |
| 132 source: []string{"hA©\n"}, |
| 133 allowSplit: true, |
| 134 limit: 3, |
| 135 out: []textTestOutput{ |
| 136 {lines: []string{"hA"}}, |
| 137 {lines: []string{"©\n"}}, |
| 138 }, |
| 139 }, |
| 140 |
| 141 { |
| 142 title: `A two-byte Unicode glyph will retur
n nothing with a limit of 1.`, |
| 143 source: []string{"©\n"}, |
| 144 limit: 1, |
| 145 allowSplit: true, |
| 146 out: []textTestOutput{}, |
| 147 }, |
| 148 |
| 149 { |
| 150 title: `Multiple chunks with different times
tamps across newline boundaries`, |
| 151 source: []string{"fo", "o\nb", "ar\n", "baz\n
qux\n"}, |
| 152 increment: time.Second, |
| 153 out: []textTestOutput{ |
| 154 {seq: 0, lines: []string{"foo\n"}}, |
| 155 {seq: 1, lines: []string{"bar\n"}, incre
ment: time.Second}, |
| 156 {seq: 2, lines: []string{"baz\n", "qux\n
"}, increment: 2 * time.Second}, |
| 157 }, |
| 158 }, |
| 159 { |
| 160 title: `Will parse end of line when closed.
`, |
| 161 source: []string{"foo\nbar\nbaz"}, |
| 162 allowSplit: true, |
| 163 closed: true, |
| 164 out: []textTestOutput{ |
| 165 {lines: []string{"foo\n", "bar\n", "baz"
}}, |
| 166 }, |
| 167 }, |
| 168 |
| 169 { |
| 170 title: `Will parse empty lines from sequential
mixed-OS delimiters.`, |
| 171 source: []string{"\n\r\n\n\r\n\n\r\n\n\n\r\n\n\n
"}, |
| 172 limit: 8, |
| 173 out: []textTestOutput{ |
| 174 {lines: []string{"\n", "\r\n", "\n", "\r
\n", "\n"}}, |
| 175 {seq: 5, lines: []string{"\r\n", "\n", "
\n", "\r\n", "\n", "\n"}}, |
| 176 }, |
| 177 }, |
| 178 } { |
| 179 if tst.limit == 0 { |
| 180 tst.limit = 1024 |
| 181 } |
| 182 |
| 183 Convey(fmt.Sprintf(`Test case: %q`, tst.title), func() { |
| 184 p := &textParser{ |
| 185 baseParser: s.base(), |
| 186 } |
| 187 c := &constraints{ |
| 188 limit: tst.limit, |
| 189 } |
| 190 |
| 191 now := s.now |
| 192 aggregate := []byte{} |
| 193 for _, chunk := range tst.source { |
| 194 p.Append(dstr(now, chunk)) |
| 195 aggregate = append(aggregate, []byte(chu
nk)...) |
| 196 now = now.Add(tst.increment) |
| 197 } |
| 198 |
| 199 c.allowSplit = tst.allowSplit |
| 200 c.closed = tst.closed |
| 201 |
| 202 Convey(fmt.Sprintf(`Processes source %q.`, aggre
gate), func() { |
| 203 for _, o := range tst.out { |
| 204 le, err := p.nextEntry(c) |
| 205 So(err, ShouldBeNil) |
| 206 |
| 207 So(le, shouldMatchLogEntry, s.ad
d(o.increment).le(o.seq, o.testLines())) |
| 208 } |
| 209 |
| 210 le, err := p.nextEntry(c) |
| 211 So(err, ShouldBeNil) |
| 212 So(le, ShouldBeNil) |
| 213 }) |
| 214 }) |
| 215 } |
| 216 }) |
| 217 } |
| OLD | NEW |