1 /*
2 Copyright (c) DataStax, Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #include "unit.hpp"
18
19 #include "query_request.hpp"
20 #include "session.hpp"
21 #include "tracing_data_handler.hpp"
22
23 using namespace datastax::internal::core;
24
25 class TracingUnitTest : public Unit {
26 public:
TearDown()27 void TearDown() {
28 ASSERT_TRUE(session.close()->wait_for(WAIT_FOR_TIME));
29 Unit::TearDown();
30 }
31
connect(const Config & config=Config ())32 void connect(const Config& config = Config()) {
33 Config temp(config);
34 temp.contact_points().push_back(Address("127.0.0.1", 9042));
35 Future::Ptr connect_future(session.connect(temp));
36 ASSERT_TRUE(connect_future->wait_for(WAIT_FOR_TIME))
37 << "Timed out waiting for session to connect";
38 ASSERT_FALSE(connect_future->error()) << cass_error_desc(connect_future->error()->code) << ": "
39 << connect_future->error()->message;
40 }
41
42 Session session;
43 };
44
TEST_F(TracingUnitTest,Simple)45 TEST_F(TracingUnitTest, Simple) {
46 mockssandra::SimpleRequestHandlerBuilder builder;
47 builder.on(mockssandra::OPCODE_QUERY)
48 .system_local()
49 .system_peers()
50 .system_traces()
51 .empty_rows_result(1);
52 mockssandra::SimpleCluster cluster(builder.build());
53 ASSERT_EQ(cluster.start_all(), 0);
54
55 connect();
56
57 Statement::Ptr request(new QueryRequest("blah", 0));
58 request->set_tracing(true);
59
60 ResponseFuture::Ptr future(session.execute(Request::ConstPtr(request)));
61 future->wait();
62
63 ASSERT_TRUE(future->response());
64 EXPECT_TRUE(future->response()->has_tracing_id());
65
66 CassUuid tracing_id(future->response()->tracing_id());
67 EXPECT_NE(tracing_id.time_and_version, 0u);
68 }
69
TEST_F(TracingUnitTest,DataNotAvailble)70 TEST_F(TracingUnitTest, DataNotAvailble) {
71 mockssandra::SimpleRequestHandlerBuilder builder;
72 builder.on(mockssandra::OPCODE_QUERY)
73 .system_local()
74 .system_peers()
75 .is_query(SELECT_TRACES_SESSION)
76 .then(mockssandra::Action::Builder().empty_rows_result(0)) // Send back an empty row result
77 .empty_rows_result(1);
78 mockssandra::SimpleCluster cluster(builder.build());
79 ASSERT_EQ(cluster.start_all(), 0);
80
81 connect();
82
83 Statement::Ptr request(new QueryRequest("blah", 0));
84 request->set_tracing(true);
85
86 add_logging_critera("Tracing data not available after 15 ms");
87
88 ResponseFuture::Ptr future(session.execute(Request::ConstPtr(request)));
89 future->wait();
90
91 ASSERT_TRUE(future->response());
92 EXPECT_TRUE(future->response()->has_tracing_id());
93
94 CassUuid tracing_id(future->response()->tracing_id());
95 EXPECT_NE(tracing_id.time_and_version, 0u);
96
97 EXPECT_GT(logging_criteria_count(), 0);
98 }
99
TEST_F(TracingUnitTest,RequestTimeout)100 TEST_F(TracingUnitTest, RequestTimeout) {
101 mockssandra::SimpleRequestHandlerBuilder builder;
102 builder.on(mockssandra::OPCODE_QUERY)
103 .system_local()
104 .system_peers()
105 .is_query(SELECT_TRACES_SESSION)
106 .then(mockssandra::Action::Builder().no_result()) // Don't send back a response
107 .empty_rows_result(1);
108 mockssandra::SimpleCluster cluster(builder.build());
109 ASSERT_EQ(cluster.start_all(), 0);
110
111 Config config;
112 config.set_max_tracing_wait_time_ms(500);
113 connect(config);
114
115 Statement::Ptr request(new QueryRequest("blah", 0));
116 request->set_request_timeout_ms(100);
117 request->set_tracing(true);
118
119 add_logging_critera("A query timeout occurred waiting for tracing data to become available");
120
121 ResponseFuture::Ptr future(session.execute(Request::ConstPtr(request)));
122 future->wait();
123
124 ASSERT_TRUE(future->response());
125 EXPECT_TRUE(future->response()->has_tracing_id());
126
127 CassUuid tracing_id(future->response()->tracing_id());
128 EXPECT_NE(tracing_id.time_and_version, 0u);
129
130 EXPECT_GT(logging_criteria_count(), 0);
131 }
132
TEST_F(TracingUnitTest,QueryError)133 TEST_F(TracingUnitTest, QueryError) {
134 mockssandra::SimpleRequestHandlerBuilder builder;
135 builder.on(mockssandra::OPCODE_QUERY)
136 .system_local()
137 .system_peers()
138 .is_query(SELECT_TRACES_SESSION)
139 .then(mockssandra::Action::Builder().error(mockssandra::ERROR_INVALID_QUERY, "Invalid query"))
140 .empty_rows_result(1);
141 mockssandra::SimpleCluster cluster(builder.build());
142 ASSERT_EQ(cluster.start_all(), 0);
143
144 connect();
145
146 Statement::Ptr request(new QueryRequest("blah", 0));
147 request->set_tracing(true);
148
149 add_logging_critera("Chained error response 'Invalid query' (0x02002200) for query "
150 "\"SELECT session_id FROM system_traces.sessions WHERE session_id = ?\"");
151
152 ResponseFuture::Ptr future(session.execute(Request::ConstPtr(request)));
153 future->wait();
154
155 ASSERT_TRUE(future->response());
156 EXPECT_TRUE(future->response()->has_tracing_id());
157
158 CassUuid tracing_id(future->response()->tracing_id());
159 EXPECT_NE(tracing_id.time_and_version, 0u);
160
161 EXPECT_GT(logging_criteria_count(), 0);
162 }
163