1
1
#include <fcntl.h>
2
2
#include <mongoc/mongoc.h>
3
3
#include <mongoc/mongoc-array-private.h>
4
+ #include <mongoc/mongoc-flags-private.h>
4
5
#include <mongoc/mongoc-rpc-private.h>
5
6
#include <stdio.h>
6
7
#include <stdlib.h>
7
8
#include <string.h>
8
9
9
10
#include "TestSuite.h"
11
+ #include "test-conveniences.h"
10
12
#include "mongoc/mongoc-cluster-private.h"
11
13
12
14
@@ -655,6 +657,143 @@ test_mongoc_rpc_buffer_iov (void)
655
657
}
656
658
657
659
660
+ static void
661
+ test_mongoc_rpc_msg_checksum_gather (mongoc_rpc_t * rpc )
662
+ {
663
+ mongoc_array_t array ;
664
+ _mongoc_array_init (& array , sizeof (mongoc_iovec_t ));
665
+
666
+ _mongoc_rpc_gather (rpc , & array );
667
+ _mongoc_rpc_swab_to_le (rpc );
668
+
669
+ // OP_MSG gather should always ignore the optional checksum.
670
+ ASSERT_CMPSIZE_T (array .len , = = , 7u );
671
+
672
+ const size_t expected_lens [] = {
673
+ 4u , // MsgHeader.messageLength
674
+ 4u , // MsgHeader.requestID
675
+ 4u , // MsgHeader.responseTo
676
+ 4u , // MsgHeader.opCode
677
+ 4u , // OP_MSG.flagBits
678
+ 1u , // OP_MSG.sections[0] Kind
679
+ 11u , // OP_MSG.sections[0] Payload
680
+ };
681
+
682
+ for (size_t i = 0u ; i < array .len ; ++ i ) {
683
+ const size_t expected = expected_lens [i ];
684
+ const size_t actual =
685
+ _mongoc_array_index (& array , mongoc_iovec_t , i ).iov_len ;
686
+
687
+ ASSERT_WITH_MSG (expected == actual ,
688
+ "expected element %zu to have iov_len %zu, got %zu" ,
689
+ i ,
690
+ expected ,
691
+ actual );
692
+ }
693
+
694
+ _mongoc_array_destroy (& array );
695
+ }
696
+
697
+
698
+ static void
699
+ test_mongoc_rpc_msg_checksum (void )
700
+ {
701
+ // OP_MSG scatter should be able to handle absence of checksum.
702
+ {
703
+ // clang-format off
704
+ unsigned char input [] = {
705
+ // OP_MSG.header
706
+ 0x20 , 0x00 , 0x00 , 0x00 , // MsgHeader.messageLength (0x00000020 = 32)
707
+ 0x01 , 0x00 , 0x00 , 0x00 , // MsgHeader.requestID (0x00000001 = 1)
708
+ 0x00 , 0x00 , 0x00 , 0x00 , // MsgHeader.responseTo (0x00000000 = 0)
709
+ 0xdd , 0x07 , 0x00 , 0x00 , // MsgHeader.opCode (0x000007dd = 2013 (OP_MSG))
710
+
711
+ // OP_MSG.flagBits
712
+ 0x00 , 0x00 , 0x00 , 0x00 , // 0x00000000 = MONGOC_MSG_NONE (0)
713
+
714
+ // OP_MSG.sections
715
+ 0x00 , // Kind 0
716
+ 0x0b , 0x00 , 0x00 , 0x00 , // Section size (0x0000000b = 11)
717
+ 0x08 , 0x68 , 0x61 , 0x73 , 0x00 , 0x00 , // Boolean "has" (false)
718
+ 0x00 , // End Byte (empty document)
719
+ };
720
+ // clang-format on
721
+
722
+ mongoc_rpc_t rpc = {._init = 0 };
723
+ ASSERT_WITH_MSG (_mongoc_rpc_scatter (& rpc , input , sizeof (input )),
724
+ "failed to parse OP_MSG without checksum" );
725
+ _mongoc_rpc_swab_from_le (& rpc );
726
+
727
+ ASSERT_CMPSIZE_T ((size_t ) rpc .msg .msg_len , = = , sizeof (input ));
728
+ ASSERT_CMPINT32 (rpc .msg .request_id , = = , 1 );
729
+ ASSERT_CMPINT32 (rpc .msg .response_to , = = , 0 );
730
+ ASSERT_CMPINT32 (rpc .msg .opcode , = = , MONGOC_OPCODE_MSG );
731
+ ASSERT_CMPUINT32 (
732
+ (uint32_t ) rpc .msg .flags , = = , (uint32_t ) MONGOC_MSG_NONE );
733
+ ASSERT_CMPINT32 (rpc .msg .n_sections , = = , 1 );
734
+ ASSERT_CMPINT (rpc .msg .sections -> payload_type , = = , 0 );
735
+ {
736
+ bson_t doc ;
737
+ ASSERT_WITH_MSG (
738
+ _mongoc_rpc_get_first_document (& rpc , & doc ),
739
+ "failed to parse document in OP_MSG without checksum" );
740
+ assert_match_bson (& doc , tmp_bson ("{'has': false}" ), false);
741
+ bson_destroy (& doc );
742
+ }
743
+ ASSERT_CMPUINT32 (rpc .msg .checksum , = = , 0u );
744
+
745
+ test_mongoc_rpc_msg_checksum_gather (& rpc );
746
+ }
747
+
748
+ // OP_MSG scatter should be able to handle presence of checksum.
749
+ {
750
+ // clang-format off
751
+ unsigned char input [] = {
752
+ // OP_MSG.header
753
+ 0x24 , 0x00 , 0x00 , 0x00 , // MsgHeader.messageLength (0x00000024 = 36)
754
+ 0x01 , 0x00 , 0x00 , 0x00 , // MsgHeader.requestID (0x00000001 = 1)
755
+ 0x00 , 0x00 , 0x00 , 0x00 , // MsgHeader.responseTo (0x00000000 = 0)
756
+ 0xdd , 0x07 , 0x00 , 0x00 , // MsgHeader.opCode (0x000007dd = 2013 (OP_MSG))
757
+
758
+ // OP_MSG.flagBits
759
+ 0x01 , 0x00 , 0x00 , 0x00 , // 0x00000001 = MONGOC_MSG_CHECKSUM_PRESENT (1)
760
+
761
+ // OP_MSG.sections
762
+ 0x00 , // Kind 0
763
+ 0x0b , 0x00 , 0x00 , 0x00 , // Section size (0x0000000b = 11)
764
+ 0x08 , 0x68 , 0x61 , 0x73 , 0x00 , 0x01 , // Boolean "has" (true)
765
+ 0x00 , // End Byte (empty document)
766
+ 0x01 , 0x02 , 0x03 , 0x04 , // Checksum (0x04030201 = 67305985)
767
+ };
768
+ // clang-format on
769
+
770
+ mongoc_rpc_t rpc = {._init = 0 };
771
+ ASSERT_WITH_MSG (_mongoc_rpc_scatter (& rpc , input , sizeof (input )),
772
+ "failed to parse OP_MSG with checksum" );
773
+ _mongoc_rpc_swab_from_le (& rpc );
774
+
775
+ ASSERT_CMPSIZE_T ((size_t ) rpc .msg .msg_len , = = , sizeof (input ));
776
+ ASSERT_CMPINT32 (rpc .msg .request_id , = = , 1 );
777
+ ASSERT_CMPINT32 (rpc .msg .response_to , = = , 0 );
778
+ ASSERT_CMPINT32 (rpc .msg .opcode , = = , MONGOC_OPCODE_MSG );
779
+ ASSERT_CMPUINT32 (
780
+ (uint32_t ) rpc .msg .flags , = = , (uint32_t ) MONGOC_MSG_CHECKSUM_PRESENT );
781
+ ASSERT_CMPINT32 (rpc .msg .n_sections , = = , 1 );
782
+ ASSERT_CMPINT (rpc .msg .sections -> payload_type , = = , 0 );
783
+ {
784
+ bson_t doc ;
785
+ ASSERT_WITH_MSG (_mongoc_rpc_get_first_document (& rpc , & doc ),
786
+ "failed to parse document in OP_MSG with checksum" );
787
+ assert_match_bson (& doc , tmp_bson ("{'has': true}" ), false);
788
+ bson_destroy (& doc );
789
+ }
790
+ ASSERT_CMPUINT32 (rpc .msg .checksum , = = , 67305985 );
791
+
792
+ test_mongoc_rpc_msg_checksum_gather (& rpc );
793
+ }
794
+ }
795
+
796
+
658
797
void
659
798
test_rpc_install (TestSuite * suite )
660
799
{
@@ -678,4 +817,5 @@ test_rpc_install (TestSuite *suite)
678
817
TestSuite_Add (suite , "/Rpc/update/gather" , test_mongoc_rpc_update_gather );
679
818
TestSuite_Add (suite , "/Rpc/update/scatter" , test_mongoc_rpc_update_scatter );
680
819
TestSuite_Add (suite , "/Rpc/buffer/iov" , test_mongoc_rpc_buffer_iov );
820
+ TestSuite_Add (suite , "/Rpc/msg/checksum" , test_mongoc_rpc_msg_checksum );
681
821
}
0 commit comments