|
|
@ -30,15 +30,17 @@ |
|
|
|
#include "test/core/util/test_config.h" |
|
|
|
#include "test/core/util/test_config.h" |
|
|
|
|
|
|
|
|
|
|
|
using grpc_core::ChannelTracer; |
|
|
|
using grpc_core::ChannelTracer; |
|
|
|
|
|
|
|
using grpc_core::MakeRefCounted; |
|
|
|
|
|
|
|
using grpc_core::RefCountedPtr; |
|
|
|
|
|
|
|
|
|
|
|
static void add_simple_trace(ChannelTracer* tracer) { |
|
|
|
static void add_simple_trace(RefCountedPtr<ChannelTracer> tracer) { |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("simple trace"), |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("simple trace"), |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), |
|
|
|
GRPC_CHANNEL_READY, nullptr); |
|
|
|
GRPC_CHANNEL_READY); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// checks for the existence of all the required members of the tracer.
|
|
|
|
// checks for the existence of all the required members of the tracer.
|
|
|
|
static void validate_tracer(ChannelTracer* tracer, |
|
|
|
static void validate_tracer(RefCountedPtr<ChannelTracer> tracer, |
|
|
|
size_t expected_num_nodes_logged, |
|
|
|
size_t expected_num_nodes_logged, |
|
|
|
size_t max_nodes) { |
|
|
|
size_t max_nodes) { |
|
|
|
if (!max_nodes) return; |
|
|
|
if (!max_nodes) return; |
|
|
@ -50,7 +52,8 @@ static void validate_tracer(ChannelTracer* tracer, |
|
|
|
gpr_free(json_str); |
|
|
|
gpr_free(json_str); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void validate_tracer_data_matches_uuid_lookup(ChannelTracer* tracer) { |
|
|
|
static void validate_tracer_data_matches_uuid_lookup( |
|
|
|
|
|
|
|
RefCountedPtr<ChannelTracer> tracer) { |
|
|
|
intptr_t uuid = tracer->GetUuid(); |
|
|
|
intptr_t uuid = tracer->GetUuid(); |
|
|
|
if (uuid == -1) return; // Doesn't make sense to lookup if tracing disabled
|
|
|
|
if (uuid == -1) return; // Doesn't make sense to lookup if tracing disabled
|
|
|
|
char* tracer_json_str = tracer->RenderTrace(true); |
|
|
|
char* tracer_json_str = tracer->RenderTrace(true); |
|
|
@ -62,7 +65,7 @@ static void validate_tracer_data_matches_uuid_lookup(ChannelTracer* tracer) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ensures the tracer has the correct number of children tracers.
|
|
|
|
// ensures the tracer has the correct number of children tracers.
|
|
|
|
static void validate_children(ChannelTracer* tracer, |
|
|
|
static void validate_children(RefCountedPtr<ChannelTracer> tracer, |
|
|
|
size_t expected_num_children) { |
|
|
|
size_t expected_num_children) { |
|
|
|
char* json_str = tracer->RenderTrace(true); |
|
|
|
char* json_str = tracer->RenderTrace(true); |
|
|
|
grpc_json* json = grpc_json_parse_string(json_str); |
|
|
|
grpc_json* json = grpc_json_parse_string(json_str); |
|
|
@ -75,28 +78,28 @@ static void validate_children(ChannelTracer* tracer, |
|
|
|
// lookups by uuid.
|
|
|
|
// lookups by uuid.
|
|
|
|
static void test_basic_channel_tracing(size_t max_nodes) { |
|
|
|
static void test_basic_channel_tracing(size_t max_nodes) { |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
ChannelTracer tracer(max_nodes); |
|
|
|
RefCountedPtr<ChannelTracer> tracer = |
|
|
|
add_simple_trace(&tracer); |
|
|
|
MakeRefCounted<ChannelTracer>(max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer_data_matches_uuid_lookup(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
tracer.AddTrace( |
|
|
|
validate_tracer_data_matches_uuid_lookup(tracer); |
|
|
|
|
|
|
|
tracer->AddTrace( |
|
|
|
grpc_slice_from_static_string("trace three"), |
|
|
|
grpc_slice_from_static_string("trace three"), |
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), |
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), |
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, 2), |
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, 2), |
|
|
|
GRPC_CHANNEL_IDLE, nullptr); |
|
|
|
GRPC_CHANNEL_IDLE); |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("trace four"), GRPC_ERROR_NONE, |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("trace four"), GRPC_ERROR_NONE, |
|
|
|
GRPC_CHANNEL_SHUTDOWN, nullptr); |
|
|
|
GRPC_CHANNEL_SHUTDOWN); |
|
|
|
validate_tracer(&tracer, 4, max_nodes); |
|
|
|
validate_tracer(tracer, 4, max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer(&tracer, 6, max_nodes); |
|
|
|
validate_tracer(tracer, 6, max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer(&tracer, 10, max_nodes); |
|
|
|
validate_tracer(tracer, 10, max_nodes); |
|
|
|
validate_tracer_data_matches_uuid_lookup(&tracer); |
|
|
|
validate_tracer_data_matches_uuid_lookup(tracer); |
|
|
|
tracer.Unref(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Calls basic test with various values for max_nodes (including 0, which turns
|
|
|
|
// Calls basic test with various values for max_nodes (including 0, which turns
|
|
|
@ -115,41 +118,39 @@ static void test_basic_channel_sizing() { |
|
|
|
// and this function will both hold refs to the subchannel.
|
|
|
|
// and this function will both hold refs to the subchannel.
|
|
|
|
static void test_complex_channel_tracing(size_t max_nodes) { |
|
|
|
static void test_complex_channel_tracing(size_t max_nodes) { |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
ChannelTracer tracer(max_nodes); |
|
|
|
RefCountedPtr<ChannelTracer> tracer = |
|
|
|
add_simple_trace(&tracer); |
|
|
|
MakeRefCounted<ChannelTracer>(max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
ChannelTracer sc1(max_nodes); |
|
|
|
add_simple_trace(tracer); |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel one created"), |
|
|
|
RefCountedPtr<ChannelTracer> sc1 = MakeRefCounted<ChannelTracer>(max_nodes); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc1); |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel one created"), |
|
|
|
validate_tracer(&tracer, 3, max_nodes); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc1); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
validate_tracer(tracer, 3, max_nodes); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
add_simple_trace(sc1); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
add_simple_trace(sc1); |
|
|
|
validate_tracer(&sc1, 3, max_nodes); |
|
|
|
add_simple_trace(sc1); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
validate_tracer(sc1, 3, max_nodes); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
add_simple_trace(sc1); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
add_simple_trace(sc1); |
|
|
|
validate_tracer(&sc1, 6, max_nodes); |
|
|
|
add_simple_trace(sc1); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
validate_tracer(sc1, 6, max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer(&tracer, 5, max_nodes); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer_data_matches_uuid_lookup(&tracer); |
|
|
|
validate_tracer(tracer, 5, max_nodes); |
|
|
|
ChannelTracer sc2(max_nodes); |
|
|
|
validate_tracer_data_matches_uuid_lookup(tracer); |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel two created"), |
|
|
|
RefCountedPtr<ChannelTracer> sc2 = MakeRefCounted<ChannelTracer>(max_nodes); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc2); |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel two created"), |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel one inactive"), |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc2); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc1); |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel one inactive"), |
|
|
|
validate_tracer(&tracer, 7, max_nodes); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc1); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
validate_tracer(tracer, 7, max_nodes); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
validate_tracer_data_matches_uuid_lookup(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
sc1.Unref(); |
|
|
|
validate_tracer_data_matches_uuid_lookup(tracer); |
|
|
|
sc2.Unref(); |
|
|
|
|
|
|
|
tracer.Unref(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Calls the complex test with a sweep of sizes for max_nodes.
|
|
|
|
// Calls the complex test with a sweep of sizes for max_nodes.
|
|
|
@ -162,59 +163,38 @@ static void test_complex_channel_sizing() { |
|
|
|
test_complex_channel_tracing(15); |
|
|
|
test_complex_channel_tracing(15); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Tests edge case in which the parent channel tracer is destroyed before the
|
|
|
|
|
|
|
|
// subchannel. Not sure if it is a realistic scenario, but the refcounting
|
|
|
|
|
|
|
|
// balance should still hold.
|
|
|
|
|
|
|
|
static void test_delete_parent_first() { |
|
|
|
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
|
|
|
ChannelTracer tracer(3); |
|
|
|
|
|
|
|
add_simple_trace(&tracer); |
|
|
|
|
|
|
|
add_simple_trace(&tracer); |
|
|
|
|
|
|
|
ChannelTracer sc1(3); |
|
|
|
|
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel one created"), |
|
|
|
|
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc1); |
|
|
|
|
|
|
|
// this will cause the tracer destructor to run.
|
|
|
|
|
|
|
|
tracer.Unref(); |
|
|
|
|
|
|
|
sc1.Unref(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Test a case in which the parent channel has subchannels and the subchannels
|
|
|
|
// Test a case in which the parent channel has subchannels and the subchannels
|
|
|
|
// have connections. Ensures that everything lives as long as it should then
|
|
|
|
// have connections. Ensures that everything lives as long as it should then
|
|
|
|
// gets deleted.
|
|
|
|
// gets deleted.
|
|
|
|
static void test_nesting() { |
|
|
|
static void test_nesting() { |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
ChannelTracer tracer(10); |
|
|
|
RefCountedPtr<ChannelTracer> tracer = MakeRefCounted<ChannelTracer>(10); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
ChannelTracer sc1(5); |
|
|
|
RefCountedPtr<ChannelTracer> sc1 = MakeRefCounted<ChannelTracer>(5); |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel one created"), |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel one created"), |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc1); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc1); |
|
|
|
// channel has only one subchannel right here.
|
|
|
|
// channel has only one subchannel right here.
|
|
|
|
validate_children(&tracer, 1); |
|
|
|
validate_children(tracer, 1); |
|
|
|
add_simple_trace(&sc1); |
|
|
|
add_simple_trace(sc1); |
|
|
|
ChannelTracer conn1(5); |
|
|
|
RefCountedPtr<ChannelTracer> conn1 = MakeRefCounted<ChannelTracer>(5); |
|
|
|
// nesting one level deeper.
|
|
|
|
// nesting one level deeper.
|
|
|
|
sc1.AddTrace(grpc_slice_from_static_string("connection one created"), |
|
|
|
sc1->AddTrace(grpc_slice_from_static_string("connection one created"), |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &conn1); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, conn1); |
|
|
|
validate_children(&sc1, 1); |
|
|
|
validate_children(sc1, 1); |
|
|
|
add_simple_trace(&conn1); |
|
|
|
add_simple_trace(conn1); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
ChannelTracer sc2(5); |
|
|
|
RefCountedPtr<ChannelTracer> sc2 = MakeRefCounted<ChannelTracer>(5); |
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel two created"), |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel two created"), |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc2); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc2); |
|
|
|
validate_children(&tracer, 2); |
|
|
|
validate_children(tracer, 2); |
|
|
|
// this trace should not get added to the parents children since it is already
|
|
|
|
// this trace should not get added to the parents children since it is already
|
|
|
|
// present in the tracer.
|
|
|
|
// present in the tracer.
|
|
|
|
tracer.AddTrace(grpc_slice_from_static_string("subchannel one inactive"), |
|
|
|
tracer->AddTrace(grpc_slice_from_static_string("subchannel one inactive"), |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, &sc1); |
|
|
|
GRPC_ERROR_NONE, GRPC_CHANNEL_IDLE, sc1); |
|
|
|
validate_children(&tracer, 2); |
|
|
|
validate_children(tracer, 2); |
|
|
|
add_simple_trace(&tracer); |
|
|
|
add_simple_trace(tracer); |
|
|
|
|
|
|
|
|
|
|
|
conn1.Unref(); |
|
|
|
|
|
|
|
sc1.Unref(); |
|
|
|
|
|
|
|
sc2.Unref(); |
|
|
|
|
|
|
|
tracer.Unref(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) { |
|
|
|
int main(int argc, char** argv) { |
|
|
@ -224,7 +204,6 @@ int main(int argc, char** argv) { |
|
|
|
test_basic_channel_sizing(); |
|
|
|
test_basic_channel_sizing(); |
|
|
|
test_complex_channel_tracing(5); |
|
|
|
test_complex_channel_tracing(5); |
|
|
|
test_complex_channel_sizing(); |
|
|
|
test_complex_channel_sizing(); |
|
|
|
test_delete_parent_first(); |
|
|
|
|
|
|
|
test_nesting(); |
|
|
|
test_nesting(); |
|
|
|
grpc_shutdown(); |
|
|
|
grpc_shutdown(); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|