@@ -11,131 +11,134 @@ import (
1111 "testing"
1212)
1313
14- func TestLineReader (t * testing.T ) {
15- type nextLine struct {
16- line string
17- incomplete bool // next call before this line should return incomplete
18- }
19- complete := func (s string ) nextLine {
20- return nextLine {line : s }
21- }
22- incomplete := func (s string ) nextLine {
23- return nextLine {line : s , incomplete : true }
24- }
14+ type nextLine struct {
15+ line string
16+ incomplete bool // next call before this line should return incomplete
17+ }
2518
26- const scratchSize = 8
19+ func complete (s string ) nextLine {
20+ return nextLine {line : s }
21+ }
22+ func incomplete (s string ) nextLine {
23+ return nextLine {line : s , incomplete : true }
24+ }
2725
28- tests := []struct {
29- name string
30- contents string
31- want []nextLine
32- }{
33- {
34- name : "empty" ,
35- contents : "" ,
36- },
37- {
38- name : "single" ,
39- contents : "1234\n " ,
40- want : []nextLine {
41- complete ("1234" ),
42- },
26+ const scratchSize = 8
27+
28+ var readerTests = []struct {
29+ name string
30+ contents string
31+ want []nextLine
32+ }{
33+ {
34+ name : "empty" ,
35+ contents : "" ,
36+ },
37+ {
38+ name : "single" ,
39+ contents : "1234\n " ,
40+ want : []nextLine {
41+ complete ("1234" ),
4342 },
44- {
45- name : "single-incomplete" ,
46- contents : "1234 " ,
47- want : [] nextLine {
48- incomplete ( "1234" ),
49- } ,
43+ },
44+ {
45+ name : "single-incomplete " ,
46+ contents : "1234" ,
47+ want : [] nextLine {
48+ incomplete ( "1234" ) ,
5049 },
51- {
52- name : "single-exact" ,
53- contents : "1234567 \n " ,
54- want : [] nextLine {
55- complete ( "1234567" ),
56- } ,
50+ },
51+ {
52+ name : "single-exact " ,
53+ contents : "1234567 \n " ,
54+ want : [] nextLine {
55+ complete ( "1234567" ) ,
5756 },
58- {
59- name : "single-exact-incomplete" ,
60- contents : "12345678 " ,
61- want : [] nextLine {
62- incomplete ( "12345678" ),
63- } ,
57+ },
58+ {
59+ name : "single-exact-incomplete " ,
60+ contents : "12345678" ,
61+ want : [] nextLine {
62+ incomplete ( "12345678" ) ,
6463 },
65- {
66- name : "multi" ,
67- contents : `1234
64+ },
65+ {
66+ name : "multi" ,
67+ contents : `1234
68685678
6969` ,
70- want : []nextLine {
71- complete ("1234" ),
72- complete ("5678" ),
73- },
70+ want : []nextLine {
71+ complete ("1234" ),
72+ complete ("5678" ),
7473 },
75- {
76- name : "multi-short" ,
77- contents : `12
74+ },
75+ {
76+ name : "multi-short" ,
77+ contents : `12
787834
797956
808078
8181` ,
82- want : []nextLine {
83- complete ("12" ),
84- complete ("34" ),
85- complete ("56" ),
86- complete ("78" ),
87- },
82+ want : []nextLine {
83+ complete ("12" ),
84+ complete ("34" ),
85+ complete ("56" ),
86+ complete ("78" ),
8887 },
89- {
90- name : "multi-notrailingnewline" ,
91- contents : `1234
88+ },
89+ {
90+ name : "multi-notrailingnewline" ,
91+ contents : `1234
92925678` ,
93- want : []nextLine {
94- complete ("1234" ),
95- incomplete ("5678" ),
96- },
93+ want : []nextLine {
94+ complete ("1234" ),
95+ incomplete ("5678" ),
9796 },
98- {
99- name : "middle-too-long" ,
100- contents : `1234
97+ },
98+ {
99+ name : "middle-too-long" ,
100+ contents : `1234
1011011234567890
1021025678
103103` ,
104- want : []nextLine {
105- complete ("1234" ),
106- incomplete ("12345678" ),
107- complete ("5678" ),
108- },
104+ want : []nextLine {
105+ complete ("1234" ),
106+ incomplete ("12345678" ),
107+ complete ("5678" ),
109108 },
110- {
111- // Multiple reads required to find newline.
112- name : "middle-way-too-long" ,
113- contents : `1234
109+ },
110+ {
111+ // Multiple reads required to find newline.
112+ name : "middle-way-too-long" ,
113+ contents : `1234
11411412345678900000000000000000000000000000000000000000000000000
1151155678
116116` ,
117- want : []nextLine {
118- complete ("1234" ),
119- incomplete ("12345678" ),
120- complete ("5678" ),
121- },
117+ want : []nextLine {
118+ complete ("1234" ),
119+ incomplete ("12345678" ),
120+ complete ("5678" ),
122121 },
122+ },
123+ }
124+
125+ func readString (contents string ) func (fd int , b []byte ) (int , uintptr ) {
126+ r := strings .NewReader (contents )
127+ return func (fd int , b []byte ) (int , uintptr ) {
128+ n , err := r .Read (b )
129+ if err != nil && err != io .EOF {
130+ const dummyErrno = 42
131+ return n , dummyErrno
132+ }
133+ return n , 0
123134 }
135+ }
124136
125- for _ , tc := range tests {
137+ func TestLineReader (t * testing.T ) {
138+ for _ , tc := range readerTests {
126139 t .Run (tc .name , func (t * testing.T ) {
127- r := strings .NewReader (tc .contents )
128- read := func (fd int , b []byte ) (int , uintptr ) {
129- n , err := r .Read (b )
130- if err != nil && err != io .EOF {
131- const dummyErrno = 42
132- return n , dummyErrno
133- }
134- return n , 0
135- }
136-
137140 var scratch [scratchSize ]byte
138- l := cgroup .NewLineReader (0 , scratch [:], read )
141+ l := cgroup .NewLineReader (0 , scratch [:], readString ( tc . contents ) )
139142
140143 var got []nextLine
141144 for {
@@ -168,3 +171,39 @@ func TestLineReader(t *testing.T) {
168171 })
169172 }
170173}
174+
175+ func FuzzLineReader (f * testing.F ) {
176+ for _ , tc := range readerTests {
177+ f .Add (tc .contents )
178+ }
179+ f .Fuzz (func (t * testing.T , input string ) {
180+ scratch := make ([]byte , scratchSize )
181+ reader := cgroup .NewLineReader (0 , scratch , readString (input ))
182+ for expected := range strings .Lines (input ) {
183+ err := reader .Next ()
184+ line := reader .Line ()
185+
186+ var expectedErr error
187+ if len (expected ) > scratchSize {
188+ expected = expected [:scratchSize ]
189+ expectedErr = cgroup .ErrIncompleteLine
190+ } else if expected [len (expected )- 1 ] == '\n' {
191+ expected = expected [:len (expected )- 1 ]
192+ } else {
193+ expectedErr = cgroup .ErrIncompleteLine
194+ }
195+
196+ if err != expectedErr {
197+ t .Fatalf ("got err %v, want %v" , err , expectedErr )
198+ }
199+
200+ if string (line ) != expected {
201+ t .Fatalf ("got %q, want %q" , string (line ), expected )
202+ }
203+ }
204+ err := reader .Next ()
205+ if err != cgroup .ErrEOF {
206+ t .Fatalf ("got %v, want EOF" , err )
207+ }
208+ })
209+ }
0 commit comments