Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: logdog/client/coordinator/stream_test.go

Issue 2341113002: Update Coordinator client, add datagram assembly. (Closed)
Patch Set: Remove outdated Milo warning message. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package coordinator 5 package coordinator
6 6
7 import ( 7 import (
8 "errors" 8 "errors"
9 "testing" 9 "testing"
10 10
(...skipping 15 matching lines...) Expand all
26 Content: &logpb.LogEntry_Text{ 26 Content: &logpb.LogEntry_Text{
27 Text: &logpb.Text{ 27 Text: &logpb.Text{
28 Lines: []*logpb.Text_Line{ 28 Lines: []*logpb.Text_Line{
29 {Value: id}, 29 {Value: id},
30 }, 30 },
31 }, 31 },
32 }, 32 },
33 } 33 }
34 } 34 }
35 35
36 func genDG(idx int64, content ...string) []*logpb.LogEntry {
37 var contentSize uint64
38 if len(content) > 1 {
39 for _, c := range content {
40 contentSize += uint64(len(c))
41 }
42 }
43
44 logs := make([]*logpb.LogEntry, len(content))
45 for i, c := range content {
46 dg := logpb.Datagram{
47 Data: []byte(c),
48 }
49 if len(content) > 1 {
50 dg.Partial = &logpb.Datagram_Partial{
51 Index: uint32(i),
52 Size: contentSize,
53 Last: (i == len(content)-1),
54 }
55 }
56
57 logs[i] = &logpb.LogEntry{
58 StreamIndex: uint64(idx + int64(i)),
59 Content: &logpb.LogEntry_Datagram{&dg},
60 }
61 }
62 return logs
63 }
64
36 // testStreamLogsService implements just the Get and Tail endpoints, 65 // testStreamLogsService implements just the Get and Tail endpoints,
37 // instrumented for testing. 66 // instrumented for testing.
38 type testStreamLogsService struct { 67 type testStreamLogsService struct {
39 testLogsServiceBase 68 testLogsServiceBase
40 69
41 // Get 70 // Get
42 GR logdog.GetRequest 71 GR logdog.GetRequest
43 GH func(*logdog.GetRequest) (*logdog.GetResponse, error) 72 GH func(*logdog.GetRequest) (*logdog.GetResponse, error)
44 73
45 // Tail 74 // Tail
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 panic(err) 112 panic(err)
84 } 113 }
85 client := Client{ 114 client := Client{
86 C: logdog.NewLogsPRPCClient(prpcClient), 115 C: logdog.NewLogsPRPCClient(prpcClient),
87 } 116 }
88 117
89 Convey(`Can bind a Stream`, func() { 118 Convey(`Can bind a Stream`, func() {
90 s := client.Stream("myproj", "test/+/a") 119 s := client.Stream("myproj", "test/+/a")
91 120
92 Convey(`Test Get`, func() { 121 Convey(`Test Get`, func() {
93 p := NewGetParams()
94
95 Convey(`A default Get query will return logs and no state.`, func() { 122 Convey(`A default Get query will return logs and no state.`, func() {
96 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 123 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
97 return &logdog.GetResponse{ 124 return &logdog.GetResponse{
98 Logs: []*logpb.LogEntry{ 125 Logs: []*logpb.LogEntry{
99 genLog(1337, "oh ai"), 126 genLog(1337, "oh ai"),
100 genLog(1338, "kt hxbye"), 127 genLog(1338, "kt hxbye"),
101 }, 128 },
102 }, nil 129 }, nil
103 } 130 }
104 131
105 » » » » » l, err := s.Get(c, nil) 132 » » » » » l, err := s.Get(c)
106 So(err, ShouldBeNil) 133 So(err, ShouldBeNil)
107 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "ohai"), genLog(1338, "kthxbye")}) 134 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "ohai"), genLog(1338, "kthxbye")})
108 135
109 // Validate the correct parameters were sent. 136 // Validate the correct parameters were sent.
110 So(svc.GR, ShouldResemble, logdog.GetReq uest{ 137 So(svc.GR, ShouldResemble, logdog.GetReq uest{
111 Project: "myproj", 138 Project: "myproj",
112 Path: "test/+/a", 139 Path: "test/+/a",
113 }) 140 })
114 }) 141 })
115 142
116 Convey(`Will form a proper Get logs query.`, fun c() { 143 Convey(`Will form a proper Get logs query.`, fun c() {
117 p = p.NonContiguous().Index(1)
118
119 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 144 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
120 return &logdog.GetResponse{}, ni l 145 return &logdog.GetResponse{}, ni l
121 } 146 }
122 147
123 » » » » » l, err := s.Get(c, p) 148 » » » » » l, err := s.Get(c, NonContiguous(), Inde x(1))
124 So(err, ShouldBeNil) 149 So(err, ShouldBeNil)
125 So(l, ShouldBeNil) 150 So(l, ShouldBeNil)
126 151
127 // Validate the correct parameters were sent. 152 // Validate the correct parameters were sent.
128 So(svc.GR, ShouldResemble, logdog.GetReq uest{ 153 So(svc.GR, ShouldResemble, logdog.GetReq uest{
129 Project: "myproj", 154 Project: "myproj",
130 Path: "test/+/a", 155 Path: "test/+/a",
131 NonContiguous: true, 156 NonContiguous: true,
132 Index: 1, 157 Index: 1,
133 }) 158 })
134 }) 159 })
135 160
136 Convey(`Will request a specific number of logs i f a constraint is supplied.`, func() { 161 Convey(`Will request a specific number of logs i f a constraint is supplied.`, func() {
137 p = p.Limit(32, 64)
138
139 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 162 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
140 return &logdog.GetResponse{ 163 return &logdog.GetResponse{
141 Logs: []*logpb.LogEntry{ 164 Logs: []*logpb.LogEntry{
142 genLog(1337, "oh ai"), 165 genLog(1337, "oh ai"),
143 }, 166 },
144 }, nil 167 }, nil
145 } 168 }
146 169
147 » » » » » l, err := s.Get(c, p) 170 » » » » » l, err := s.Get(c, LimitCount(64), Limit Bytes(32))
148 So(err, ShouldBeNil) 171 So(err, ShouldBeNil)
149 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "ohai")}) 172 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "ohai")})
150 173
151 // Validate the HTTP request that we mad e. 174 // Validate the HTTP request that we mad e.
152 So(svc.GR, ShouldResemble, logdog.GetReq uest{ 175 So(svc.GR, ShouldResemble, logdog.GetReq uest{
153 Project: "myproj", 176 Project: "myproj",
154 Path: "test/+/a", 177 Path: "test/+/a",
155 LogCount: 64, 178 LogCount: 64,
156 ByteCount: 32, 179 ByteCount: 32,
157 }) 180 })
158 }) 181 })
159 182
160 Convey(`Can decode a full protobuf and state.`, func() { 183 Convey(`Can decode a full protobuf and state.`, func() {
161 var ls LogStream
162 p = p.State(&ls)
163
164 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 184 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
165 return &logdog.GetResponse{ 185 return &logdog.GetResponse{
166 Logs: []*logpb.LogEntry{ 186 Logs: []*logpb.LogEntry{
167 genLog(1337, "kt hxbye"), 187 genLog(1337, "kt hxbye"),
168 }, 188 },
169 State: &logdog.LogStream State{ 189 State: &logdog.LogStream State{
170 Created: google. NewTimestamp(now), 190 Created: google. NewTimestamp(now),
171 Archive: &logdog .LogStreamState_ArchiveInfo{ 191 Archive: &logdog .LogStreamState_ArchiveInfo{
172 IndexUrl : "index", 192 IndexUrl : "index",
173 StreamUr l: "stream", 193 StreamUr l: "stream",
174 DataUrl: "data", 194 DataUrl: "data",
175 }, 195 },
176 }, 196 },
177 Desc: &logpb.LogStreamDe scriptor{ 197 Desc: &logpb.LogStreamDe scriptor{
178 Prefix: "tes t", 198 Prefix: "tes t",
179 Name: "a", 199 Name: "a",
180 StreamType: logp b.StreamType_TEXT, 200 StreamType: logp b.StreamType_TEXT,
181 }, 201 },
182 }, nil 202 }, nil
183 } 203 }
184 204
185 » » » » » l, err := s.Get(c, p) 205 » » » » » var ls LogStream
206 » » » » » l, err := s.Get(c, WithState(&ls))
186 So(err, ShouldBeNil) 207 So(err, ShouldBeNil)
187 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "kthxbye")}) 208 So(l, ShouldResemble, []*logpb.LogEntry{ genLog(1337, "kthxbye")})
188 So(ls, ShouldResemble, LogStream{ 209 So(ls, ShouldResemble, LogStream{
189 Path: "test/+/a", 210 Path: "test/+/a",
190 » » » » » » Desc: &logpb.LogStreamDescriptor { 211 » » » » » » Desc: logpb.LogStreamDescriptor{
191 Prefix: "test", 212 Prefix: "test",
192 Name: "a", 213 Name: "a",
193 StreamType: logpb.Stream Type_TEXT, 214 StreamType: logpb.Stream Type_TEXT,
194 }, 215 },
195 » » » » » » State: &StreamState{ 216 » » » » » » State: StreamState{
196 Created: now, 217 Created: now,
197 Archived: true, 218 Archived: true,
198 ArchiveIndexURL: "index ", 219 ArchiveIndexURL: "index ",
199 ArchiveStreamURL: "strea m", 220 ArchiveStreamURL: "strea m",
200 ArchiveDataURL: "data" , 221 ArchiveDataURL: "data" ,
201 }, 222 },
202 }) 223 })
203 }) 224 })
204 225
205 Convey(`Will return ErrNoSuchStream if the strea m is not found.`, func() { 226 Convey(`Will return ErrNoSuchStream if the strea m is not found.`, func() {
206 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 227 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
207 return nil, grpcutil.NotFound 228 return nil, grpcutil.NotFound
208 } 229 }
209 230
210 » » » » » _, err := s.Get(c, p) 231 » » » » » _, err := s.Get(c)
211 So(err, ShouldEqual, ErrNoSuchStream) 232 So(err, ShouldEqual, ErrNoSuchStream)
212 }) 233 })
213 234
214 Convey(`Will return ErrNoAccess if unauthenticat ed.`, func() { 235 Convey(`Will return ErrNoAccess if unauthenticat ed.`, func() {
215 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 236 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
216 return nil, grpcutil.Unauthentic ated 237 return nil, grpcutil.Unauthentic ated
217 } 238 }
218 239
219 » » » » » _, err := s.Get(c, p) 240 » » » » » _, err := s.Get(c)
220 So(err, ShouldEqual, ErrNoAccess) 241 So(err, ShouldEqual, ErrNoAccess)
221 }) 242 })
222 243
223 Convey(`Will return ErrNoAccess if permission is denied.`, func() { 244 Convey(`Will return ErrNoAccess if permission is denied.`, func() {
224 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 245 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
225 return nil, grpcutil.PermissionD enied 246 return nil, grpcutil.PermissionD enied
226 } 247 }
227 248
228 » » » » » _, err := s.Get(c, p) 249 » » » » » _, err := s.Get(c)
229 So(err, ShouldEqual, ErrNoAccess) 250 So(err, ShouldEqual, ErrNoAccess)
230 }) 251 })
231 }) 252 })
232 253
233 Convey(`Test State`, func() { 254 Convey(`Test State`, func() {
234 Convey(`Will request just the state if asked.`, func() { 255 Convey(`Will request just the state if asked.`, func() {
235 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) { 256 svc.GH = func(*logdog.GetRequest) (*logd og.GetResponse, error) {
236 return &logdog.GetResponse{ 257 return &logdog.GetResponse{
237 Project: "myproj", 258 Project: "myproj",
259 Desc: &logpb.LogStreamDe scriptor{
260 Prefix: "tes t",
261 Name: "a",
262 StreamType: logp b.StreamType_TEXT,
263 },
238 State: &logdog.LogStream State{ 264 State: &logdog.LogStream State{
239 Created: google. NewTimestamp(now), 265 Created: google. NewTimestamp(now),
240 }, 266 },
241 }, nil 267 }, nil
242 } 268 }
243 269
244 l, err := s.State(c) 270 l, err := s.State(c)
245 So(err, ShouldBeNil) 271 So(err, ShouldBeNil)
246 So(l, ShouldResemble, &LogStream{ 272 So(l, ShouldResemble, &LogStream{
247 Project: "myproj", 273 Project: "myproj",
248 Path: "test/+/a", 274 Path: "test/+/a",
249 » » » » » » State: &StreamState{ 275 » » » » » » Desc: logpb.LogStreamDescriptor{
276 » » » » » » » Prefix: "test",
277 » » » » » » » Name: "a",
278 » » » » » » » StreamType: logpb.Stream Type_TEXT,
279 » » » » » » },
280 » » » » » » State: StreamState{
250 Created: now.UTC(), 281 Created: now.UTC(),
251 }, 282 },
252 }) 283 })
253 284
254 // Validate the HTTP request that we mad e. 285 // Validate the HTTP request that we mad e.
255 So(svc.GR, ShouldResemble, logdog.GetReq uest{ 286 So(svc.GR, ShouldResemble, logdog.GetReq uest{
256 Project: "myproj", 287 Project: "myproj",
257 Path: "test/+/a", 288 Path: "test/+/a",
258 LogCount: -1, 289 LogCount: -1,
259 State: true, 290 State: true,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 Name: "a", 332 Name: "a",
302 StreamType: logp b.StreamType_TEXT, 333 StreamType: logp b.StreamType_TEXT,
303 }, 334 },
304 Logs: []*logpb.LogEntry{ 335 Logs: []*logpb.LogEntry{
305 genLog(1337, "kt hxbye"), 336 genLog(1337, "kt hxbye"),
306 }, 337 },
307 }, nil 338 }, nil
308 } 339 }
309 340
310 var ls LogStream 341 var ls LogStream
311 » » » » » l, err := s.Tail(c, &ls) 342 » » » » » l, err := s.Tail(c, WithState(&ls))
312 So(err, ShouldBeNil) 343 So(err, ShouldBeNil)
313 344
314 // Validate the HTTP request that we mad e. 345 // Validate the HTTP request that we mad e.
315 So(svc.TR, ShouldResemble, logdog.TailRe quest{ 346 So(svc.TR, ShouldResemble, logdog.TailRe quest{
316 Project: "myproj", 347 Project: "myproj",
317 Path: "test/+/a", 348 Path: "test/+/a",
318 State: true, 349 State: true,
319 }) 350 })
320 351
321 // Validate that the log and state were returned. 352 // Validate that the log and state were returned.
322 So(l, ShouldResemble, genLog(1337, "kthx bye")) 353 So(l, ShouldResemble, genLog(1337, "kthx bye"))
323 So(ls, ShouldResemble, LogStream{ 354 So(ls, ShouldResemble, LogStream{
324 Project: "myproj", 355 Project: "myproj",
325 Path: "test/+/a", 356 Path: "test/+/a",
326 » » » » » » Desc: &logpb.LogStreamDescriptor { 357 » » » » » » Desc: logpb.LogStreamDescriptor{
327 Prefix: "test", 358 Prefix: "test",
328 Name: "a", 359 Name: "a",
329 StreamType: logpb.Stream Type_TEXT, 360 StreamType: logpb.Stream Type_TEXT,
330 }, 361 },
331 » » » » » » State: &StreamState{ 362 » » » » » » State: StreamState{
332 Created: now, 363 Created: now,
333 }, 364 },
334 }) 365 })
335 }) 366 })
336 367
337 Convey(`Will return nil with state if no logs ar e returned from the endpoint.`, func() { 368 Convey(`Will return nil with state if no logs ar e returned from the endpoint.`, func() {
338 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) { 369 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) {
339 return &logdog.GetResponse{ 370 return &logdog.GetResponse{
340 Project: "myproj", 371 Project: "myproj",
341 State: &logdog.LogStream State{ 372 State: &logdog.LogStream State{
342 Created: google. NewTimestamp(now), 373 Created: google. NewTimestamp(now),
343 }, 374 },
344 Desc: &logpb.LogStreamDe scriptor{ 375 Desc: &logpb.LogStreamDe scriptor{
345 Prefix: "tes t", 376 Prefix: "tes t",
346 Name: "a", 377 Name: "a",
347 StreamType: logp b.StreamType_TEXT, 378 StreamType: logp b.StreamType_TEXT,
348 }, 379 },
349 }, nil 380 }, nil
350 } 381 }
351 382
352 var ls LogStream 383 var ls LogStream
353 » » » » » l, err := s.Tail(c, &ls) 384 » » » » » l, err := s.Tail(c, WithState(&ls))
354 So(err, ShouldBeNil) 385 So(err, ShouldBeNil)
355 So(l, ShouldBeNil) 386 So(l, ShouldBeNil)
356 So(ls, ShouldResemble, LogStream{ 387 So(ls, ShouldResemble, LogStream{
357 Project: "myproj", 388 Project: "myproj",
358 Path: "test/+/a", 389 Path: "test/+/a",
359 » » » » » » Desc: &logpb.LogStreamDescriptor { 390 » » » » » » Desc: logpb.LogStreamDescriptor{
360 Prefix: "test", 391 Prefix: "test",
361 Name: "a", 392 Name: "a",
362 StreamType: logpb.Stream Type_TEXT, 393 StreamType: logpb.Stream Type_TEXT,
363 }, 394 },
364 » » » » » » State: &StreamState{ 395 » » » » » » State: StreamState{
365 Created: now, 396 Created: now,
366 }, 397 },
367 }) 398 })
368 }) 399 })
369 400
370 Convey(`Will error if multiple logs are returned from the endpoint.`, func() { 401 Convey(`Will error if multiple logs are returned from the endpoint.`, func() {
371 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) { 402 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) {
372 return &logdog.GetResponse{ 403 return &logdog.GetResponse{
373 State: &logdog.LogStream State{ 404 State: &logdog.LogStream State{
374 Created: google. NewTimestamp(now), 405 Created: google. NewTimestamp(now),
375 }, 406 },
376 Logs: []*logpb.LogEntry{ 407 Logs: []*logpb.LogEntry{
377 genLog(1337, "oh ai"), 408 genLog(1337, "oh ai"),
378 genLog(1338, "kt hxbye"), 409 genLog(1338, "kt hxbye"),
379 }, 410 },
380 }, nil 411 }, nil
381 } 412 }
382 413
383 » » » » » _, err := s.Tail(c, nil) 414 » » » » » _, err := s.Tail(c)
384 So(err, ShouldErrLike, "tail call return ed 2 logs") 415 So(err, ShouldErrLike, "tail call return ed 2 logs")
385 }) 416 })
386 417
387 Convey(`Will return ErrNoSuchStream if the strea m is not found.`, func() { 418 Convey(`Will return ErrNoSuchStream if the strea m is not found.`, func() {
388 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) { 419 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) {
389 return nil, grpcutil.NotFound 420 return nil, grpcutil.NotFound
390 } 421 }
391 422
392 » » » » » _, err := s.Tail(c, nil) 423 » » » » » _, err := s.Tail(c)
393 So(err, ShouldEqual, ErrNoSuchStream) 424 So(err, ShouldEqual, ErrNoSuchStream)
394 }) 425 })
395 426
396 Convey(`Will return ErrNoAccess if unauthenticat ed.`, func() { 427 Convey(`Will return ErrNoAccess if unauthenticat ed.`, func() {
397 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) { 428 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) {
398 return nil, grpcutil.Unauthentic ated 429 return nil, grpcutil.Unauthentic ated
399 } 430 }
400 431
401 » » » » » _, err := s.Tail(c, nil) 432 » » » » » _, err := s.Tail(c)
402 So(err, ShouldEqual, ErrNoAccess) 433 So(err, ShouldEqual, ErrNoAccess)
403 }) 434 })
404 435
405 Convey(`Will return ErrNoAccess if permission is denied.`, func() { 436 Convey(`Will return ErrNoAccess if permission is denied.`, func() {
406 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) { 437 svc.TH = func(*logdog.TailRequest) (*log dog.GetResponse, error) {
407 return nil, grpcutil.PermissionD enied 438 return nil, grpcutil.PermissionD enied
408 } 439 }
409 440
410 » » » » » _, err := s.Tail(c, nil) 441 » » » » » _, err := s.Tail(c)
411 So(err, ShouldEqual, ErrNoAccess) 442 So(err, ShouldEqual, ErrNoAccess)
412 }) 443 })
444
445 Convey(`When requesting complete streams`, func( ) {
446 var allLogs []*logpb.LogEntry
447 allLogs = append(allLogs, genDG(1337, "f oo", "bar", "baz", "kthxbye")...)
448 allLogs = append(allLogs, genDG(1341, "q ux", "ohai")...)
449 allLogs = append(allLogs, genDG(1343, "c omplete")...)
450 tailLog := allLogs[len(allLogs)-1]
451
452 svc.TH = func(req *logdog.TailRequest) ( *logdog.GetResponse, error) {
453 return &logdog.GetResponse{
454 Logs: []*logpb.LogEntry{ tailLog},
455 State: &logdog.LogStream State{
456 Created: google. NewTimestamp(now),
457 },
458 Desc: &logpb.LogStreamDe scriptor{
459 Prefix: "tes t",
460 Name: "a",
461 StreamType: logp b.StreamType_DATAGRAM,
462 },
463 }, nil
464 }
465
466 svc.GH = func(req *logdog.GetRequest) (* logdog.GetResponse, error) {
467 if req.State || req.NonContiguou s || req.ByteCount != 0 {
468 return nil, errors.New(" not implemented in test")
469 }
470 if len(allLogs) == 0 {
471 return &logdog.GetRespon se{}, nil
472 }
473
474 // Identify the requested index.
475 var ret []*logpb.LogEntry
476 for i, le := range allLogs {
477 if le.StreamIndex == uin t64(req.Index) {
478 ret = allLogs[i: ]
479 break
480 }
481 }
482 count := int(req.LogCount)
483 if count > len(ret) {
484 count = len(ret)
485 }
486 return &logdog.GetResponse{
487 Logs: ret[:count],
488 }, nil
489 }
490
491 Convey(`With a non-partial datagram, ret urns that datagram.`, func() {
492 le, err := s.Tail(c, Complete())
493 So(err, ShouldBeNil)
494 So(le.StreamIndex, ShouldEqual, 1343)
495 So(le.GetDatagram().Partial, Sho uldBeNil)
496 So(le.GetDatagram().Data, Should Resemble, []byte("complete"))
497 })
498
499 Convey(`Can assemble a set of one partia l datagram.`, func() {
500 // This is weird, since this doe sn't need to be partial at all, but
501 // we should handle it gracefull y.
502 dg := tailLog.GetDatagram()
503 dg.Partial = &logpb.Datagram_Par tial{
504 Index: 0,
505 Size: uint64(len(dg.Dat a)),
506 Last: true,
507 }
508
509 le, err := s.Tail(c, Complete())
510 So(err, ShouldBeNil)
511 So(le.StreamIndex, ShouldEqual, 1343)
512 So(le.GetDatagram().Partial, Sho uldBeNil)
513 So(le.GetDatagram().Data, Should Resemble, []byte("complete"))
514 })
515
516 Convey(`Can assemble a set of two partia l datagrams.`, func() {
517 tailLog = allLogs[5]
518
519 le, err := s.Tail(c, Complete())
520 So(err, ShouldBeNil)
521 So(le.StreamIndex, ShouldEqual, 1341)
522 So(le.GetDatagram().Partial, Sho uldBeNil)
523 So(le.GetDatagram().Data, Should Resemble, []byte("quxohai"))
524 })
525
526 Convey(`With a set of three partial data grams.`, func() {
527 tailLog = allLogs[3]
528
529 Convey(`Will return a fully reas sembled datagram.`, func() {
530 var ls LogStream
531 le, err := s.Tail(c, Wit hState(&ls), Complete())
532 So(err, ShouldBeNil)
533 So(le.StreamIndex, Shoul dEqual, 1337)
534 So(le.GetDatagram().Part ial, ShouldBeNil)
535 So(le.GetDatagram().Data , ShouldResemble, []byte("foobarbazkthxbye"))
536
537 So(ls, ShouldResemble, L ogStream{
538 Path: "test/+/a" ,
539 Desc: logpb.LogS treamDescriptor{
540 Prefix: "test",
541 Name: "a",
542 StreamTy pe: logpb.StreamType_DATAGRAM,
543 },
544 State: StreamSta te{
545 Created: now,
546 },
547 })
548 })
549
550 Convey(`Will return an error if the Get fails.`, func() {
551 svc.GH = func(req *logdo g.GetRequest) (*logdog.GetResponse, error) {
552 return nil, erro rs.New("test error")
553 }
554
555 _, err := s.Tail(c, Comp lete())
556 So(err, ShouldErrLike, " failed to get intermediate logs")
martiniss 2016/09/22 03:40:39 test for test error in the err?
dnj 2016/09/22 16:00:05 Done. I'll have to make this function return a gRP
557 })
558
559 Convey(`Will return an error if the Get returns fewer logs than requested.`, func() {
560 allLogs = allLogs[0:1]
561
562 _, err := s.Tail(c, Comp lete())
563 So(err, ShouldErrLike, " incomplete intermediate logs results")
564 })
565
566 Convey(`Will return an error if Get returns non-datagram logs.`, func() {
567 allLogs[1].Content = nil
568
569 _, err := s.Tail(c, Comp lete())
570 So(err, ShouldErrLike, " is not a datagram")
571 })
572
573 Convey(`Will return an error if Get returns non-partial datagram logs.`, func() {
574 allLogs[1].GetDatagram() .Partial = nil
575
576 _, err := s.Tail(c, Comp lete())
577 So(err, ShouldErrLike, " is not partial")
578 })
579
580 Convey(`Will return an error if Get returns non-contiguous partial datagrams.`, func() {
581 allLogs[1].GetDatagram() .Partial.Index = 2
582
583 _, err := s.Tail(c, Comp lete())
584 So(err, ShouldErrLike, " does not have a contiguous index")
585 })
586
587 Convey(`Will return an error if the chunks declare different sizes.`, func() {
588 allLogs[1].GetDatagram() .Partial.Size = 0
589
590 _, err := s.Tail(c, Comp lete())
591 So(err, ShouldErrLike, " inconsistent datagram size")
592 })
593
594 Convey(`Will return an error if the reassembled length exceeds the declared size.`, func() {
595 for _, le := range allLo gs {
596 if p := le.GetDa tagram().Partial; p != nil {
597 p.Size = 0
598 }
599 }
600
601 _, err := s.Tail(c, Comp lete())
602 So(err, ShouldErrLike, " appending chunk data would exceed the declared size")
603 })
604
605 Convey(`Will return an error if the reassembled length doesn't match the declared size.`, func() {
606 for _, le := range allLo gs {
607 if p := le.GetDa tagram().Partial; p != nil {
608 p.Size = 1024 * 1024
609 }
610 }
611
612 _, err := s.Tail(c, Comp lete())
613 So(err, ShouldErrLike, " differs from declared length")
614 })
615 })
616
617 Convey(`When Tail returns a mid-partial datagram.`, func() {
618 tailLog = allLogs[4]
619
620 Convey(`If the previous datagram is not partial, will return it.`, func() {
621 allLogs[3].GetDatagram() .Partial = nil
622
623 le, err := s.Tail(c, Com plete())
624 So(err, ShouldBeNil)
625 So(le.StreamIndex, Shoul dEqual, 1340)
626 So(le.GetDatagram().Part ial, ShouldBeNil)
627 So(le.GetDatagram().Data , ShouldResemble, []byte("kthxbye"))
628 })
629
630 Convey(`If the previous datagram is partial, will return it reassembled.`, func() {
martiniss 2016/09/22 03:40:39 nit: move this above the other test?
dnj 2016/09/22 16:00:05 Done.
631 le, err := s.Tail(c, Com plete())
632 So(err, ShouldBeNil)
633 So(le.StreamIndex, Shoul dEqual, 1337)
634 So(le.GetDatagram().Part ial, ShouldBeNil)
635 So(le.GetDatagram().Data , ShouldResemble, []byte("foobarbazkthxbye"))
636 })
637 })
638 })
413 }) 639 })
414 }) 640 })
415 }) 641 })
416 } 642 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698