2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
29 "github.com/golang/mock/gomock"
32 // TestCase: Comprehensive call and reply workflow in the client.
33 // Setup mock to fail at a certain position. Return true if position exists otherwise false.
34 func prepareClientCallReply(protocol *MockTProtocol, failAt int, failWith error) bool {
40 last := protocol.EXPECT().WriteMessageBegin("testStruct", thrift.CALL, int32(1)).Return(err)
47 last = protocol.EXPECT().WriteStructBegin("testStruct_args").Return(err).After(last)
54 last = protocol.EXPECT().WriteFieldBegin("thing", thrift.TType(thrift.STRUCT), int16(1)).Return(err).After(last)
61 last = protocol.EXPECT().WriteStructBegin("TestStruct").Return(err).After(last)
68 last = protocol.EXPECT().WriteFieldBegin("m", thrift.TType(thrift.MAP), int16(1)).Return(err).After(last)
75 last = protocol.EXPECT().WriteMapBegin(thrift.TType(thrift.STRING), thrift.TType(thrift.STRING), 0).Return(err).After(last)
82 last = protocol.EXPECT().WriteMapEnd().Return(err).After(last)
89 last = protocol.EXPECT().WriteFieldEnd().Return(err).After(last)
96 last = protocol.EXPECT().WriteFieldBegin("l", thrift.TType(thrift.LIST), int16(2)).Return(err).After(last)
103 last = protocol.EXPECT().WriteListBegin(thrift.TType(thrift.STRING), 0).Return(err).After(last)
110 last = protocol.EXPECT().WriteListEnd().Return(err).After(last)
117 last = protocol.EXPECT().WriteFieldEnd().Return(err).After(last)
125 last = protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.SET), int16(3)).Return(err).After(last)
132 last = protocol.EXPECT().WriteSetBegin(thrift.TType(thrift.STRING), 0).Return(err).After(last)
139 last = protocol.EXPECT().WriteSetEnd().Return(err).After(last)
146 last = protocol.EXPECT().WriteFieldEnd().Return(err).After(last)
153 last = protocol.EXPECT().WriteFieldBegin("i", thrift.TType(thrift.I32), int16(4)).Return(err).After(last)
160 last = protocol.EXPECT().WriteI32(int32(3)).Return(err).After(last)
167 last = protocol.EXPECT().WriteFieldEnd().Return(err).After(last)
174 last = protocol.EXPECT().WriteFieldStop().Return(err).After(last)
181 last = protocol.EXPECT().WriteStructEnd().Return(err).After(last)
188 last = protocol.EXPECT().WriteFieldEnd().Return(err).After(last)
195 last = protocol.EXPECT().WriteFieldStop().Return(err).After(last)
202 last = protocol.EXPECT().WriteStructEnd().Return(err).After(last)
209 last = protocol.EXPECT().WriteMessageEnd().Return(err).After(last)
216 last = protocol.EXPECT().Flush(context.Background()).Return(err).After(last)
223 last = protocol.EXPECT().ReadMessageBegin().Return("testStruct", thrift.REPLY, int32(1), err).After(last)
230 last = protocol.EXPECT().ReadStructBegin().Return("testStruct_args", err).After(last)
237 last = protocol.EXPECT().ReadFieldBegin().Return("_", thrift.TType(thrift.STRUCT), int16(0), err).After(last)
244 last = protocol.EXPECT().ReadStructBegin().Return("TestStruct", err).After(last)
251 last = protocol.EXPECT().ReadFieldBegin().Return("m", thrift.TType(thrift.MAP), int16(1), err).After(last)
258 last = protocol.EXPECT().ReadMapBegin().Return(thrift.TType(thrift.STRING), thrift.TType(thrift.STRING), 0, err).After(last)
265 last = protocol.EXPECT().ReadMapEnd().Return(err).After(last)
272 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
279 last = protocol.EXPECT().ReadFieldBegin().Return("l", thrift.TType(thrift.LIST), int16(2), err).After(last)
286 last = protocol.EXPECT().ReadListBegin().Return(thrift.TType(thrift.STRING), 0, err).After(last)
293 last = protocol.EXPECT().ReadListEnd().Return(err).After(last)
300 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
307 last = protocol.EXPECT().ReadFieldBegin().Return("s", thrift.TType(thrift.SET), int16(3), err).After(last)
314 last = protocol.EXPECT().ReadSetBegin().Return(thrift.TType(thrift.STRING), 0, err).After(last)
321 last = protocol.EXPECT().ReadSetEnd().Return(err).After(last)
328 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
335 last = protocol.EXPECT().ReadFieldBegin().Return("i", thrift.TType(thrift.I32), int16(4), err).After(last)
342 last = protocol.EXPECT().ReadI32().Return(int32(3), err).After(last)
349 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
356 last = protocol.EXPECT().ReadFieldBegin().Return("_", thrift.TType(thrift.STOP), int16(5), err).After(last)
363 last = protocol.EXPECT().ReadStructEnd().Return(err).After(last)
370 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
377 last = protocol.EXPECT().ReadFieldBegin().Return("_", thrift.TType(thrift.STOP), int16(1), err).After(last)
384 last = protocol.EXPECT().ReadStructEnd().Return(err).After(last)
391 last = protocol.EXPECT().ReadMessageEnd().Return(err).After(last)
398 // TestCase: Comprehensive call and reply workflow in the client.
399 // Expecting TTransportError on fail.
400 func TestClientReportTTransportErrors(t *testing.T) {
401 mockCtrl := gomock.NewController(t)
403 thing := errortest.NewTestStruct()
404 thing.M = make(map[string]string)
405 thing.L = make([]string, 0)
406 thing.S = make([]string, 0)
409 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test")
411 protocol := NewMockTProtocol(mockCtrl)
412 if !prepareClientCallReply(protocol, i, err) {
415 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
416 _, retErr := client.TestStruct(defaultCtx, thing)
418 mockCtrl = gomock.NewController(t)
419 err2, ok := retErr.(thrift.TTransportException)
421 t.Fatal("Expected a TTrasportException")
424 if err2.TypeId() != thrift.TIMED_OUT {
425 t.Fatal("Expected TIMED_OUT error")
430 // TestCase: Comprehensive call and reply workflow in the client.
431 // Expecting TTransportError on fail.
432 // Similar to TestClientReportTTransportErrors, but using legacy client constructor.
433 func TestClientReportTTransportErrorsLegacy(t *testing.T) {
434 mockCtrl := gomock.NewController(t)
435 transport := thrift.NewTMemoryBuffer()
436 thing := errortest.NewTestStruct()
437 thing.M = make(map[string]string)
438 thing.L = make([]string, 0)
439 thing.S = make([]string, 0)
442 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test")
444 protocol := NewMockTProtocol(mockCtrl)
445 if !prepareClientCallReply(protocol, i, err) {
448 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
449 _, retErr := client.TestStruct(defaultCtx, thing)
451 mockCtrl = gomock.NewController(t)
452 err2, ok := retErr.(thrift.TTransportException)
454 t.Fatal("Expected a TTrasportException")
457 if err2.TypeId() != thrift.TIMED_OUT {
458 t.Fatal("Expected TIMED_OUT error")
463 // TestCase: Comprehensive call and reply workflow in the client.
464 // Expecting TTProtocolErrors on fail.
465 func TestClientReportTProtocolErrors(t *testing.T) {
466 mockCtrl := gomock.NewController(t)
468 thing := errortest.NewTestStruct()
469 thing.M = make(map[string]string)
470 thing.L = make([]string, 0)
471 thing.S = make([]string, 0)
474 err := thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, errors.New("test"))
476 protocol := NewMockTProtocol(mockCtrl)
477 if !prepareClientCallReply(protocol, i, err) {
480 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
481 _, retErr := client.TestStruct(defaultCtx, thing)
483 mockCtrl = gomock.NewController(t)
484 err2, ok := retErr.(thrift.TProtocolException)
486 t.Fatal("Expected a TProtocolException")
488 if err2.TypeId() != thrift.INVALID_DATA {
489 t.Fatal("Expected INVALID_DATA error")
494 // TestCase: Comprehensive call and reply workflow in the client.
495 // Expecting TTProtocolErrors on fail.
496 // Similar to TestClientReportTProtocolErrors, but using legacy client constructor.
497 func TestClientReportTProtocolErrorsLegacy(t *testing.T) {
498 mockCtrl := gomock.NewController(t)
499 transport := thrift.NewTMemoryBuffer()
500 thing := errortest.NewTestStruct()
501 thing.M = make(map[string]string)
502 thing.L = make([]string, 0)
503 thing.S = make([]string, 0)
506 err := thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, errors.New("test"))
508 protocol := NewMockTProtocol(mockCtrl)
509 if !prepareClientCallReply(protocol, i, err) {
512 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
513 _, retErr := client.TestStruct(defaultCtx, thing)
515 mockCtrl = gomock.NewController(t)
516 err2, ok := retErr.(thrift.TProtocolException)
518 t.Fatal("Expected a TProtocolException")
520 if err2.TypeId() != thrift.INVALID_DATA {
521 t.Fatal("Expected INVALID_DATA error")
526 // TestCase: call and reply with exception workflow in the client.
527 // Setup mock to fail at a certain position. Return true if position exists otherwise false.
528 func prepareClientCallException(protocol *MockTProtocol, failAt int, failWith error) bool {
531 // No need to test failure in this block, because it is covered in other test cases
532 last := protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1))
533 last = protocol.EXPECT().WriteStructBegin("testString_args").After(last)
534 last = protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)).After(last)
535 last = protocol.EXPECT().WriteString("test").After(last)
536 last = protocol.EXPECT().WriteFieldEnd().After(last)
537 last = protocol.EXPECT().WriteFieldStop().After(last)
538 last = protocol.EXPECT().WriteStructEnd().After(last)
539 last = protocol.EXPECT().WriteMessageEnd().After(last)
540 last = protocol.EXPECT().Flush(context.Background()).After(last)
542 // Reading the exception, might fail.
546 last = protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.EXCEPTION, int32(1), err).After(last)
553 last = protocol.EXPECT().ReadStructBegin().Return("TApplicationException", err).After(last)
560 last = protocol.EXPECT().ReadFieldBegin().Return("message", thrift.TType(thrift.STRING), int16(1), err).After(last)
567 last = protocol.EXPECT().ReadString().Return("test", err).After(last)
574 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
581 last = protocol.EXPECT().ReadFieldBegin().Return("type", thrift.TType(thrift.I32), int16(2), err).After(last)
588 last = protocol.EXPECT().ReadI32().Return(int32(thrift.PROTOCOL_ERROR), err).After(last)
595 last = protocol.EXPECT().ReadFieldEnd().Return(err).After(last)
602 last = protocol.EXPECT().ReadFieldBegin().Return("_", thrift.TType(thrift.STOP), int16(2), err).After(last)
609 last = protocol.EXPECT().ReadStructEnd().Return(err).After(last)
616 last = protocol.EXPECT().ReadMessageEnd().Return(err).After(last)
624 // TestCase: call and reply with exception workflow in the client.
625 func TestClientCallException(t *testing.T) {
626 mockCtrl := gomock.NewController(t)
628 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test")
630 protocol := NewMockTProtocol(mockCtrl)
631 willComplete := !prepareClientCallException(protocol, i, err)
633 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
634 _, retErr := client.TestString(defaultCtx, "test")
636 mockCtrl = gomock.NewController(t)
639 err2, ok := retErr.(thrift.TTransportException)
641 t.Fatal("Expected a TTransportException")
643 if err2.TypeId() != thrift.TIMED_OUT {
644 t.Fatal("Expected TIMED_OUT error")
647 err2, ok := retErr.(thrift.TApplicationException)
649 t.Fatal("Expected a TApplicationException")
651 if err2.TypeId() != thrift.PROTOCOL_ERROR {
652 t.Fatal("Expected PROTOCOL_ERROR error")
659 // TestCase: call and reply with exception workflow in the client.
660 // Similar to TestClientCallException, but using legacy client constructor.
661 func TestClientCallExceptionLegacy(t *testing.T) {
662 mockCtrl := gomock.NewController(t)
663 transport := thrift.NewTMemoryBuffer()
664 err := thrift.NewTTransportException(thrift.TIMED_OUT, "test")
666 protocol := NewMockTProtocol(mockCtrl)
667 willComplete := !prepareClientCallException(protocol, i, err)
669 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
670 _, retErr := client.TestString(defaultCtx, "test")
672 mockCtrl = gomock.NewController(t)
675 err2, ok := retErr.(thrift.TTransportException)
677 t.Fatal("Expected a TTransportException")
679 if err2.TypeId() != thrift.TIMED_OUT {
680 t.Fatal("Expected TIMED_OUT error")
683 err2, ok := retErr.(thrift.TApplicationException)
685 t.Fatal("Expected a TApplicationException")
687 if err2.TypeId() != thrift.PROTOCOL_ERROR {
688 t.Fatal("Expected PROTOCOL_ERROR error")
695 // TestCase: Mismatching sequence id has been received in the client.
696 func TestClientSeqIdMismatch(t *testing.T) {
697 mockCtrl := gomock.NewController(t)
698 protocol := NewMockTProtocol(mockCtrl)
700 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
701 protocol.EXPECT().WriteStructBegin("testString_args"),
702 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
703 protocol.EXPECT().WriteString("test"),
704 protocol.EXPECT().WriteFieldEnd(),
705 protocol.EXPECT().WriteFieldStop(),
706 protocol.EXPECT().WriteStructEnd(),
707 protocol.EXPECT().WriteMessageEnd(),
708 protocol.EXPECT().Flush(context.Background()),
709 protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil),
712 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
713 _, err := client.TestString(defaultCtx, "test")
715 appErr, ok := err.(thrift.TApplicationException)
717 t.Fatal("Expected TApplicationException")
719 if appErr.TypeId() != thrift.BAD_SEQUENCE_ID {
720 t.Fatal("Expected BAD_SEQUENCE_ID error")
724 // TestCase: Mismatching sequence id has been received in the client.
725 // Similar to TestClientSeqIdMismatch, but using legacy client constructor.
726 func TestClientSeqIdMismatchLegeacy(t *testing.T) {
727 mockCtrl := gomock.NewController(t)
728 transport := thrift.NewTMemoryBuffer()
729 protocol := NewMockTProtocol(mockCtrl)
731 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
732 protocol.EXPECT().WriteStructBegin("testString_args"),
733 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
734 protocol.EXPECT().WriteString("test"),
735 protocol.EXPECT().WriteFieldEnd(),
736 protocol.EXPECT().WriteFieldStop(),
737 protocol.EXPECT().WriteStructEnd(),
738 protocol.EXPECT().WriteMessageEnd(),
739 protocol.EXPECT().Flush(context.Background()),
740 protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil),
743 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
744 _, err := client.TestString(defaultCtx, "test")
746 appErr, ok := err.(thrift.TApplicationException)
748 t.Fatal("Expected TApplicationException")
750 if appErr.TypeId() != thrift.BAD_SEQUENCE_ID {
751 t.Fatal("Expected BAD_SEQUENCE_ID error")
755 // TestCase: Wrong method name has been received in the client.
756 func TestClientWrongMethodName(t *testing.T) {
757 mockCtrl := gomock.NewController(t)
758 protocol := NewMockTProtocol(mockCtrl)
760 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
761 protocol.EXPECT().WriteStructBegin("testString_args"),
762 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
763 protocol.EXPECT().WriteString("test"),
764 protocol.EXPECT().WriteFieldEnd(),
765 protocol.EXPECT().WriteFieldStop(),
766 protocol.EXPECT().WriteStructEnd(),
767 protocol.EXPECT().WriteMessageEnd(),
768 protocol.EXPECT().Flush(context.Background()),
769 protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil),
772 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
773 _, err := client.TestString(defaultCtx, "test")
775 appErr, ok := err.(thrift.TApplicationException)
777 t.Fatal("Expected TApplicationException")
779 if appErr.TypeId() != thrift.WRONG_METHOD_NAME {
780 t.Fatal("Expected WRONG_METHOD_NAME error")
784 // TestCase: Wrong method name has been received in the client.
785 // Similar to TestClientWrongMethodName, but using legacy client constructor.
786 func TestClientWrongMethodNameLegacy(t *testing.T) {
787 mockCtrl := gomock.NewController(t)
788 transport := thrift.NewTMemoryBuffer()
789 protocol := NewMockTProtocol(mockCtrl)
791 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
792 protocol.EXPECT().WriteStructBegin("testString_args"),
793 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
794 protocol.EXPECT().WriteString("test"),
795 protocol.EXPECT().WriteFieldEnd(),
796 protocol.EXPECT().WriteFieldStop(),
797 protocol.EXPECT().WriteStructEnd(),
798 protocol.EXPECT().WriteMessageEnd(),
799 protocol.EXPECT().Flush(context.Background()),
800 protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil),
803 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
804 _, err := client.TestString(defaultCtx, "test")
806 appErr, ok := err.(thrift.TApplicationException)
808 t.Fatal("Expected TApplicationException")
810 if appErr.TypeId() != thrift.WRONG_METHOD_NAME {
811 t.Fatal("Expected WRONG_METHOD_NAME error")
815 // TestCase: Wrong message type has been received in the client.
816 func TestClientWrongMessageType(t *testing.T) {
817 mockCtrl := gomock.NewController(t)
818 protocol := NewMockTProtocol(mockCtrl)
820 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
821 protocol.EXPECT().WriteStructBegin("testString_args"),
822 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
823 protocol.EXPECT().WriteString("test"),
824 protocol.EXPECT().WriteFieldEnd(),
825 protocol.EXPECT().WriteFieldStop(),
826 protocol.EXPECT().WriteStructEnd(),
827 protocol.EXPECT().WriteMessageEnd(),
828 protocol.EXPECT().Flush(context.Background()),
829 protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil),
832 client := errortest.NewErrorTestClient(thrift.NewTStandardClient(protocol, protocol))
833 _, err := client.TestString(defaultCtx, "test")
835 appErr, ok := err.(thrift.TApplicationException)
837 t.Fatal("Expected TApplicationException")
839 if appErr.TypeId() != thrift.INVALID_MESSAGE_TYPE_EXCEPTION {
840 t.Fatal("Expected INVALID_MESSAGE_TYPE_EXCEPTION error")
844 // TestCase: Wrong message type has been received in the client.
845 // Similar to TestClientWrongMessageType, but using legacy client constructor.
846 func TestClientWrongMessageTypeLegacy(t *testing.T) {
847 mockCtrl := gomock.NewController(t)
848 transport := thrift.NewTMemoryBuffer()
849 protocol := NewMockTProtocol(mockCtrl)
851 protocol.EXPECT().WriteMessageBegin("testString", thrift.CALL, int32(1)),
852 protocol.EXPECT().WriteStructBegin("testString_args"),
853 protocol.EXPECT().WriteFieldBegin("s", thrift.TType(thrift.STRING), int16(1)),
854 protocol.EXPECT().WriteString("test"),
855 protocol.EXPECT().WriteFieldEnd(),
856 protocol.EXPECT().WriteFieldStop(),
857 protocol.EXPECT().WriteStructEnd(),
858 protocol.EXPECT().WriteMessageEnd(),
859 protocol.EXPECT().Flush(context.Background()),
860 protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil),
863 client := errortest.NewErrorTestClientProtocol(transport, protocol, protocol)
864 _, err := client.TestString(defaultCtx, "test")
866 appErr, ok := err.(thrift.TApplicationException)
868 t.Fatal("Expected TApplicationException")
870 if appErr.TypeId() != thrift.INVALID_MESSAGE_TYPE_EXCEPTION {
871 t.Fatal("Expected INVALID_MESSAGE_TYPE_EXCEPTION error")