1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 
19 /**
20  * In this file you'll find unit tests related to the DCP subsystem
21  */
22 
23 #include "testapp.h"
24 #include "testapp_client_test.h"
25 
26 #include <xattr/blob.h>
27 #include <xattr/utils.h>
28 
29 class DcpTest : public TestappClientTest {
30 
31 };
32 
33 INSTANTIATE_TEST_CASE_P(TransportProtocols,
34                         DcpTest,
35                         ::testing::Values(TransportProtocols::McbpPlain,
36                                           TransportProtocols::McbpIpv6Plain,
37                                           TransportProtocols::McbpSsl,
38                                           TransportProtocols::McbpIpv6Ssl
39                                          ),
40                         ::testing::PrintToStringParamName());
41 
TEST_P(DcpTest, TestDcpOpenCantBeProducerAndConsumer)42 TEST_P(DcpTest, TestDcpOpenCantBeProducerAndConsumer) {
43     auto& conn = getConnection();
44 
45     conn.sendCommand(BinprotDcpOpenCommand{"ewb_internal:1", 0,
46                                            DCP_OPEN_PRODUCER |
47                                            DCP_OPEN_NOTIFIER});
48 
49     BinprotResponse rsp;
50     conn.recvResponse(rsp);
51     EXPECT_FALSE(rsp.isSuccess());
52     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_EINVAL, rsp.getStatus());
53 }
54 
TEST_P(DcpTest, TestDcpNotfierCantBeNoValue)55 TEST_P(DcpTest, TestDcpNotfierCantBeNoValue) {
56     auto& conn = getConnection();
57 
58     conn.sendCommand(BinprotDcpOpenCommand{"ewb_internal:1", 0,
59                                            DCP_OPEN_NO_VALUE |
60                                            DCP_OPEN_NOTIFIER});
61 
62     BinprotResponse rsp;
63     conn.recvResponse(rsp);
64     EXPECT_FALSE(rsp.isSuccess());
65     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_EINVAL, rsp.getStatus());
66 }
67 
TEST_P(DcpTest, TestDcpNotfierCantIncludeXattrs)68 TEST_P(DcpTest, TestDcpNotfierCantIncludeXattrs) {
69     auto& conn = getConnection();
70 
71     conn.sendCommand(BinprotDcpOpenCommand{"ewb_internal:1", 0,
72                                            DCP_OPEN_INCLUDE_XATTRS |
73                                            DCP_OPEN_NOTIFIER});
74 
75     BinprotResponse rsp;
76     conn.recvResponse(rsp);
77     EXPECT_FALSE(rsp.isSuccess());
78     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_EINVAL, rsp.getStatus());
79 }
80 
81 /**
82  * Make sure that the rollback sequence number in the response isn't being
83  * stripped / replaced with an error object
84  */
TEST_P(DcpTest, MB24145_RollbackShouldContainSeqno)85 TEST_P(DcpTest, MB24145_RollbackShouldContainSeqno) {
86     auto& conn = getConnection();
87 
88     conn.sendCommand(BinprotDcpOpenCommand{"ewb_internal:1", 0,
89                                            DCP_OPEN_PRODUCER});
90 
91     BinprotResponse rsp;
92     conn.recvResponse(rsp);
93     ASSERT_TRUE(rsp.isSuccess());
94 
95     BinprotDcpStreamRequestCommand streamReq;
96     streamReq.setDcpStartSeqno(1);
97     conn.sendCommand(streamReq);
98     conn.recvResponse(rsp);
99     ASSERT_FALSE(rsp.isSuccess());
100 
101     auto data = rsp.getData();
102     ASSERT_EQ(sizeof(uint64_t), data.size());
103     auto* value = reinterpret_cast<const uint64_t*>(data.data());
104     EXPECT_EQ(0, *value);
105 
106 }
107 
TEST_P(DcpTest, UnorderedExecutionNotSupported)108 TEST_P(DcpTest, UnorderedExecutionNotSupported) {
109     // Verify that it isn't possible to run a DCP open command
110     // on a connection which is set to unordered execution mode.
111     // Ideally we should have verified each of the available DCP
112     // packets, but our test framework does not have methods to
113     // create all of them. The DCP validators does however
114     // all call a common validator method to check this
115     // restriction. Once the full DCP test suite is implemented
116     // we should extend this test to validate all of the
117     // various commands.
118     auto& conn = getConnection();
119     conn.setUnorderedExecutionMode(ExecutionMode::Unordered);
120     conn.sendCommand(BinprotDcpOpenCommand{"ewb_internal:1", 0,
121                                            DCP_OPEN_PRODUCER});
122 
123     BinprotResponse rsp;
124     conn.recvResponse(rsp);
125     EXPECT_FALSE(rsp.isSuccess());
126     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED, rsp.getStatus());
127 }
128