blob: 533703a2bec08b36e9a9322dcddcc3780156d545 [file] [log] [blame]
ncteisenb8a52e02018-06-07 18:58:03 -07001/*
2 *
3 * Copyright 2015 gRPC authors.
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#include "test/core/end2end/end2end_tests.h"
20
21#include <stdio.h>
22#include <string.h>
23
24#include "src/core/lib/surface/channel.h"
25
26#include <grpc/byte_buffer.h>
27#include <grpc/grpc.h>
28#include <grpc/support/alloc.h>
29#include <grpc/support/log.h>
30#include <grpc/support/time.h>
31#include "src/core/lib/gpr/string.h"
32#include "test/core/end2end/cq_verifier.h"
33
34static void* tag(intptr_t t) { return (void*)t; }
35
36static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
37 const char* test_name,
38 grpc_channel_args* client_args,
39 grpc_channel_args* server_args) {
40 grpc_end2end_test_fixture f;
41 gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
42 f = config.create_fixture(client_args, server_args);
43 config.init_server(&f, server_args);
44 config.init_client(&f, client_args);
45 return f;
46}
47
48static gpr_timespec n_seconds_from_now(int n) {
49 return grpc_timeout_seconds_to_deadline(n);
50}
51
52static gpr_timespec five_seconds_from_now(void) {
53 return n_seconds_from_now(5);
54}
55
56static void drain_cq(grpc_completion_queue* cq) {
57 grpc_event ev;
58 do {
59 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
60 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
61}
62
63static void shutdown_server(grpc_end2end_test_fixture* f) {
64 if (!f->server) return;
65 grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
66 GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
67 grpc_timeout_seconds_to_deadline(5),
68 nullptr)
69 .type == GRPC_OP_COMPLETE);
70 grpc_server_destroy(f->server);
71 f->server = nullptr;
72}
73
74static void shutdown_client(grpc_end2end_test_fixture* f) {
75 if (!f->client) return;
76 grpc_channel_destroy(f->client);
77 f->client = nullptr;
78}
79
80static void end_test(grpc_end2end_test_fixture* f) {
81 shutdown_server(f);
82 shutdown_client(f);
83
84 grpc_completion_queue_shutdown(f->cq);
85 drain_cq(f->cq);
86 grpc_completion_queue_destroy(f->cq);
87 grpc_completion_queue_destroy(f->shutdown_cq);
88}
89
90static void run_one_request(grpc_end2end_test_config config,
91 grpc_end2end_test_fixture f,
92 bool request_is_success) {
93 grpc_call* c;
94 grpc_call* s;
95 cq_verifier* cqv = cq_verifier_create(f.cq);
96 grpc_op ops[6];
97 grpc_op* op;
98 grpc_metadata_array initial_metadata_recv;
99 grpc_metadata_array trailing_metadata_recv;
100 grpc_metadata_array request_metadata_recv;
101 grpc_call_details call_details;
102 grpc_status_code status;
103 grpc_call_error error;
104 grpc_slice details;
105 int was_cancelled = 2;
106
107 gpr_timespec deadline = five_seconds_from_now();
108 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
109 grpc_slice_from_static_string("/foo"), nullptr,
110 deadline, nullptr);
111 GPR_ASSERT(c);
112
113 grpc_metadata_array_init(&initial_metadata_recv);
114 grpc_metadata_array_init(&trailing_metadata_recv);
115 grpc_metadata_array_init(&request_metadata_recv);
116 grpc_call_details_init(&call_details);
117
118 memset(ops, 0, sizeof(ops));
119 op = ops;
120 op->op = GRPC_OP_SEND_INITIAL_METADATA;
121 op->data.send_initial_metadata.count = 0;
122 op->flags = 0;
123 op->reserved = nullptr;
124 op++;
125 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
126 op->flags = 0;
127 op->reserved = nullptr;
128 op++;
129 op->op = GRPC_OP_RECV_INITIAL_METADATA;
130 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
131 op->flags = 0;
132 op->reserved = nullptr;
133 op++;
134 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
135 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
136 op->data.recv_status_on_client.status = &status;
137 op->data.recv_status_on_client.status_details = &details;
138 op->data.recv_status_on_client.error_string = nullptr;
139 op->flags = 0;
140 op->reserved = nullptr;
141 op++;
142 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
143 nullptr);
144 GPR_ASSERT(GRPC_CALL_OK == error);
145
146 error =
147 grpc_server_request_call(f.server, &s, &call_details,
148 &request_metadata_recv, f.cq, f.cq, tag(101));
149 GPR_ASSERT(GRPC_CALL_OK == error);
150 CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
151 cq_verify(cqv);
152
153 memset(ops, 0, sizeof(ops));
154 op = ops;
155 op->op = GRPC_OP_SEND_INITIAL_METADATA;
156 op->data.send_initial_metadata.count = 0;
157 op->flags = 0;
158 op->reserved = nullptr;
159 op++;
160 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
161 op->data.send_status_from_server.trailing_metadata_count = 0;
162 op->data.send_status_from_server.status =
163 request_is_success ? GRPC_STATUS_OK : GRPC_STATUS_UNIMPLEMENTED;
164 grpc_slice status_details = grpc_slice_from_static_string("xyz");
165 op->data.send_status_from_server.status_details = &status_details;
166 op->flags = 0;
167 op->reserved = nullptr;
168 op++;
169 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
170 op->data.recv_close_on_server.cancelled = &was_cancelled;
171 op->flags = 0;
172 op->reserved = nullptr;
173 op++;
174 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
175 nullptr);
176 GPR_ASSERT(GRPC_CALL_OK == error);
177
178 CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
179 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
180 cq_verify(cqv);
181
182 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
183 GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
184 GPR_ASSERT(0 == call_details.flags);
185
186 grpc_slice_unref(details);
187 grpc_metadata_array_destroy(&initial_metadata_recv);
188 grpc_metadata_array_destroy(&trailing_metadata_recv);
189 grpc_metadata_array_destroy(&request_metadata_recv);
190 grpc_call_details_destroy(&call_details);
191
192 grpc_call_unref(c);
193 grpc_call_unref(s);
194
195 cq_verifier_destroy(cqv);
196}
197
198static void test_channelz(grpc_end2end_test_config config) {
199 grpc_end2end_test_fixture f;
200
ncteisenc7166ae2018-06-15 11:04:37 -0400201 grpc_arg client_a;
202 client_a.type = GRPC_ARG_INTEGER;
203 client_a.key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ);
204 client_a.value.integer = true;
205 grpc_channel_args client_args = {1, &client_a};
206
207 f = begin_test(config, "test_channelz", &client_args, nullptr);
ncteisendb6593e2018-06-08 09:46:55 -0700208 grpc_core::channelz::ChannelNode* channelz_channel =
ncteisenb8a52e02018-06-07 18:58:03 -0700209 grpc_channel_get_channelz_node(f.client);
210
ncteisen48d03392018-06-20 08:52:27 -0700211 GPR_ASSERT(channelz_channel != nullptr);
ncteisen97066fd2018-07-13 14:05:27 -0700212 char* json = channelz_channel->RenderJsonString();
ncteisenc7166ae2018-06-15 11:04:37 -0400213 GPR_ASSERT(json != nullptr);
ncteisen97066fd2018-07-13 14:05:27 -0700214 // nothing is present yet
215 GPR_ASSERT(nullptr == strstr(json, "\"callsStarted\""));
216 GPR_ASSERT(nullptr == strstr(json, "\"callsFailed\""));
217 GPR_ASSERT(nullptr == strstr(json, "\"callsSucceeded\""));
ncteisenb8a52e02018-06-07 18:58:03 -0700218 gpr_free(json);
219
220 // one successful request
221 run_one_request(config, f, true);
222
ncteisen97066fd2018-07-13 14:05:27 -0700223 json = channelz_channel->RenderJsonString();
ncteisenc7166ae2018-06-15 11:04:37 -0400224 GPR_ASSERT(json != nullptr);
ncteisenb8a52e02018-06-07 18:58:03 -0700225 GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"1\""));
ncteisenb8a52e02018-06-07 18:58:03 -0700226 GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\""));
227 gpr_free(json);
228
229 // one failed request
230 run_one_request(config, f, false);
231
ncteisen97066fd2018-07-13 14:05:27 -0700232 json = channelz_channel->RenderJsonString();
ncteisenc7166ae2018-06-15 11:04:37 -0400233 GPR_ASSERT(json != nullptr);
ncteisenb8a52e02018-06-07 18:58:03 -0700234 gpr_log(GPR_INFO, "%s", json);
235 GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\""));
236 GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\""));
237 GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\""));
ncteisenc7166ae2018-06-15 11:04:37 -0400238 // channel tracing is not enables, so these should not be preset.
239 GPR_ASSERT(nullptr == strstr(json, "\"trace\""));
240 GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\""));
241 GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\""));
ncteisenb8a52e02018-06-07 18:58:03 -0700242 gpr_free(json);
243
244 end_test(&f);
245 config.tear_down_data(&f);
246}
247
248static void test_channelz_with_channel_trace(grpc_end2end_test_config config) {
249 grpc_end2end_test_fixture f;
250
ncteisenc7166ae2018-06-15 11:04:37 -0400251 grpc_arg client_a[2];
252 client_a[0].type = GRPC_ARG_INTEGER;
253 client_a[0].key =
254 const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE);
255 client_a[0].value.integer = 5;
256 client_a[1].type = GRPC_ARG_INTEGER;
257 client_a[1].key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ);
258 client_a[1].value.integer = true;
259 grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
ncteisenb8a52e02018-06-07 18:58:03 -0700260
261 f = begin_test(config, "test_channelz_with_channel_trace", &client_args,
262 nullptr);
ncteisendb6593e2018-06-08 09:46:55 -0700263 grpc_core::channelz::ChannelNode* channelz_channel =
ncteisenb8a52e02018-06-07 18:58:03 -0700264 grpc_channel_get_channelz_node(f.client);
265
ncteisen48d03392018-06-20 08:52:27 -0700266 GPR_ASSERT(channelz_channel != nullptr);
ncteisen97066fd2018-07-13 14:05:27 -0700267 char* json = channelz_channel->RenderJsonString();
ncteisenc7166ae2018-06-15 11:04:37 -0400268 GPR_ASSERT(json != nullptr);
ncteisenb8a52e02018-06-07 18:58:03 -0700269 gpr_log(GPR_INFO, "%s", json);
270 GPR_ASSERT(nullptr != strstr(json, "\"trace\""));
271 GPR_ASSERT(nullptr != strstr(json, "\"description\":\"Channel created\""));
272 GPR_ASSERT(nullptr != strstr(json, "\"severity\":\"CT_INFO\""));
273 gpr_free(json);
274
275 end_test(&f);
276 config.tear_down_data(&f);
277}
ncteisenc7166ae2018-06-15 11:04:37 -0400278
279static void test_channelz_disabled(grpc_end2end_test_config config) {
280 grpc_end2end_test_fixture f;
281
282 f = begin_test(config, "test_channelz_disabled", nullptr, nullptr);
283 grpc_core::channelz::ChannelNode* channelz_channel =
284 grpc_channel_get_channelz_node(f.client);
ncteisen1ab12872018-06-19 17:09:53 -0700285 GPR_ASSERT(channelz_channel == nullptr);
ncteisenc7166ae2018-06-15 11:04:37 -0400286 // one successful request
287 run_one_request(config, f, true);
ncteisen1ab12872018-06-19 17:09:53 -0700288 GPR_ASSERT(channelz_channel == nullptr);
ncteisenc7166ae2018-06-15 11:04:37 -0400289 end_test(&f);
290 config.tear_down_data(&f);
291}
292
ncteisenb8a52e02018-06-07 18:58:03 -0700293void channelz(grpc_end2end_test_config config) {
294 test_channelz(config);
295 test_channelz_with_channel_trace(config);
ncteisenc7166ae2018-06-15 11:04:37 -0400296 test_channelz_disabled(config);
ncteisenb8a52e02018-06-07 18:58:03 -0700297}
298
299void channelz_pre_init(void) {}