github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/daemon/logger/awslogs/cloudwatchlogs_test.go (about) 1 package awslogs 2 3 import ( 4 "errors" 5 "fmt" 6 "net/http" 7 "reflect" 8 "runtime" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/aws/aws-sdk-go/aws" 14 "github.com/aws/aws-sdk-go/aws/awserr" 15 "github.com/aws/aws-sdk-go/aws/request" 16 "github.com/aws/aws-sdk-go/service/cloudwatchlogs" 17 "github.com/docker/docker/daemon/logger" 18 "github.com/docker/docker/daemon/logger/loggerutils" 19 "github.com/docker/docker/dockerversion" 20 ) 21 22 const ( 23 groupName = "groupName" 24 streamName = "streamName" 25 sequenceToken = "sequenceToken" 26 nextSequenceToken = "nextSequenceToken" 27 logline = "this is a log line" 28 ) 29 30 func TestNewAWSLogsClientUserAgentHandler(t *testing.T) { 31 info := logger.Info{ 32 Config: map[string]string{ 33 regionKey: "us-east-1", 34 }, 35 } 36 37 client, err := newAWSLogsClient(info) 38 if err != nil { 39 t.Fatal(err) 40 } 41 realClient, ok := client.(*cloudwatchlogs.CloudWatchLogs) 42 if !ok { 43 t.Fatal("Could not cast client to cloudwatchlogs.CloudWatchLogs") 44 } 45 buildHandlerList := realClient.Handlers.Build 46 request := &request.Request{ 47 HTTPRequest: &http.Request{ 48 Header: http.Header{}, 49 }, 50 } 51 buildHandlerList.Run(request) 52 expectedUserAgentString := fmt.Sprintf("Docker %s (%s) %s/%s (%s; %s; %s)", 53 dockerversion.Version, runtime.GOOS, aws.SDKName, aws.SDKVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH) 54 userAgent := request.HTTPRequest.Header.Get("User-Agent") 55 if userAgent != expectedUserAgentString { 56 t.Errorf("Wrong User-Agent string, expected \"%s\" but was \"%s\"", 57 expectedUserAgentString, userAgent) 58 } 59 } 60 61 func TestNewAWSLogsClientRegionDetect(t *testing.T) { 62 info := logger.Info{ 63 Config: map[string]string{}, 64 } 65 66 mockMetadata := newMockMetadataClient() 67 newRegionFinder = func() regionFinder { 68 return mockMetadata 69 } 70 mockMetadata.regionResult <- ®ionResult{ 71 successResult: "us-east-1", 72 } 73 74 _, err := newAWSLogsClient(info) 75 if err != nil { 76 t.Fatal(err) 77 } 78 } 79 80 func TestCreateSuccess(t *testing.T) { 81 mockClient := newMockClient() 82 stream := &logStream{ 83 client: mockClient, 84 logGroupName: groupName, 85 logStreamName: streamName, 86 } 87 mockClient.createLogStreamResult <- &createLogStreamResult{} 88 89 err := stream.create() 90 91 if err != nil { 92 t.Errorf("Received unexpected err: %v\n", err) 93 } 94 argument := <-mockClient.createLogStreamArgument 95 if argument.LogGroupName == nil { 96 t.Fatal("Expected non-nil LogGroupName") 97 } 98 if *argument.LogGroupName != groupName { 99 t.Errorf("Expected LogGroupName to be %s", groupName) 100 } 101 if argument.LogStreamName == nil { 102 t.Fatal("Expected non-nil LogStreamName") 103 } 104 if *argument.LogStreamName != streamName { 105 t.Errorf("Expected LogStreamName to be %s", streamName) 106 } 107 } 108 109 func TestCreateLogGroupSuccess(t *testing.T) { 110 mockClient := newMockClient() 111 stream := &logStream{ 112 client: mockClient, 113 logGroupName: groupName, 114 logStreamName: streamName, 115 logCreateGroup: true, 116 } 117 mockClient.createLogGroupResult <- &createLogGroupResult{} 118 mockClient.createLogStreamResult <- &createLogStreamResult{} 119 120 err := stream.create() 121 122 if err != nil { 123 t.Errorf("Received unexpected err: %v\n", err) 124 } 125 argument := <-mockClient.createLogStreamArgument 126 if argument.LogGroupName == nil { 127 t.Fatal("Expected non-nil LogGroupName") 128 } 129 if *argument.LogGroupName != groupName { 130 t.Errorf("Expected LogGroupName to be %s", groupName) 131 } 132 if argument.LogStreamName == nil { 133 t.Fatal("Expected non-nil LogStreamName") 134 } 135 if *argument.LogStreamName != streamName { 136 t.Errorf("Expected LogStreamName to be %s", streamName) 137 } 138 } 139 140 func TestCreateError(t *testing.T) { 141 mockClient := newMockClient() 142 stream := &logStream{ 143 client: mockClient, 144 } 145 mockClient.createLogStreamResult <- &createLogStreamResult{ 146 errorResult: errors.New("Error!"), 147 } 148 149 err := stream.create() 150 151 if err == nil { 152 t.Fatal("Expected non-nil err") 153 } 154 } 155 156 func TestCreateAlreadyExists(t *testing.T) { 157 mockClient := newMockClient() 158 stream := &logStream{ 159 client: mockClient, 160 } 161 mockClient.createLogStreamResult <- &createLogStreamResult{ 162 errorResult: awserr.New(resourceAlreadyExistsCode, "", nil), 163 } 164 165 err := stream.create() 166 167 if err != nil { 168 t.Fatal("Expected nil err") 169 } 170 } 171 172 func TestPublishBatchSuccess(t *testing.T) { 173 mockClient := newMockClient() 174 stream := &logStream{ 175 client: mockClient, 176 logGroupName: groupName, 177 logStreamName: streamName, 178 sequenceToken: aws.String(sequenceToken), 179 } 180 mockClient.putLogEventsResult <- &putLogEventsResult{ 181 successResult: &cloudwatchlogs.PutLogEventsOutput{ 182 NextSequenceToken: aws.String(nextSequenceToken), 183 }, 184 } 185 events := []wrappedEvent{ 186 { 187 inputLogEvent: &cloudwatchlogs.InputLogEvent{ 188 Message: aws.String(logline), 189 }, 190 }, 191 } 192 193 stream.publishBatch(events) 194 if stream.sequenceToken == nil { 195 t.Fatal("Expected non-nil sequenceToken") 196 } 197 if *stream.sequenceToken != nextSequenceToken { 198 t.Errorf("Expected sequenceToken to be %s, but was %s", nextSequenceToken, *stream.sequenceToken) 199 } 200 argument := <-mockClient.putLogEventsArgument 201 if argument == nil { 202 t.Fatal("Expected non-nil PutLogEventsInput") 203 } 204 if argument.SequenceToken == nil { 205 t.Fatal("Expected non-nil PutLogEventsInput.SequenceToken") 206 } 207 if *argument.SequenceToken != sequenceToken { 208 t.Errorf("Expected PutLogEventsInput.SequenceToken to be %s, but was %s", sequenceToken, *argument.SequenceToken) 209 } 210 if len(argument.LogEvents) != 1 { 211 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 212 } 213 if argument.LogEvents[0] != events[0].inputLogEvent { 214 t.Error("Expected event to equal input") 215 } 216 } 217 218 func TestPublishBatchError(t *testing.T) { 219 mockClient := newMockClient() 220 stream := &logStream{ 221 client: mockClient, 222 logGroupName: groupName, 223 logStreamName: streamName, 224 sequenceToken: aws.String(sequenceToken), 225 } 226 mockClient.putLogEventsResult <- &putLogEventsResult{ 227 errorResult: errors.New("Error!"), 228 } 229 230 events := []wrappedEvent{ 231 { 232 inputLogEvent: &cloudwatchlogs.InputLogEvent{ 233 Message: aws.String(logline), 234 }, 235 }, 236 } 237 238 stream.publishBatch(events) 239 if stream.sequenceToken == nil { 240 t.Fatal("Expected non-nil sequenceToken") 241 } 242 if *stream.sequenceToken != sequenceToken { 243 t.Errorf("Expected sequenceToken to be %s, but was %s", sequenceToken, *stream.sequenceToken) 244 } 245 } 246 247 func TestPublishBatchInvalidSeqSuccess(t *testing.T) { 248 mockClient := newMockClientBuffered(2) 249 stream := &logStream{ 250 client: mockClient, 251 logGroupName: groupName, 252 logStreamName: streamName, 253 sequenceToken: aws.String(sequenceToken), 254 } 255 mockClient.putLogEventsResult <- &putLogEventsResult{ 256 errorResult: awserr.New(invalidSequenceTokenCode, "use token token", nil), 257 } 258 mockClient.putLogEventsResult <- &putLogEventsResult{ 259 successResult: &cloudwatchlogs.PutLogEventsOutput{ 260 NextSequenceToken: aws.String(nextSequenceToken), 261 }, 262 } 263 264 events := []wrappedEvent{ 265 { 266 inputLogEvent: &cloudwatchlogs.InputLogEvent{ 267 Message: aws.String(logline), 268 }, 269 }, 270 } 271 272 stream.publishBatch(events) 273 if stream.sequenceToken == nil { 274 t.Fatal("Expected non-nil sequenceToken") 275 } 276 if *stream.sequenceToken != nextSequenceToken { 277 t.Errorf("Expected sequenceToken to be %s, but was %s", nextSequenceToken, *stream.sequenceToken) 278 } 279 280 argument := <-mockClient.putLogEventsArgument 281 if argument == nil { 282 t.Fatal("Expected non-nil PutLogEventsInput") 283 } 284 if argument.SequenceToken == nil { 285 t.Fatal("Expected non-nil PutLogEventsInput.SequenceToken") 286 } 287 if *argument.SequenceToken != sequenceToken { 288 t.Errorf("Expected PutLogEventsInput.SequenceToken to be %s, but was %s", sequenceToken, *argument.SequenceToken) 289 } 290 if len(argument.LogEvents) != 1 { 291 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 292 } 293 if argument.LogEvents[0] != events[0].inputLogEvent { 294 t.Error("Expected event to equal input") 295 } 296 297 argument = <-mockClient.putLogEventsArgument 298 if argument == nil { 299 t.Fatal("Expected non-nil PutLogEventsInput") 300 } 301 if argument.SequenceToken == nil { 302 t.Fatal("Expected non-nil PutLogEventsInput.SequenceToken") 303 } 304 if *argument.SequenceToken != "token" { 305 t.Errorf("Expected PutLogEventsInput.SequenceToken to be %s, but was %s", "token", *argument.SequenceToken) 306 } 307 if len(argument.LogEvents) != 1 { 308 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 309 } 310 if argument.LogEvents[0] != events[0].inputLogEvent { 311 t.Error("Expected event to equal input") 312 } 313 } 314 315 func TestPublishBatchAlreadyAccepted(t *testing.T) { 316 mockClient := newMockClient() 317 stream := &logStream{ 318 client: mockClient, 319 logGroupName: groupName, 320 logStreamName: streamName, 321 sequenceToken: aws.String(sequenceToken), 322 } 323 mockClient.putLogEventsResult <- &putLogEventsResult{ 324 errorResult: awserr.New(dataAlreadyAcceptedCode, "use token token", nil), 325 } 326 327 events := []wrappedEvent{ 328 { 329 inputLogEvent: &cloudwatchlogs.InputLogEvent{ 330 Message: aws.String(logline), 331 }, 332 }, 333 } 334 335 stream.publishBatch(events) 336 if stream.sequenceToken == nil { 337 t.Fatal("Expected non-nil sequenceToken") 338 } 339 if *stream.sequenceToken != "token" { 340 t.Errorf("Expected sequenceToken to be %s, but was %s", "token", *stream.sequenceToken) 341 } 342 343 argument := <-mockClient.putLogEventsArgument 344 if argument == nil { 345 t.Fatal("Expected non-nil PutLogEventsInput") 346 } 347 if argument.SequenceToken == nil { 348 t.Fatal("Expected non-nil PutLogEventsInput.SequenceToken") 349 } 350 if *argument.SequenceToken != sequenceToken { 351 t.Errorf("Expected PutLogEventsInput.SequenceToken to be %s, but was %s", sequenceToken, *argument.SequenceToken) 352 } 353 if len(argument.LogEvents) != 1 { 354 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 355 } 356 if argument.LogEvents[0] != events[0].inputLogEvent { 357 t.Error("Expected event to equal input") 358 } 359 } 360 361 func TestCollectBatchSimple(t *testing.T) { 362 mockClient := newMockClient() 363 stream := &logStream{ 364 client: mockClient, 365 logGroupName: groupName, 366 logStreamName: streamName, 367 sequenceToken: aws.String(sequenceToken), 368 messages: make(chan *logger.Message), 369 } 370 mockClient.putLogEventsResult <- &putLogEventsResult{ 371 successResult: &cloudwatchlogs.PutLogEventsOutput{ 372 NextSequenceToken: aws.String(nextSequenceToken), 373 }, 374 } 375 ticks := make(chan time.Time) 376 newTicker = func(_ time.Duration) *time.Ticker { 377 return &time.Ticker{ 378 C: ticks, 379 } 380 } 381 382 go stream.collectBatch() 383 384 stream.Log(&logger.Message{ 385 Line: []byte(logline), 386 Timestamp: time.Time{}, 387 }) 388 389 ticks <- time.Time{} 390 stream.Close() 391 392 argument := <-mockClient.putLogEventsArgument 393 if argument == nil { 394 t.Fatal("Expected non-nil PutLogEventsInput") 395 } 396 if len(argument.LogEvents) != 1 { 397 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 398 } 399 if *argument.LogEvents[0].Message != logline { 400 t.Errorf("Expected message to be %s but was %s", logline, *argument.LogEvents[0].Message) 401 } 402 } 403 404 func TestCollectBatchTicker(t *testing.T) { 405 mockClient := newMockClient() 406 stream := &logStream{ 407 client: mockClient, 408 logGroupName: groupName, 409 logStreamName: streamName, 410 sequenceToken: aws.String(sequenceToken), 411 messages: make(chan *logger.Message), 412 } 413 mockClient.putLogEventsResult <- &putLogEventsResult{ 414 successResult: &cloudwatchlogs.PutLogEventsOutput{ 415 NextSequenceToken: aws.String(nextSequenceToken), 416 }, 417 } 418 ticks := make(chan time.Time) 419 newTicker = func(_ time.Duration) *time.Ticker { 420 return &time.Ticker{ 421 C: ticks, 422 } 423 } 424 425 go stream.collectBatch() 426 427 stream.Log(&logger.Message{ 428 Line: []byte(logline + " 1"), 429 Timestamp: time.Time{}, 430 }) 431 stream.Log(&logger.Message{ 432 Line: []byte(logline + " 2"), 433 Timestamp: time.Time{}, 434 }) 435 436 ticks <- time.Time{} 437 438 // Verify first batch 439 argument := <-mockClient.putLogEventsArgument 440 if argument == nil { 441 t.Fatal("Expected non-nil PutLogEventsInput") 442 } 443 if len(argument.LogEvents) != 2 { 444 t.Errorf("Expected LogEvents to contain 2 elements, but contains %d", len(argument.LogEvents)) 445 } 446 if *argument.LogEvents[0].Message != logline+" 1" { 447 t.Errorf("Expected message to be %s but was %s", logline+" 1", *argument.LogEvents[0].Message) 448 } 449 if *argument.LogEvents[1].Message != logline+" 2" { 450 t.Errorf("Expected message to be %s but was %s", logline+" 2", *argument.LogEvents[0].Message) 451 } 452 453 stream.Log(&logger.Message{ 454 Line: []byte(logline + " 3"), 455 Timestamp: time.Time{}, 456 }) 457 458 ticks <- time.Time{} 459 argument = <-mockClient.putLogEventsArgument 460 if argument == nil { 461 t.Fatal("Expected non-nil PutLogEventsInput") 462 } 463 if len(argument.LogEvents) != 1 { 464 t.Errorf("Expected LogEvents to contain 1 elements, but contains %d", len(argument.LogEvents)) 465 } 466 if *argument.LogEvents[0].Message != logline+" 3" { 467 t.Errorf("Expected message to be %s but was %s", logline+" 3", *argument.LogEvents[0].Message) 468 } 469 470 stream.Close() 471 472 } 473 474 func TestCollectBatchClose(t *testing.T) { 475 mockClient := newMockClient() 476 stream := &logStream{ 477 client: mockClient, 478 logGroupName: groupName, 479 logStreamName: streamName, 480 sequenceToken: aws.String(sequenceToken), 481 messages: make(chan *logger.Message), 482 } 483 mockClient.putLogEventsResult <- &putLogEventsResult{ 484 successResult: &cloudwatchlogs.PutLogEventsOutput{ 485 NextSequenceToken: aws.String(nextSequenceToken), 486 }, 487 } 488 var ticks = make(chan time.Time) 489 newTicker = func(_ time.Duration) *time.Ticker { 490 return &time.Ticker{ 491 C: ticks, 492 } 493 } 494 495 go stream.collectBatch() 496 497 stream.Log(&logger.Message{ 498 Line: []byte(logline), 499 Timestamp: time.Time{}, 500 }) 501 502 // no ticks 503 stream.Close() 504 505 argument := <-mockClient.putLogEventsArgument 506 if argument == nil { 507 t.Fatal("Expected non-nil PutLogEventsInput") 508 } 509 if len(argument.LogEvents) != 1 { 510 t.Errorf("Expected LogEvents to contain 1 element, but contains %d", len(argument.LogEvents)) 511 } 512 if *argument.LogEvents[0].Message != logline { 513 t.Errorf("Expected message to be %s but was %s", logline, *argument.LogEvents[0].Message) 514 } 515 } 516 517 func TestCollectBatchLineSplit(t *testing.T) { 518 mockClient := newMockClient() 519 stream := &logStream{ 520 client: mockClient, 521 logGroupName: groupName, 522 logStreamName: streamName, 523 sequenceToken: aws.String(sequenceToken), 524 messages: make(chan *logger.Message), 525 } 526 mockClient.putLogEventsResult <- &putLogEventsResult{ 527 successResult: &cloudwatchlogs.PutLogEventsOutput{ 528 NextSequenceToken: aws.String(nextSequenceToken), 529 }, 530 } 531 var ticks = make(chan time.Time) 532 newTicker = func(_ time.Duration) *time.Ticker { 533 return &time.Ticker{ 534 C: ticks, 535 } 536 } 537 538 go stream.collectBatch() 539 540 longline := strings.Repeat("A", maximumBytesPerEvent) 541 stream.Log(&logger.Message{ 542 Line: []byte(longline + "B"), 543 Timestamp: time.Time{}, 544 }) 545 546 // no ticks 547 stream.Close() 548 549 argument := <-mockClient.putLogEventsArgument 550 if argument == nil { 551 t.Fatal("Expected non-nil PutLogEventsInput") 552 } 553 if len(argument.LogEvents) != 2 { 554 t.Errorf("Expected LogEvents to contain 2 elements, but contains %d", len(argument.LogEvents)) 555 } 556 if *argument.LogEvents[0].Message != longline { 557 t.Errorf("Expected message to be %s but was %s", longline, *argument.LogEvents[0].Message) 558 } 559 if *argument.LogEvents[1].Message != "B" { 560 t.Errorf("Expected message to be %s but was %s", "B", *argument.LogEvents[1].Message) 561 } 562 } 563 564 func TestCollectBatchMaxEvents(t *testing.T) { 565 mockClient := newMockClientBuffered(1) 566 stream := &logStream{ 567 client: mockClient, 568 logGroupName: groupName, 569 logStreamName: streamName, 570 sequenceToken: aws.String(sequenceToken), 571 messages: make(chan *logger.Message), 572 } 573 mockClient.putLogEventsResult <- &putLogEventsResult{ 574 successResult: &cloudwatchlogs.PutLogEventsOutput{ 575 NextSequenceToken: aws.String(nextSequenceToken), 576 }, 577 } 578 var ticks = make(chan time.Time) 579 newTicker = func(_ time.Duration) *time.Ticker { 580 return &time.Ticker{ 581 C: ticks, 582 } 583 } 584 585 go stream.collectBatch() 586 587 line := "A" 588 for i := 0; i <= maximumLogEventsPerPut; i++ { 589 stream.Log(&logger.Message{ 590 Line: []byte(line), 591 Timestamp: time.Time{}, 592 }) 593 } 594 595 // no ticks 596 stream.Close() 597 598 argument := <-mockClient.putLogEventsArgument 599 if argument == nil { 600 t.Fatal("Expected non-nil PutLogEventsInput") 601 } 602 if len(argument.LogEvents) != maximumLogEventsPerPut { 603 t.Errorf("Expected LogEvents to contain %d elements, but contains %d", maximumLogEventsPerPut, len(argument.LogEvents)) 604 } 605 606 argument = <-mockClient.putLogEventsArgument 607 if argument == nil { 608 t.Fatal("Expected non-nil PutLogEventsInput") 609 } 610 if len(argument.LogEvents) != 1 { 611 t.Errorf("Expected LogEvents to contain %d elements, but contains %d", 1, len(argument.LogEvents)) 612 } 613 } 614 615 func TestCollectBatchMaxTotalBytes(t *testing.T) { 616 mockClient := newMockClientBuffered(1) 617 stream := &logStream{ 618 client: mockClient, 619 logGroupName: groupName, 620 logStreamName: streamName, 621 sequenceToken: aws.String(sequenceToken), 622 messages: make(chan *logger.Message), 623 } 624 mockClient.putLogEventsResult <- &putLogEventsResult{ 625 successResult: &cloudwatchlogs.PutLogEventsOutput{ 626 NextSequenceToken: aws.String(nextSequenceToken), 627 }, 628 } 629 var ticks = make(chan time.Time) 630 newTicker = func(_ time.Duration) *time.Ticker { 631 return &time.Ticker{ 632 C: ticks, 633 } 634 } 635 636 go stream.collectBatch() 637 638 longline := strings.Repeat("A", maximumBytesPerPut) 639 stream.Log(&logger.Message{ 640 Line: []byte(longline + "B"), 641 Timestamp: time.Time{}, 642 }) 643 644 // no ticks 645 stream.Close() 646 647 argument := <-mockClient.putLogEventsArgument 648 if argument == nil { 649 t.Fatal("Expected non-nil PutLogEventsInput") 650 } 651 bytes := 0 652 for _, event := range argument.LogEvents { 653 bytes += len(*event.Message) 654 } 655 if bytes > maximumBytesPerPut { 656 t.Errorf("Expected <= %d bytes but was %d", maximumBytesPerPut, bytes) 657 } 658 659 argument = <-mockClient.putLogEventsArgument 660 if len(argument.LogEvents) != 1 { 661 t.Errorf("Expected LogEvents to contain 1 elements, but contains %d", len(argument.LogEvents)) 662 } 663 message := *argument.LogEvents[0].Message 664 if message[len(message)-1:] != "B" { 665 t.Errorf("Expected message to be %s but was %s", "B", message[len(message)-1:]) 666 } 667 } 668 669 func TestCollectBatchWithDuplicateTimestamps(t *testing.T) { 670 mockClient := newMockClient() 671 stream := &logStream{ 672 client: mockClient, 673 logGroupName: groupName, 674 logStreamName: streamName, 675 sequenceToken: aws.String(sequenceToken), 676 messages: make(chan *logger.Message), 677 } 678 mockClient.putLogEventsResult <- &putLogEventsResult{ 679 successResult: &cloudwatchlogs.PutLogEventsOutput{ 680 NextSequenceToken: aws.String(nextSequenceToken), 681 }, 682 } 683 ticks := make(chan time.Time) 684 newTicker = func(_ time.Duration) *time.Ticker { 685 return &time.Ticker{ 686 C: ticks, 687 } 688 } 689 690 go stream.collectBatch() 691 692 times := maximumLogEventsPerPut 693 expectedEvents := []*cloudwatchlogs.InputLogEvent{} 694 timestamp := time.Now() 695 for i := 0; i < times; i++ { 696 line := fmt.Sprintf("%d", i) 697 if i%2 == 0 { 698 timestamp.Add(1 * time.Nanosecond) 699 } 700 stream.Log(&logger.Message{ 701 Line: []byte(line), 702 Timestamp: timestamp, 703 }) 704 expectedEvents = append(expectedEvents, &cloudwatchlogs.InputLogEvent{ 705 Message: aws.String(line), 706 Timestamp: aws.Int64(timestamp.UnixNano() / int64(time.Millisecond)), 707 }) 708 } 709 710 ticks <- time.Time{} 711 stream.Close() 712 713 argument := <-mockClient.putLogEventsArgument 714 if argument == nil { 715 t.Fatal("Expected non-nil PutLogEventsInput") 716 } 717 if len(argument.LogEvents) != times { 718 t.Errorf("Expected LogEvents to contain %d elements, but contains %d", times, len(argument.LogEvents)) 719 } 720 for i := 0; i < times; i++ { 721 if !reflect.DeepEqual(*argument.LogEvents[i], *expectedEvents[i]) { 722 t.Errorf("Expected event to be %v but was %v", *expectedEvents[i], *argument.LogEvents[i]) 723 } 724 } 725 } 726 727 func TestCreateTagSuccess(t *testing.T) { 728 mockClient := newMockClient() 729 info := logger.Info{ 730 ContainerName: "/test-container", 731 ContainerID: "container-abcdefghijklmnopqrstuvwxyz01234567890", 732 Config: map[string]string{"tag": "{{.Name}}/{{.FullID}}"}, 733 } 734 logStreamName, e := loggerutils.ParseLogTag(info, loggerutils.DefaultTemplate) 735 if e != nil { 736 t.Errorf("Error generating tag: %q", e) 737 } 738 stream := &logStream{ 739 client: mockClient, 740 logGroupName: groupName, 741 logStreamName: logStreamName, 742 } 743 mockClient.createLogStreamResult <- &createLogStreamResult{} 744 745 err := stream.create() 746 747 if err != nil { 748 t.Errorf("Received unexpected err: %v\n", err) 749 } 750 argument := <-mockClient.createLogStreamArgument 751 752 if *argument.LogStreamName != "test-container/container-abcdefghijklmnopqrstuvwxyz01234567890" { 753 t.Errorf("Expected LogStreamName to be %s", "test-container/container-abcdefghijklmnopqrstuvwxyz01234567890") 754 } 755 }