1// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. 2 3//go:build go1.16 4// +build go1.16 5 6package lexruntimev2 7 8import ( 9 "bytes" 10 "context" 11 "io/ioutil" 12 "net/http" 13 "reflect" 14 "strings" 15 "sync" 16 "testing" 17 "time" 18 19 "github.com/aws/aws-sdk-go/aws" 20 "github.com/aws/aws-sdk-go/aws/awserr" 21 "github.com/aws/aws-sdk-go/aws/corehandlers" 22 "github.com/aws/aws-sdk-go/aws/request" 23 "github.com/aws/aws-sdk-go/awstesting/unit" 24 "github.com/aws/aws-sdk-go/private/protocol" 25 "github.com/aws/aws-sdk-go/private/protocol/eventstream" 26 "github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi" 27 "github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamtest" 28 "github.com/aws/aws-sdk-go/private/protocol/restjson" 29) 30 31var _ time.Time 32var _ awserr.Error 33var _ context.Context 34var _ sync.WaitGroup 35var _ strings.Reader 36 37func TestStartConversation_Read(t *testing.T) { 38 expectEvents, eventMsgs := mockStartConversationReadEvents() 39 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 40 eventstreamtest.ServeEventStream{ 41 T: t, 42 Events: eventMsgs, 43 }, 44 true, 45 ) 46 if err != nil { 47 t.Fatalf("expect no error, %v", err) 48 } 49 defer cleanupFn() 50 51 svc := New(sess) 52 resp, err := svc.StartConversation(nil) 53 if err != nil { 54 t.Fatalf("expect no error got, %v", err) 55 } 56 defer resp.GetStream().Close() 57 58 var i int 59 for event := range resp.GetStream().Events() { 60 if event == nil { 61 t.Errorf("%d, expect event, got nil", i) 62 } 63 if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) { 64 t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a) 65 } 66 i++ 67 } 68 69 if err := resp.GetStream().Err(); err != nil { 70 t.Errorf("expect no error, %v", err) 71 } 72} 73 74func TestStartConversation_ReadClose(t *testing.T) { 75 _, eventMsgs := mockStartConversationReadEvents() 76 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 77 eventstreamtest.ServeEventStream{ 78 T: t, 79 Events: eventMsgs, 80 }, 81 true, 82 ) 83 if err != nil { 84 t.Fatalf("expect no error, %v", err) 85 } 86 defer cleanupFn() 87 88 svc := New(sess) 89 resp, err := svc.StartConversation(nil) 90 if err != nil { 91 t.Fatalf("expect no error got, %v", err) 92 } 93 94 // Assert calling Err before close does not close the stream. 95 resp.GetStream().Err() 96 select { 97 case _, ok := <-resp.GetStream().Events(): 98 if !ok { 99 t.Fatalf("expect stream not to be closed, but was") 100 } 101 default: 102 } 103 104 resp.GetStream().Close() 105 <-resp.GetStream().Events() 106 107 if err := resp.GetStream().Err(); err != nil { 108 t.Errorf("expect no error, %v", err) 109 } 110} 111 112func TestStartConversation_ReadUnknownEvent(t *testing.T) { 113 expectEvents, eventMsgs := mockStartConversationReadEvents() 114 var eventOffset int 115 116 unknownEvent := eventstream.Message{ 117 Headers: eventstream.Headers{ 118 eventstreamtest.EventMessageTypeHeader, 119 { 120 Name: eventstreamapi.EventTypeHeader, 121 Value: eventstream.StringValue("UnknownEventName"), 122 }, 123 }, 124 Payload: []byte("some unknown event"), 125 } 126 127 eventMsgs = append(eventMsgs[:eventOffset], 128 append([]eventstream.Message{unknownEvent}, eventMsgs[eventOffset:]...)...) 129 130 expectEvents = append(expectEvents[:eventOffset], 131 append([]StartConversationResponseEventStreamEvent{ 132 &StartConversationResponseEventStreamUnknownEvent{ 133 Type: "UnknownEventName", 134 Message: unknownEvent, 135 }, 136 }, 137 expectEvents[eventOffset:]...)...) 138 139 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 140 eventstreamtest.ServeEventStream{ 141 T: t, 142 Events: eventMsgs, 143 }, 144 true, 145 ) 146 if err != nil { 147 t.Fatalf("expect no error, %v", err) 148 } 149 defer cleanupFn() 150 151 svc := New(sess) 152 resp, err := svc.StartConversation(nil) 153 if err != nil { 154 t.Fatalf("expect no error got, %v", err) 155 } 156 defer resp.GetStream().Close() 157 158 var i int 159 for event := range resp.GetStream().Events() { 160 if event == nil { 161 t.Errorf("%d, expect event, got nil", i) 162 } 163 if e, a := expectEvents[i], event; !reflect.DeepEqual(e, a) { 164 t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a) 165 } 166 i++ 167 } 168 169 if err := resp.GetStream().Err(); err != nil { 170 t.Errorf("expect no error, %v", err) 171 } 172} 173 174func BenchmarkStartConversation_Read(b *testing.B) { 175 _, eventMsgs := mockStartConversationReadEvents() 176 var buf bytes.Buffer 177 encoder := eventstream.NewEncoder(&buf) 178 for _, msg := range eventMsgs { 179 if err := encoder.Encode(msg); err != nil { 180 b.Fatalf("failed to encode message, %v", err) 181 } 182 } 183 stream := &loopReader{source: bytes.NewReader(buf.Bytes())} 184 185 sess := unit.Session 186 svc := New(sess, &aws.Config{ 187 Endpoint: aws.String("https://example.com"), 188 DisableParamValidation: aws.Bool(true), 189 }) 190 svc.Handlers.Send.Swap(corehandlers.SendHandler.Name, 191 request.NamedHandler{Name: "mockSend", 192 Fn: func(r *request.Request) { 193 r.HTTPResponse = &http.Response{ 194 Status: "200 OK", 195 StatusCode: 200, 196 Header: http.Header{}, 197 Body: ioutil.NopCloser(stream), 198 } 199 }, 200 }, 201 ) 202 203 resp, err := svc.StartConversation(nil) 204 if err != nil { 205 b.Fatalf("failed to create request, %v", err) 206 } 207 defer resp.GetStream().Close() 208 b.ResetTimer() 209 210 for i := 0; i < b.N; i++ { 211 if err = resp.GetStream().Err(); err != nil { 212 b.Fatalf("expect no error, got %v", err) 213 } 214 event := <-resp.GetStream().Events() 215 if event == nil { 216 b.Fatalf("expect event, got nil, %v, %d", resp.GetStream().Err(), i) 217 } 218 } 219} 220 221func mockStartConversationReadEvents() ( 222 []StartConversationResponseEventStreamEvent, 223 []eventstream.Message, 224) { 225 expectEvents := []StartConversationResponseEventStreamEvent{ 226 &AudioResponseEvent{ 227 AudioChunk: []byte("blob value goes here"), 228 ContentType: aws.String("string value goes here"), 229 EventId: aws.String("string value goes here"), 230 }, 231 &HeartbeatEvent{ 232 EventId: aws.String("string value goes here"), 233 }, 234 &IntentResultEvent{ 235 EventId: aws.String("string value goes here"), 236 InputMode: aws.String("string value goes here"), 237 Interpretations: []*Interpretation{ 238 { 239 Intent: &Intent{ 240 ConfirmationState: aws.String("string value goes here"), 241 Name: aws.String("string value goes here"), 242 Slots: map[string]*Slot{ 243 "a": { 244 Shape: aws.String("string value goes here"), 245 Value: &Value{ 246 InterpretedValue: aws.String("string value goes here"), 247 OriginalValue: aws.String("string value goes here"), 248 ResolvedValues: []*string{ 249 aws.String("string value goes here"), 250 aws.String("string value goes here"), 251 aws.String("string value goes here"), 252 }, 253 }, 254 Values: []*Slot{}, 255 }, 256 "b": { 257 Shape: aws.String("string value goes here"), 258 Value: &Value{ 259 InterpretedValue: aws.String("string value goes here"), 260 OriginalValue: aws.String("string value goes here"), 261 ResolvedValues: []*string{ 262 aws.String("string value goes here"), 263 aws.String("string value goes here"), 264 aws.String("string value goes here"), 265 }, 266 }, 267 Values: []*Slot{}, 268 }, 269 "c": { 270 Shape: aws.String("string value goes here"), 271 Value: &Value{ 272 InterpretedValue: aws.String("string value goes here"), 273 OriginalValue: aws.String("string value goes here"), 274 ResolvedValues: []*string{ 275 aws.String("string value goes here"), 276 aws.String("string value goes here"), 277 aws.String("string value goes here"), 278 }, 279 }, 280 Values: []*Slot{}, 281 }, 282 }, 283 State: aws.String("string value goes here"), 284 }, 285 NluConfidence: &ConfidenceScore{ 286 Score: aws.Float64(123.45), 287 }, 288 SentimentResponse: &SentimentResponse{ 289 Sentiment: aws.String("string value goes here"), 290 SentimentScore: &SentimentScore{ 291 Mixed: aws.Float64(123.45), 292 Negative: aws.Float64(123.45), 293 Neutral: aws.Float64(123.45), 294 Positive: aws.Float64(123.45), 295 }, 296 }, 297 }, 298 { 299 Intent: &Intent{ 300 ConfirmationState: aws.String("string value goes here"), 301 Name: aws.String("string value goes here"), 302 Slots: map[string]*Slot{ 303 "a": { 304 Shape: aws.String("string value goes here"), 305 Value: &Value{ 306 InterpretedValue: aws.String("string value goes here"), 307 OriginalValue: aws.String("string value goes here"), 308 ResolvedValues: []*string{ 309 aws.String("string value goes here"), 310 aws.String("string value goes here"), 311 aws.String("string value goes here"), 312 }, 313 }, 314 Values: []*Slot{}, 315 }, 316 "b": { 317 Shape: aws.String("string value goes here"), 318 Value: &Value{ 319 InterpretedValue: aws.String("string value goes here"), 320 OriginalValue: aws.String("string value goes here"), 321 ResolvedValues: []*string{ 322 aws.String("string value goes here"), 323 aws.String("string value goes here"), 324 aws.String("string value goes here"), 325 }, 326 }, 327 Values: []*Slot{}, 328 }, 329 "c": { 330 Shape: aws.String("string value goes here"), 331 Value: &Value{ 332 InterpretedValue: aws.String("string value goes here"), 333 OriginalValue: aws.String("string value goes here"), 334 ResolvedValues: []*string{ 335 aws.String("string value goes here"), 336 aws.String("string value goes here"), 337 aws.String("string value goes here"), 338 }, 339 }, 340 Values: []*Slot{}, 341 }, 342 }, 343 State: aws.String("string value goes here"), 344 }, 345 NluConfidence: &ConfidenceScore{ 346 Score: aws.Float64(123.45), 347 }, 348 SentimentResponse: &SentimentResponse{ 349 Sentiment: aws.String("string value goes here"), 350 SentimentScore: &SentimentScore{ 351 Mixed: aws.Float64(123.45), 352 Negative: aws.Float64(123.45), 353 Neutral: aws.Float64(123.45), 354 Positive: aws.Float64(123.45), 355 }, 356 }, 357 }, 358 { 359 Intent: &Intent{ 360 ConfirmationState: aws.String("string value goes here"), 361 Name: aws.String("string value goes here"), 362 Slots: map[string]*Slot{ 363 "a": { 364 Shape: aws.String("string value goes here"), 365 Value: &Value{ 366 InterpretedValue: aws.String("string value goes here"), 367 OriginalValue: aws.String("string value goes here"), 368 ResolvedValues: []*string{ 369 aws.String("string value goes here"), 370 aws.String("string value goes here"), 371 aws.String("string value goes here"), 372 }, 373 }, 374 Values: []*Slot{}, 375 }, 376 "b": { 377 Shape: aws.String("string value goes here"), 378 Value: &Value{ 379 InterpretedValue: aws.String("string value goes here"), 380 OriginalValue: aws.String("string value goes here"), 381 ResolvedValues: []*string{ 382 aws.String("string value goes here"), 383 aws.String("string value goes here"), 384 aws.String("string value goes here"), 385 }, 386 }, 387 Values: []*Slot{}, 388 }, 389 "c": { 390 Shape: aws.String("string value goes here"), 391 Value: &Value{ 392 InterpretedValue: aws.String("string value goes here"), 393 OriginalValue: aws.String("string value goes here"), 394 ResolvedValues: []*string{ 395 aws.String("string value goes here"), 396 aws.String("string value goes here"), 397 aws.String("string value goes here"), 398 }, 399 }, 400 Values: []*Slot{}, 401 }, 402 }, 403 State: aws.String("string value goes here"), 404 }, 405 NluConfidence: &ConfidenceScore{ 406 Score: aws.Float64(123.45), 407 }, 408 SentimentResponse: &SentimentResponse{ 409 Sentiment: aws.String("string value goes here"), 410 SentimentScore: &SentimentScore{ 411 Mixed: aws.Float64(123.45), 412 Negative: aws.Float64(123.45), 413 Neutral: aws.Float64(123.45), 414 Positive: aws.Float64(123.45), 415 }, 416 }, 417 }, 418 }, 419 RequestAttributes: map[string]*string{ 420 "a": aws.String("string value goes here"), 421 "b": aws.String("string value goes here"), 422 "c": aws.String("string value goes here"), 423 }, 424 SessionId: aws.String("string value goes here"), 425 SessionState: &SessionState{ 426 ActiveContexts: []*ActiveContext{ 427 { 428 ContextAttributes: map[string]*string{ 429 "a": aws.String("string value goes here"), 430 "b": aws.String("string value goes here"), 431 "c": aws.String("string value goes here"), 432 }, 433 Name: aws.String("string value goes here"), 434 TimeToLive: &ActiveContextTimeToLive{ 435 TimeToLiveInSeconds: aws.Int64(123), 436 TurnsToLive: aws.Int64(123), 437 }, 438 }, 439 { 440 ContextAttributes: map[string]*string{ 441 "a": aws.String("string value goes here"), 442 "b": aws.String("string value goes here"), 443 "c": aws.String("string value goes here"), 444 }, 445 Name: aws.String("string value goes here"), 446 TimeToLive: &ActiveContextTimeToLive{ 447 TimeToLiveInSeconds: aws.Int64(123), 448 TurnsToLive: aws.Int64(123), 449 }, 450 }, 451 { 452 ContextAttributes: map[string]*string{ 453 "a": aws.String("string value goes here"), 454 "b": aws.String("string value goes here"), 455 "c": aws.String("string value goes here"), 456 }, 457 Name: aws.String("string value goes here"), 458 TimeToLive: &ActiveContextTimeToLive{ 459 TimeToLiveInSeconds: aws.Int64(123), 460 TurnsToLive: aws.Int64(123), 461 }, 462 }, 463 }, 464 DialogAction: &DialogAction{ 465 SlotToElicit: aws.String("string value goes here"), 466 Type: aws.String("string value goes here"), 467 }, 468 Intent: &Intent{ 469 ConfirmationState: aws.String("string value goes here"), 470 Name: aws.String("string value goes here"), 471 Slots: map[string]*Slot{ 472 "a": { 473 Shape: aws.String("string value goes here"), 474 Value: &Value{ 475 InterpretedValue: aws.String("string value goes here"), 476 OriginalValue: aws.String("string value goes here"), 477 ResolvedValues: []*string{ 478 aws.String("string value goes here"), 479 aws.String("string value goes here"), 480 aws.String("string value goes here"), 481 }, 482 }, 483 Values: []*Slot{}, 484 }, 485 "b": { 486 Shape: aws.String("string value goes here"), 487 Value: &Value{ 488 InterpretedValue: aws.String("string value goes here"), 489 OriginalValue: aws.String("string value goes here"), 490 ResolvedValues: []*string{ 491 aws.String("string value goes here"), 492 aws.String("string value goes here"), 493 aws.String("string value goes here"), 494 }, 495 }, 496 Values: []*Slot{}, 497 }, 498 "c": { 499 Shape: aws.String("string value goes here"), 500 Value: &Value{ 501 InterpretedValue: aws.String("string value goes here"), 502 OriginalValue: aws.String("string value goes here"), 503 ResolvedValues: []*string{ 504 aws.String("string value goes here"), 505 aws.String("string value goes here"), 506 aws.String("string value goes here"), 507 }, 508 }, 509 Values: []*Slot{}, 510 }, 511 }, 512 State: aws.String("string value goes here"), 513 }, 514 OriginatingRequestId: aws.String("string value goes here"), 515 SessionAttributes: map[string]*string{ 516 "a": aws.String("string value goes here"), 517 "b": aws.String("string value goes here"), 518 "c": aws.String("string value goes here"), 519 }, 520 }, 521 }, 522 &PlaybackInterruptionEvent{ 523 CausedByEventId: aws.String("string value goes here"), 524 EventId: aws.String("string value goes here"), 525 EventReason: aws.String("string value goes here"), 526 }, 527 &TextResponseEvent{ 528 EventId: aws.String("string value goes here"), 529 Messages: []*Message{ 530 { 531 Content: aws.String("string value goes here"), 532 ContentType: aws.String("string value goes here"), 533 ImageResponseCard: &ImageResponseCard{ 534 Buttons: []*Button{ 535 { 536 Text: aws.String("string value goes here"), 537 Value: aws.String("string value goes here"), 538 }, 539 { 540 Text: aws.String("string value goes here"), 541 Value: aws.String("string value goes here"), 542 }, 543 { 544 Text: aws.String("string value goes here"), 545 Value: aws.String("string value goes here"), 546 }, 547 }, 548 ImageUrl: aws.String("string value goes here"), 549 Subtitle: aws.String("string value goes here"), 550 Title: aws.String("string value goes here"), 551 }, 552 }, 553 { 554 Content: aws.String("string value goes here"), 555 ContentType: aws.String("string value goes here"), 556 ImageResponseCard: &ImageResponseCard{ 557 Buttons: []*Button{ 558 { 559 Text: aws.String("string value goes here"), 560 Value: aws.String("string value goes here"), 561 }, 562 { 563 Text: aws.String("string value goes here"), 564 Value: aws.String("string value goes here"), 565 }, 566 { 567 Text: aws.String("string value goes here"), 568 Value: aws.String("string value goes here"), 569 }, 570 }, 571 ImageUrl: aws.String("string value goes here"), 572 Subtitle: aws.String("string value goes here"), 573 Title: aws.String("string value goes here"), 574 }, 575 }, 576 { 577 Content: aws.String("string value goes here"), 578 ContentType: aws.String("string value goes here"), 579 ImageResponseCard: &ImageResponseCard{ 580 Buttons: []*Button{ 581 { 582 Text: aws.String("string value goes here"), 583 Value: aws.String("string value goes here"), 584 }, 585 { 586 Text: aws.String("string value goes here"), 587 Value: aws.String("string value goes here"), 588 }, 589 { 590 Text: aws.String("string value goes here"), 591 Value: aws.String("string value goes here"), 592 }, 593 }, 594 ImageUrl: aws.String("string value goes here"), 595 Subtitle: aws.String("string value goes here"), 596 Title: aws.String("string value goes here"), 597 }, 598 }, 599 }, 600 }, 601 &TranscriptEvent{ 602 EventId: aws.String("string value goes here"), 603 Transcript: aws.String("string value goes here"), 604 }, 605 } 606 607 var marshalers request.HandlerList 608 marshalers.PushBackNamed(restjson.BuildHandler) 609 payloadMarshaler := protocol.HandlerPayloadMarshal{ 610 Marshalers: marshalers, 611 } 612 _ = payloadMarshaler 613 614 eventMsgs := []eventstream.Message{ 615 { 616 Headers: eventstream.Headers{ 617 eventstreamtest.EventMessageTypeHeader, 618 { 619 Name: eventstreamapi.EventTypeHeader, 620 Value: eventstream.StringValue("AudioResponseEvent"), 621 }, 622 }, 623 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]), 624 }, 625 { 626 Headers: eventstream.Headers{ 627 eventstreamtest.EventMessageTypeHeader, 628 { 629 Name: eventstreamapi.EventTypeHeader, 630 Value: eventstream.StringValue("HeartbeatEvent"), 631 }, 632 }, 633 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[1]), 634 }, 635 { 636 Headers: eventstream.Headers{ 637 eventstreamtest.EventMessageTypeHeader, 638 { 639 Name: eventstreamapi.EventTypeHeader, 640 Value: eventstream.StringValue("IntentResultEvent"), 641 }, 642 }, 643 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[2]), 644 }, 645 { 646 Headers: eventstream.Headers{ 647 eventstreamtest.EventMessageTypeHeader, 648 { 649 Name: eventstreamapi.EventTypeHeader, 650 Value: eventstream.StringValue("PlaybackInterruptionEvent"), 651 }, 652 }, 653 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[3]), 654 }, 655 { 656 Headers: eventstream.Headers{ 657 eventstreamtest.EventMessageTypeHeader, 658 { 659 Name: eventstreamapi.EventTypeHeader, 660 Value: eventstream.StringValue("TextResponseEvent"), 661 }, 662 }, 663 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[4]), 664 }, 665 { 666 Headers: eventstream.Headers{ 667 eventstreamtest.EventMessageTypeHeader, 668 { 669 Name: eventstreamapi.EventTypeHeader, 670 Value: eventstream.StringValue("TranscriptEvent"), 671 }, 672 }, 673 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[5]), 674 }, 675 } 676 677 return expectEvents, eventMsgs 678} 679func TestStartConversation_ReadException(t *testing.T) { 680 expectEvents := []StartConversationResponseEventStreamEvent{ 681 &AccessDeniedException{ 682 RespMetadata: protocol.ResponseMetadata{ 683 StatusCode: 200, 684 }, 685 Message_: aws.String("string value goes here"), 686 }, 687 } 688 689 var marshalers request.HandlerList 690 marshalers.PushBackNamed(restjson.BuildHandler) 691 payloadMarshaler := protocol.HandlerPayloadMarshal{ 692 Marshalers: marshalers, 693 } 694 695 eventMsgs := []eventstream.Message{ 696 { 697 Headers: eventstream.Headers{ 698 eventstreamtest.EventExceptionTypeHeader, 699 { 700 Name: eventstreamapi.ExceptionTypeHeader, 701 Value: eventstream.StringValue("AccessDeniedException"), 702 }, 703 }, 704 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, expectEvents[0]), 705 }, 706 } 707 708 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 709 eventstreamtest.ServeEventStream{ 710 T: t, 711 Events: eventMsgs, 712 }, 713 true, 714 ) 715 if err != nil { 716 t.Fatalf("expect no error, %v", err) 717 } 718 defer cleanupFn() 719 720 svc := New(sess) 721 resp, err := svc.StartConversation(nil) 722 if err != nil { 723 t.Fatalf("expect no error got, %v", err) 724 } 725 726 defer resp.GetStream().Close() 727 728 <-resp.GetStream().Events() 729 730 err = resp.GetStream().Err() 731 if err == nil { 732 t.Fatalf("expect err, got none") 733 } 734 735 expectErr := &AccessDeniedException{ 736 RespMetadata: protocol.ResponseMetadata{ 737 StatusCode: 200, 738 }, 739 Message_: aws.String("string value goes here"), 740 } 741 aerr, ok := err.(awserr.Error) 742 if !ok { 743 t.Errorf("expect exception, got %T, %#v", err, err) 744 } 745 if e, a := expectErr.Code(), aerr.Code(); e != a { 746 t.Errorf("expect %v, got %v", e, a) 747 } 748 if e, a := expectErr.Message(), aerr.Message(); e != a { 749 t.Errorf("expect %v, got %v", e, a) 750 } 751 752 if e, a := expectErr, aerr; !reflect.DeepEqual(e, a) { 753 t.Errorf("expect error %+#v, got %+#v", e, a) 754 } 755} 756 757var _ awserr.Error = (*AccessDeniedException)(nil) 758var _ awserr.Error = (*BadGatewayException)(nil) 759var _ awserr.Error = (*ConflictException)(nil) 760var _ awserr.Error = (*DependencyFailedException)(nil) 761var _ awserr.Error = (*InternalServerException)(nil) 762var _ awserr.Error = (*ResourceNotFoundException)(nil) 763var _ awserr.Error = (*ThrottlingException)(nil) 764var _ awserr.Error = (*ValidationException)(nil) 765 766type loopReader struct { 767 source *bytes.Reader 768} 769 770func (c *loopReader) Read(p []byte) (int, error) { 771 if c.source.Len() == 0 { 772 c.source.Seek(0, 0) 773 } 774 775 return c.source.Read(p) 776} 777 778func TestStartConversation_Write(t *testing.T) { 779 clientEvents, expectedClientEvents := mockStartConversationWriteEvents() 780 781 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 782 &eventstreamtest.ServeEventStream{ 783 T: t, 784 ClientEvents: expectedClientEvents, 785 BiDirectional: true, 786 }, 787 true) 788 defer cleanupFn() 789 790 svc := New(sess) 791 resp, err := svc.StartConversation(nil) 792 if err != nil { 793 t.Fatalf("expect no error, got %v", err) 794 } 795 796 stream := resp.GetStream() 797 798 for _, event := range clientEvents { 799 err = stream.Send(context.Background(), event) 800 if err != nil { 801 t.Fatalf("expect no error, got %v", err) 802 } 803 } 804 805 if err := stream.Close(); err != nil { 806 t.Errorf("expect no error, got %v", err) 807 } 808} 809 810func TestStartConversation_WriteClose(t *testing.T) { 811 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 812 eventstreamtest.ServeEventStream{T: t, BiDirectional: true}, 813 true, 814 ) 815 if err != nil { 816 t.Fatalf("expect no error, %v", err) 817 } 818 defer cleanupFn() 819 820 svc := New(sess) 821 resp, err := svc.StartConversation(nil) 822 if err != nil { 823 t.Fatalf("expect no error got, %v", err) 824 } 825 826 // Assert calling Err before close does not close the stream. 827 resp.GetStream().Err() 828 829 err = resp.GetStream().Send(context.Background(), &AudioInputEvent{}) 830 if err != nil { 831 t.Fatalf("expect no error, got %v", err) 832 } 833 834 resp.GetStream().Close() 835 836 if err := resp.GetStream().Err(); err != nil { 837 t.Errorf("expect no error, %v", err) 838 } 839} 840 841func TestStartConversation_WriteError(t *testing.T) { 842 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 843 eventstreamtest.ServeEventStream{ 844 T: t, 845 BiDirectional: true, 846 ForceCloseAfter: time.Millisecond * 500, 847 }, 848 true, 849 ) 850 if err != nil { 851 t.Fatalf("expect no error, %v", err) 852 } 853 defer cleanupFn() 854 855 svc := New(sess) 856 resp, err := svc.StartConversation(nil) 857 if err != nil { 858 t.Fatalf("expect no error got, %v", err) 859 } 860 861 defer resp.GetStream().Close() 862 863 for { 864 err = resp.GetStream().Send(context.Background(), &AudioInputEvent{}) 865 if err != nil { 866 if strings.Contains("unable to send event", err.Error()) { 867 t.Errorf("expected stream closed error, got %v", err) 868 } 869 break 870 } 871 } 872} 873 874func TestStartConversation_ReadWrite(t *testing.T) { 875 expectedServiceEvents, serviceEvents := mockStartConversationReadEvents() 876 clientEvents, expectedClientEvents := mockStartConversationWriteEvents() 877 878 sess, cleanupFn, err := eventstreamtest.SetupEventStreamSession(t, 879 &eventstreamtest.ServeEventStream{ 880 T: t, 881 ClientEvents: expectedClientEvents, 882 Events: serviceEvents, 883 BiDirectional: true, 884 }, 885 true) 886 defer cleanupFn() 887 888 svc := New(sess) 889 resp, err := svc.StartConversation(nil) 890 if err != nil { 891 t.Fatalf("expect no error, got %v", err) 892 } 893 894 stream := resp.GetStream() 895 defer stream.Close() 896 897 var wg sync.WaitGroup 898 899 wg.Add(1) 900 go func() { 901 defer wg.Done() 902 var i int 903 for event := range resp.GetStream().Events() { 904 if event == nil { 905 t.Errorf("%d, expect event, got nil", i) 906 } 907 if e, a := expectedServiceEvents[i], event; !reflect.DeepEqual(e, a) { 908 t.Errorf("%d, expect %T %v, got %T %v", i, e, e, a, a) 909 } 910 i++ 911 } 912 }() 913 914 for _, event := range clientEvents { 915 err = stream.Send(context.Background(), event) 916 if err != nil { 917 t.Errorf("expect no error, got %v", err) 918 } 919 } 920 921 resp.GetStream().Close() 922 923 wg.Wait() 924 925 if err := resp.GetStream().Err(); err != nil { 926 t.Errorf("expect no error, %v", err) 927 } 928} 929 930func mockStartConversationWriteEvents() ( 931 []StartConversationRequestEventStreamEvent, 932 []eventstream.Message, 933) { 934 inputEvents := []StartConversationRequestEventStreamEvent{ 935 &AudioInputEvent{ 936 AudioChunk: []byte("blob value goes here"), 937 ClientTimestampMillis: aws.Int64(1234), 938 ContentType: aws.String("string value goes here"), 939 EventId: aws.String("string value goes here"), 940 }, 941 &ConfigurationEvent{ 942 ClientTimestampMillis: aws.Int64(1234), 943 DisablePlayback: aws.Bool(true), 944 EventId: aws.String("string value goes here"), 945 RequestAttributes: map[string]*string{ 946 "a": aws.String("string value goes here"), 947 "b": aws.String("string value goes here"), 948 "c": aws.String("string value goes here"), 949 }, 950 ResponseContentType: aws.String("string value goes here"), 951 SessionState: &SessionState{ 952 ActiveContexts: []*ActiveContext{ 953 { 954 ContextAttributes: map[string]*string{ 955 "a": aws.String("string value goes here"), 956 "b": aws.String("string value goes here"), 957 "c": aws.String("string value goes here"), 958 }, 959 Name: aws.String("string value goes here"), 960 TimeToLive: &ActiveContextTimeToLive{ 961 TimeToLiveInSeconds: aws.Int64(123), 962 TurnsToLive: aws.Int64(123), 963 }, 964 }, 965 { 966 ContextAttributes: map[string]*string{ 967 "a": aws.String("string value goes here"), 968 "b": aws.String("string value goes here"), 969 "c": aws.String("string value goes here"), 970 }, 971 Name: aws.String("string value goes here"), 972 TimeToLive: &ActiveContextTimeToLive{ 973 TimeToLiveInSeconds: aws.Int64(123), 974 TurnsToLive: aws.Int64(123), 975 }, 976 }, 977 { 978 ContextAttributes: map[string]*string{ 979 "a": aws.String("string value goes here"), 980 "b": aws.String("string value goes here"), 981 "c": aws.String("string value goes here"), 982 }, 983 Name: aws.String("string value goes here"), 984 TimeToLive: &ActiveContextTimeToLive{ 985 TimeToLiveInSeconds: aws.Int64(123), 986 TurnsToLive: aws.Int64(123), 987 }, 988 }, 989 }, 990 DialogAction: &DialogAction{ 991 SlotToElicit: aws.String("string value goes here"), 992 Type: aws.String("string value goes here"), 993 }, 994 Intent: &Intent{ 995 ConfirmationState: aws.String("string value goes here"), 996 Name: aws.String("string value goes here"), 997 Slots: map[string]*Slot{ 998 "a": { 999 Shape: aws.String("string value goes here"), 1000 Value: &Value{ 1001 InterpretedValue: aws.String("string value goes here"), 1002 OriginalValue: aws.String("string value goes here"), 1003 ResolvedValues: []*string{ 1004 aws.String("string value goes here"), 1005 aws.String("string value goes here"), 1006 aws.String("string value goes here"), 1007 }, 1008 }, 1009 Values: []*Slot{}, 1010 }, 1011 "b": { 1012 Shape: aws.String("string value goes here"), 1013 Value: &Value{ 1014 InterpretedValue: aws.String("string value goes here"), 1015 OriginalValue: aws.String("string value goes here"), 1016 ResolvedValues: []*string{ 1017 aws.String("string value goes here"), 1018 aws.String("string value goes here"), 1019 aws.String("string value goes here"), 1020 }, 1021 }, 1022 Values: []*Slot{}, 1023 }, 1024 "c": { 1025 Shape: aws.String("string value goes here"), 1026 Value: &Value{ 1027 InterpretedValue: aws.String("string value goes here"), 1028 OriginalValue: aws.String("string value goes here"), 1029 ResolvedValues: []*string{ 1030 aws.String("string value goes here"), 1031 aws.String("string value goes here"), 1032 aws.String("string value goes here"), 1033 }, 1034 }, 1035 Values: []*Slot{}, 1036 }, 1037 }, 1038 State: aws.String("string value goes here"), 1039 }, 1040 OriginatingRequestId: aws.String("string value goes here"), 1041 SessionAttributes: map[string]*string{ 1042 "a": aws.String("string value goes here"), 1043 "b": aws.String("string value goes here"), 1044 "c": aws.String("string value goes here"), 1045 }, 1046 }, 1047 WelcomeMessages: []*Message{ 1048 { 1049 Content: aws.String("string value goes here"), 1050 ContentType: aws.String("string value goes here"), 1051 ImageResponseCard: &ImageResponseCard{ 1052 Buttons: []*Button{ 1053 { 1054 Text: aws.String("string value goes here"), 1055 Value: aws.String("string value goes here"), 1056 }, 1057 { 1058 Text: aws.String("string value goes here"), 1059 Value: aws.String("string value goes here"), 1060 }, 1061 { 1062 Text: aws.String("string value goes here"), 1063 Value: aws.String("string value goes here"), 1064 }, 1065 }, 1066 ImageUrl: aws.String("string value goes here"), 1067 Subtitle: aws.String("string value goes here"), 1068 Title: aws.String("string value goes here"), 1069 }, 1070 }, 1071 { 1072 Content: aws.String("string value goes here"), 1073 ContentType: aws.String("string value goes here"), 1074 ImageResponseCard: &ImageResponseCard{ 1075 Buttons: []*Button{ 1076 { 1077 Text: aws.String("string value goes here"), 1078 Value: aws.String("string value goes here"), 1079 }, 1080 { 1081 Text: aws.String("string value goes here"), 1082 Value: aws.String("string value goes here"), 1083 }, 1084 { 1085 Text: aws.String("string value goes here"), 1086 Value: aws.String("string value goes here"), 1087 }, 1088 }, 1089 ImageUrl: aws.String("string value goes here"), 1090 Subtitle: aws.String("string value goes here"), 1091 Title: aws.String("string value goes here"), 1092 }, 1093 }, 1094 { 1095 Content: aws.String("string value goes here"), 1096 ContentType: aws.String("string value goes here"), 1097 ImageResponseCard: &ImageResponseCard{ 1098 Buttons: []*Button{ 1099 { 1100 Text: aws.String("string value goes here"), 1101 Value: aws.String("string value goes here"), 1102 }, 1103 { 1104 Text: aws.String("string value goes here"), 1105 Value: aws.String("string value goes here"), 1106 }, 1107 { 1108 Text: aws.String("string value goes here"), 1109 Value: aws.String("string value goes here"), 1110 }, 1111 }, 1112 ImageUrl: aws.String("string value goes here"), 1113 Subtitle: aws.String("string value goes here"), 1114 Title: aws.String("string value goes here"), 1115 }, 1116 }, 1117 }, 1118 }, 1119 &DTMFInputEvent{ 1120 ClientTimestampMillis: aws.Int64(1234), 1121 EventId: aws.String("string value goes here"), 1122 InputCharacter: aws.String("string value goes here"), 1123 }, 1124 &DisconnectionEvent{ 1125 ClientTimestampMillis: aws.Int64(1234), 1126 EventId: aws.String("string value goes here"), 1127 }, 1128 &PlaybackCompletionEvent{ 1129 ClientTimestampMillis: aws.Int64(1234), 1130 EventId: aws.String("string value goes here"), 1131 }, 1132 &TextInputEvent{ 1133 ClientTimestampMillis: aws.Int64(1234), 1134 EventId: aws.String("string value goes here"), 1135 Text: aws.String("string value goes here"), 1136 }, 1137 } 1138 1139 var marshalers request.HandlerList 1140 marshalers.PushBackNamed(restjson.BuildHandler) 1141 payloadMarshaler := protocol.HandlerPayloadMarshal{ 1142 Marshalers: marshalers, 1143 } 1144 _ = payloadMarshaler 1145 1146 eventMsgs := []eventstream.Message{ 1147 { 1148 Headers: eventstream.Headers{ 1149 eventstreamtest.EventMessageTypeHeader, 1150 { 1151 Name: eventstreamapi.EventTypeHeader, 1152 Value: eventstream.StringValue("AudioInputEvent"), 1153 }, 1154 }, 1155 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[0]), 1156 }, 1157 { 1158 Headers: eventstream.Headers{ 1159 eventstreamtest.EventMessageTypeHeader, 1160 { 1161 Name: eventstreamapi.EventTypeHeader, 1162 Value: eventstream.StringValue("ConfigurationEvent"), 1163 }, 1164 }, 1165 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[1]), 1166 }, 1167 { 1168 Headers: eventstream.Headers{ 1169 eventstreamtest.EventMessageTypeHeader, 1170 { 1171 Name: eventstreamapi.EventTypeHeader, 1172 Value: eventstream.StringValue("DTMFInputEvent"), 1173 }, 1174 }, 1175 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[2]), 1176 }, 1177 { 1178 Headers: eventstream.Headers{ 1179 eventstreamtest.EventMessageTypeHeader, 1180 { 1181 Name: eventstreamapi.EventTypeHeader, 1182 Value: eventstream.StringValue("DisconnectionEvent"), 1183 }, 1184 }, 1185 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[3]), 1186 }, 1187 { 1188 Headers: eventstream.Headers{ 1189 eventstreamtest.EventMessageTypeHeader, 1190 { 1191 Name: eventstreamapi.EventTypeHeader, 1192 Value: eventstream.StringValue("PlaybackCompletionEvent"), 1193 }, 1194 }, 1195 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[4]), 1196 }, 1197 { 1198 Headers: eventstream.Headers{ 1199 eventstreamtest.EventMessageTypeHeader, 1200 { 1201 Name: eventstreamapi.EventTypeHeader, 1202 Value: eventstream.StringValue("TextInputEvent"), 1203 }, 1204 }, 1205 Payload: eventstreamtest.MarshalEventPayload(payloadMarshaler, inputEvents[5]), 1206 }, 1207 } 1208 1209 return inputEvents, eventMsgs 1210} 1211