1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #include <string>
32 
33 #include "mongo/bson/util/builder.h"
34 #include "mongo/db/dbmessage.h"
35 #include "mongo/unittest/unittest.h"
36 
37 namespace mongo {
38 using std::string;
39 
40 // Test if the reserved field is short of 4 bytes
TEST(DBMessage1,ShortFlags)41 TEST(DBMessage1, ShortFlags) {
42     BufBuilder b;
43     string ns("test");
44 
45     b.appendChar(1);
46 
47     Message toSend;
48     toSend.setData(dbDelete, b.buf(), b.len());
49 
50     ASSERT_THROWS(DbMessage d1(toSend), AssertionException);
51 }
52 
53 // Test a short NS missing a trailing null
TEST(DBMessage1,BadNS)54 TEST(DBMessage1, BadNS) {
55     BufBuilder b;
56 
57     b.appendNum(static_cast<int>(1));
58     b.appendChar('b');
59     b.appendChar('a');
60     b.appendChar('d');
61     // Forget to append \0
62 
63     Message toSend;
64     toSend.setData(dbDelete, b.buf(), b.len());
65 
66     ASSERT_THROWS(DbMessage d1(toSend), AssertionException);
67 }
68 
69 // Test a valid kill message and try an extra pull
TEST(DBMessage1,GoodKill)70 TEST(DBMessage1, GoodKill) {
71     BufBuilder b;
72 
73     b.appendNum(static_cast<int>(1));
74     b.appendNum(static_cast<int>(3));
75 
76     Message toSend;
77     toSend.setData(dbKillCursors, b.buf(), b.len());
78 
79     DbMessage d1(toSend);
80     ASSERT_EQUALS(3, d1.pullInt());
81 
82     ASSERT_THROWS(d1.pullInt(), AssertionException);
83 }
84 
85 // Try a bad read of a type too large
TEST(DBMessage1,GoodKill2)86 TEST(DBMessage1, GoodKill2) {
87     BufBuilder b;
88 
89     b.appendNum(static_cast<int>(1));
90     b.appendNum(static_cast<int>(3));
91 
92     Message toSend;
93     toSend.setData(dbKillCursors, b.buf(), b.len());
94 
95     DbMessage d1(toSend);
96     ASSERT_THROWS(d1.pullInt64(), AssertionException);
97 }
98 
99 // Test a basic good insert, and an extra read
TEST(DBMessage1,GoodInsert)100 TEST(DBMessage1, GoodInsert) {
101     BufBuilder b;
102     string ns("test");
103 
104     b.appendNum(static_cast<int>(1));
105     b.appendStr(ns);
106     b.appendNum(static_cast<int>(3));
107     b.appendNum(static_cast<int>(39));
108 
109     Message toSend;
110     toSend.setData(dbInsert, b.buf(), b.len());
111 
112     DbMessage d1(toSend);
113     ASSERT_EQUALS(3, d1.pullInt());
114     ASSERT_EQUALS(39, d1.pullInt());
115     ASSERT_THROWS(d1.pullInt(), AssertionException);
116 }
117 
118 // Test a basic good insert, and an extra read
TEST(DBMessage1,GoodInsert2)119 TEST(DBMessage1, GoodInsert2) {
120     BufBuilder b;
121     string ns("test");
122 
123     b.appendNum(static_cast<int>(1));
124     b.appendStr(ns);
125     b.appendNum(static_cast<int>(3));
126     b.appendNum(static_cast<int>(39));
127 
128     BSONObj bo = BSON("ts" << 0);
129     bo.appendSelfToBufBuilder(b);
130 
131     Message toSend;
132     toSend.setData(dbInsert, b.buf(), b.len());
133 
134     DbMessage d1(toSend);
135     ASSERT_EQUALS(3, d1.pullInt());
136 
137 
138     ASSERT_EQUALS(39, d1.pullInt());
139     BSONObj bo2 = d1.nextJsObj();
140     ASSERT_THROWS(d1.nextJsObj(), AssertionException);
141 }
142 
143 
144 }  // mongo namespace
145