Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |