diff options
Diffstat (limited to 'test/core')
40 files changed, 1026 insertions, 548 deletions
diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index e2ea7540ef..73d251eff4 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -37,7 +37,7 @@ static void* tag(intptr_t t) { return (void*)t; } static void run_test(const char* target, size_t nops) { grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(nullptr, nullptr, nullptr); + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); grpc_channel* channel; grpc_call* c; diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index c554b20148..da419f00cf 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -84,6 +84,23 @@ grpc_cc_test( ) grpc_cc_test( + name = "channelz_test", + srcs = ["channelz_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:channel_trace_proto_helper", + ], + external_deps = [ + "gtest", + ], +) + +grpc_cc_test( name = "channelz_registry_test", srcs = ["channelz_registry_test.cc"], language = "C++", @@ -105,6 +122,7 @@ grpc_cc_test( language = "C++", deps = [ "//:grpc", + "//test/core/util:gpr_test_util", ], external_deps = [ "gtest", diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index d99a32d91d..bbddee3f14 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -25,6 +25,7 @@ #include <grpc/support/log.h> #include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -39,6 +40,7 @@ #include <string.h> namespace grpc_core { +namespace channelz { namespace testing { namespace { @@ -69,7 +71,7 @@ void ValidateChannelTraceData(grpc_json* json, ASSERT_NE(json, nullptr); grpc_json* num_events_logged_json = GetJsonChild(json, "numEventsLogged"); ASSERT_NE(num_events_logged_json, nullptr); - grpc_json* start_time = GetJsonChild(json, "creationTime"); + grpc_json* start_time = GetJsonChild(json, "creationTimestamp"); ASSERT_NE(start_time, nullptr); size_t num_events_logged = (size_t)strtol(num_events_logged_json->value, nullptr, 0); @@ -77,35 +79,47 @@ void ValidateChannelTraceData(grpc_json* json, ValidateJsonArraySize(json, "events", actual_num_events_expected); } -void AddSimpleTrace(const RefCountedPtr<ChannelTrace>& tracer) { +void AddSimpleTrace(ChannelTrace* tracer) { tracer->AddTraceEvent(ChannelTrace::Severity::Info, grpc_slice_from_static_string("simple trace")); } // checks for the existence of all the required members of the tracer. -void ValidateChannelTrace(const RefCountedPtr<ChannelTrace>& tracer, +void ValidateChannelTrace(ChannelTrace* tracer, size_t expected_num_event_logged, size_t max_nodes) { if (!max_nodes) return; - char* json_str = tracer->RenderTrace(); + grpc_json* json = tracer->RenderJSON(); + EXPECT_NE(json, nullptr); + char* json_str = grpc_json_dump_to_string(json, 0); + grpc_json_destroy(json); grpc::testing::ValidateChannelTraceProtoJsonTranslation(json_str); - grpc_json* json = grpc_json_parse_string(json_str); - ValidateChannelTraceData(json, expected_num_event_logged, + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateChannelTraceData(parsed_json, expected_num_event_logged, GPR_MIN(expected_num_event_logged, max_nodes)); - grpc_json_destroy(json); + grpc_json_destroy(parsed_json); gpr_free(json_str); } -void ValidateTraceDataMatchedUuidLookup( - const RefCountedPtr<ChannelTrace>& tracer) { - intptr_t uuid = tracer->GetUuid(); - if (uuid == -1) return; // Doesn't make sense to lookup if tracing disabled - char* tracer_json_str = tracer->RenderTrace(); - ChannelTrace* uuid_lookup = ChannelzRegistry::Get<ChannelTrace>(uuid); - char* uuid_lookup_json_str = uuid_lookup->RenderTrace(); - EXPECT_EQ(strcmp(tracer_json_str, uuid_lookup_json_str), 0); - gpr_free(tracer_json_str); - gpr_free(uuid_lookup_json_str); -} +class ChannelFixture { + public: + ChannelFixture(int max_trace_nodes) { + grpc_arg client_a; + client_a.type = GRPC_ARG_INTEGER; + client_a.key = + const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + client_a.value.integer = max_trace_nodes; + grpc_channel_args client_args = {1, &client_a}; + channel_ = + grpc_insecure_channel_create("fake_target", &client_args, nullptr); + } + + ~ChannelFixture() { grpc_channel_destroy(channel_); } + + grpc_channel* channel() { return channel_; } + + private: + grpc_channel* channel_; +}; } // anonymous namespace @@ -115,25 +129,22 @@ class ChannelTracerTest : public ::testing::TestWithParam<size_t> {}; // lookups by uuid. TEST_P(ChannelTracerTest, BasicTest) { grpc_core::ExecCtx exec_ctx; - RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateTraceDataMatchedUuidLookup(tracer); - tracer->AddTraceEvent(ChannelTrace::Severity::Info, - grpc_slice_from_static_string("trace three")); - tracer->AddTraceEvent(ChannelTrace::Severity::Error, - grpc_slice_from_static_string("trace four error")); - ValidateChannelTrace(tracer, 4, GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 6, GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 10, GetParam()); - ValidateTraceDataMatchedUuidLookup(tracer); - tracer.reset(nullptr); + ChannelTrace tracer(GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + tracer.AddTraceEvent(ChannelTrace::Severity::Info, + grpc_slice_from_static_string("trace three")); + tracer.AddTraceEvent(ChannelTrace::Severity::Error, + grpc_slice_from_static_string("trace four error")); + ValidateChannelTrace(&tracer, 4, GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 6, GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 10, GetParam()); } // Tests more complex functionality, like a parent channel tracking @@ -141,42 +152,43 @@ TEST_P(ChannelTracerTest, BasicTest) { // and this function will both hold refs to the subchannel. TEST_P(ChannelTracerTest, ComplexTest) { grpc_core::ExecCtx exec_ctx; - RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - RefCountedPtr<ChannelTrace> sc1 = MakeRefCounted<ChannelTrace>(GetParam()); - tracer->AddTraceEventReferencingSubchannel( + ChannelTrace tracer(GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ChannelFixture channel1(GetParam()); + RefCountedPtr<ChannelNode> sc1 = + MakeRefCounted<ChannelNode>(channel1.channel(), GetParam()); + tracer.AddTraceEventReferencingSubchannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); - ValidateChannelTrace(tracer, 3, GetParam()); - AddSimpleTrace(sc1); - AddSimpleTrace(sc1); - AddSimpleTrace(sc1); - ValidateChannelTrace(sc1, 3, GetParam()); - AddSimpleTrace(sc1); - AddSimpleTrace(sc1); - AddSimpleTrace(sc1); - ValidateChannelTrace(sc1, 6, GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 5, GetParam()); - ValidateTraceDataMatchedUuidLookup(tracer); - RefCountedPtr<ChannelTrace> sc2 = MakeRefCounted<ChannelTrace>(GetParam()); - tracer->AddTraceEventReferencingChannel( + ValidateChannelTrace(&tracer, 3, GetParam()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + ValidateChannelTrace(sc1->trace(), 3, GetParam()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + ValidateChannelTrace(sc1->trace(), 6, GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 5, GetParam()); + ChannelFixture channel2(GetParam()); + RefCountedPtr<ChannelNode> sc2 = + MakeRefCounted<ChannelNode>(channel2.channel(), GetParam()); + tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("LB channel two created"), sc2); - tracer->AddTraceEventReferencingSubchannel( + tracer.AddTraceEventReferencingSubchannel( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); - ValidateChannelTrace(tracer, 7, GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateTraceDataMatchedUuidLookup(tracer); - tracer.reset(nullptr); + ValidateChannelTrace(&tracer, 7, GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); sc1.reset(nullptr); sc2.reset(nullptr); } @@ -186,39 +198,44 @@ TEST_P(ChannelTracerTest, ComplexTest) { // gets deleted. TEST_P(ChannelTracerTest, TestNesting) { grpc_core::ExecCtx exec_ctx; - RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 2, GetParam()); - RefCountedPtr<ChannelTrace> sc1 = MakeRefCounted<ChannelTrace>(GetParam()); - tracer->AddTraceEventReferencingChannel( + ChannelTrace tracer(GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 2, GetParam()); + ChannelFixture channel1(GetParam()); + RefCountedPtr<ChannelNode> sc1 = + MakeRefCounted<ChannelNode>(channel1.channel(), GetParam()); + tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); - ValidateChannelTrace(tracer, 3, GetParam()); - AddSimpleTrace(sc1); - RefCountedPtr<ChannelTrace> conn1 = MakeRefCounted<ChannelTrace>(GetParam()); + ValidateChannelTrace(&tracer, 3, GetParam()); + AddSimpleTrace(sc1->trace()); + ChannelFixture channel2(GetParam()); + RefCountedPtr<ChannelNode> conn1 = + MakeRefCounted<ChannelNode>(channel2.channel(), GetParam()); // nesting one level deeper. - sc1->AddTraceEventReferencingSubchannel( + sc1->trace()->AddTraceEventReferencingSubchannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("connection one created"), conn1); - ValidateChannelTrace(tracer, 3, GetParam()); - AddSimpleTrace(conn1); - AddSimpleTrace(tracer); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 5, GetParam()); - ValidateChannelTrace(conn1, 1, GetParam()); - RefCountedPtr<ChannelTrace> sc2 = MakeRefCounted<ChannelTrace>(GetParam()); - tracer->AddTraceEventReferencingSubchannel( + ValidateChannelTrace(&tracer, 3, GetParam()); + AddSimpleTrace(conn1->trace()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 5, GetParam()); + ValidateChannelTrace(conn1->trace(), 1, GetParam()); + ChannelFixture channel3(GetParam()); + RefCountedPtr<ChannelNode> sc2 = + MakeRefCounted<ChannelNode>(channel3.channel(), GetParam()); + tracer.AddTraceEventReferencingSubchannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel two created"), sc2); // this trace should not get added to the parents children since it is already // present in the tracer. - tracer->AddTraceEventReferencingChannel( + tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); - AddSimpleTrace(tracer); - ValidateChannelTrace(tracer, 8, GetParam()); - tracer.reset(nullptr); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 8, GetParam()); sc1.reset(nullptr); sc2.reset(nullptr); conn1.reset(nullptr); @@ -228,6 +245,7 @@ INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest, ::testing::Values(0, 1, 2, 6, 10, 15)); } // namespace testing +} // namespace channelz } // namespace grpc_core int main(int argc, char** argv) { diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc new file mode 100644 index 0000000000..058eea914c --- /dev/null +++ b/test/core/channel/channelz_test.cc @@ -0,0 +1,216 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <gtest/gtest.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/channel/channelz_registry.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/surface/channel.h" + +#include "test/core/util/test_config.h" +#include "test/cpp/util/channel_trace_proto_helper.h" + +#include <grpc/support/string_util.h> +#include <stdlib.h> +#include <string.h> + +namespace grpc_core { +namespace channelz { +namespace testing { + +// testing peer to access channel internals +class ChannelNodePeer { + public: + ChannelNodePeer(ChannelNode* channel) : channel_(channel) {} + grpc_millis last_call_started_millis() { + return (grpc_millis)gpr_atm_no_barrier_load( + &channel_->last_call_started_millis_); + } + + private: + ChannelNode* channel_; +}; + +namespace { + +grpc_json* GetJsonChild(grpc_json* parent, const char* key) { + EXPECT_NE(parent, nullptr); + for (grpc_json* child = parent->child; child != nullptr; + child = child->next) { + if (child->key != nullptr && strcmp(child->key, key) == 0) return child; + } + return nullptr; +} + +class ChannelFixture { + public: + ChannelFixture(int max_trace_nodes) { + grpc_arg client_a[2]; + client_a[0].type = GRPC_ARG_INTEGER; + client_a[0].key = + const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + client_a[0].value.integer = max_trace_nodes; + client_a[1].type = GRPC_ARG_INTEGER; + client_a[1].key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ); + client_a[1].value.integer = true; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; + channel_ = + grpc_insecure_channel_create("fake_target", &client_args, nullptr); + } + + ~ChannelFixture() { grpc_channel_destroy(channel_); } + + grpc_channel* channel() { return channel_; } + + private: + grpc_channel* channel_; +}; + +struct validate_channel_data_args { + int64_t calls_started; + int64_t calls_failed; + int64_t calls_succeeded; +}; + +void ValidateChildInteger(grpc_json* json, int64_t expect, const char* key) { + grpc_json* gotten_json = GetJsonChild(json, key); + ASSERT_NE(gotten_json, nullptr); + int64_t gotten_number = (int64_t)strtol(gotten_json->value, nullptr, 0); + EXPECT_EQ(gotten_number, expect); +} + +void ValidateCounters(char* json_str, validate_channel_data_args args) { + grpc_json* json = grpc_json_parse_string(json_str); + ASSERT_NE(json, nullptr); + grpc_json* data = GetJsonChild(json, "data"); + ValidateChildInteger(data, args.calls_started, "callsStarted"); + ValidateChildInteger(data, args.calls_failed, "callsFailed"); + ValidateChildInteger(data, args.calls_succeeded, "callsSucceeded"); + grpc_json_destroy(json); +} + +void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { + char* json_str = channel->RenderJSON(); + grpc::testing::ValidateChannelProtoJsonTranslation(json_str); + ValidateCounters(json_str, args); + gpr_free(json_str); +} + +grpc_millis GetLastCallStartedMillis(ChannelNode* channel) { + ChannelNodePeer peer(channel); + return peer.last_call_started_millis(); +} + +void ChannelzSleep(int64_t sleep_us) { + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(sleep_us, GPR_TIMESPAN))); + grpc_core::ExecCtx::Get()->InvalidateNow(); +} + +} // anonymous namespace + +class ChannelzChannelTest : public ::testing::TestWithParam<size_t> {}; + +TEST_P(ChannelzChannelTest, BasicChannel) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture channel(GetParam()); + ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(channel.channel()); + char* json_str = channelz_channel->RenderJSON(); + ValidateCounters(json_str, {0, 0, 0}); + gpr_free(json_str); +} + +TEST(ChannelzChannelTest, ChannelzDisabled) { + grpc_core::ExecCtx exec_ctx; + grpc_channel* channel = + grpc_insecure_channel_create("fake_target", nullptr, nullptr); + ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel); + ASSERT_EQ(channelz_channel, nullptr); + grpc_channel_destroy(channel); +} + +TEST_P(ChannelzChannelTest, BasicChannelAPIFunctionality) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture channel(GetParam()); + ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(channel.channel()); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); + ValidateChannel(channelz_channel, {1, 1, 1}); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); + ValidateChannel(channelz_channel, {3, 3, 3}); +} + +TEST_P(ChannelzChannelTest, LastCallStartedMillis) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture channel(GetParam()); + ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(channel.channel()); + // start a call to set the last call started timestamp + channelz_channel->RecordCallStarted(); + grpc_millis millis1 = GetLastCallStartedMillis(channelz_channel); + // time gone by should not affect the timestamp + ChannelzSleep(100); + grpc_millis millis2 = GetLastCallStartedMillis(channelz_channel); + EXPECT_EQ(millis1, millis2); + // calls succeeded or failed should not affect the timestamp + ChannelzSleep(100); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); + grpc_millis millis3 = GetLastCallStartedMillis(channelz_channel); + EXPECT_EQ(millis1, millis3); + // another call started should affect the timestamp + // sleep for extra long to avoid flakes (since we cache Now()) + ChannelzSleep(5000); + channelz_channel->RecordCallStarted(); + grpc_millis millis4 = GetLastCallStartedMillis(channelz_channel); + EXPECT_NE(millis1, millis4); +} + +INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, + ::testing::Values(0, 1, 2, 6, 10, 15)); + +} // namespace testing +} // namespace channelz +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index a70128254a..061b23b5d6 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -54,6 +54,8 @@ extern void cancel_in_a_vacuum(grpc_end2end_test_config config); extern void cancel_in_a_vacuum_pre_init(void); extern void cancel_with_status(grpc_end2end_test_config config); extern void cancel_with_status_pre_init(void); +extern void channelz(grpc_end2end_test_config config); +extern void channelz_pre_init(void); extern void compressed_payload(grpc_end2end_test_config config); extern void compressed_payload_pre_init(void); extern void connectivity(grpc_end2end_test_config config); @@ -201,6 +203,7 @@ void grpc_end2end_tests_pre_init(void) { cancel_before_invoke_pre_init(); cancel_in_a_vacuum_pre_init(); cancel_with_status_pre_init(); + channelz_pre_init(); compressed_payload_pre_init(); connectivity_pre_init(); default_host_pre_init(); @@ -287,6 +290,7 @@ void grpc_end2end_tests(int argc, char **argv, cancel_before_invoke(config); cancel_in_a_vacuum(config); cancel_with_status(config); + channelz(config); compressed_payload(config); connectivity(config); default_host(config); @@ -404,6 +408,10 @@ void grpc_end2end_tests(int argc, char **argv, cancel_with_status(config); continue; } + if (0 == strcmp("channelz", argv[i])) { + channelz(config); + continue; + } if (0 == strcmp("compressed_payload", argv[i])) { compressed_payload(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index bf75dd4579..7ae475cdef 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -56,6 +56,8 @@ extern void cancel_in_a_vacuum(grpc_end2end_test_config config); extern void cancel_in_a_vacuum_pre_init(void); extern void cancel_with_status(grpc_end2end_test_config config); extern void cancel_with_status_pre_init(void); +extern void channelz(grpc_end2end_test_config config); +extern void channelz_pre_init(void); extern void compressed_payload(grpc_end2end_test_config config); extern void compressed_payload_pre_init(void); extern void connectivity(grpc_end2end_test_config config); @@ -204,6 +206,7 @@ void grpc_end2end_tests_pre_init(void) { cancel_before_invoke_pre_init(); cancel_in_a_vacuum_pre_init(); cancel_with_status_pre_init(); + channelz_pre_init(); compressed_payload_pre_init(); connectivity_pre_init(); default_host_pre_init(); @@ -291,6 +294,7 @@ void grpc_end2end_tests(int argc, char **argv, cancel_before_invoke(config); cancel_in_a_vacuum(config); cancel_with_status(config); + channelz(config); compressed_payload(config); connectivity(config); default_host(config); @@ -412,6 +416,10 @@ void grpc_end2end_tests(int argc, char **argv, cancel_with_status(config); continue; } + if (0 == strcmp("channelz", argv[i])) { + channelz(config); + continue; + } if (0 == strcmp("compressed_payload", argv[i])) { compressed_payload(config); continue; diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index d44aafd50a..37397d6450 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -146,7 +146,7 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( grpc_end2end_test_fixture* f, grpc_channel_args* client_args) { grpc_core::ExecCtx exec_ctx; grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr); + grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr, nullptr); grpc_call_credentials* oauth2_creds = grpc_md_only_test_credentials_create( "authorization", oauth2_md, true /* is_async */); grpc_channel_credentials* ssl_oauth2_creds = diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 999cd4cdfb..4d6c815716 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -101,7 +101,7 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { static void chttp2_init_client_simple_ssl_secure_fullstack( grpc_end2end_test_fixture* f, grpc_channel_args* client_args) { grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(nullptr, nullptr, nullptr); + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); grpc_arg ssl_name_override = { GRPC_ARG_STRING, const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index 9ab50c6217..09cbf974b6 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -55,7 +55,7 @@ static grpc_channel* create_proxy_client(const char* target, grpc_channel_args* client_args) { grpc_channel* channel; grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(nullptr, nullptr, nullptr); + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); grpc_arg ssl_name_override = { GRPC_ARG_STRING, const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), @@ -138,7 +138,7 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { static void chttp2_init_client_simple_ssl_secure_fullstack( grpc_end2end_test_fixture* f, grpc_channel_args* client_args) { grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(nullptr, nullptr, nullptr); + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); grpc_arg ssl_name_override = { GRPC_ARG_STRING, const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index ccb194cdf5..eacfd4a8c3 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -222,7 +222,7 @@ static grpc_channel_credentials* read_ssl_channel_creds(input_stream* inp) { grpc_channel_credentials* creds = grpc_ssl_credentials_create( root_certs, private_key != nullptr && certs != nullptr ? &key_cert_pair : nullptr, - nullptr); + nullptr, nullptr); cred_artifact_ctx_finish(&ctx); return creds; } @@ -1046,6 +1046,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { op->reserved = nullptr; op->flags = grpc_fuzzer_get_next_uint32(&inp); } + if (g_channel == nullptr) ok = false; if (ok) { validator* v = make_finished_batch_validator(g_active_call, has_ops); g_active_call->pending_ops++; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 1851214191..04dc2a8785 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -106,6 +106,7 @@ END2END_TESTS = { needs_compression=True), 'connectivity': connectivity_test_options._replace(needs_names=True, proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']), + 'channelz': default_test_options, 'default_host': default_test_options._replace( needs_fullstack=True, needs_dns=True, needs_names=True), 'call_host_override': default_test_options._replace( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 706f4fa86d..67769a8cb1 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -113,6 +113,7 @@ END2END_TESTS = { 'compressed_payload': test_options(proxyable=False, exclude_inproc=True), 'connectivity': test_options(needs_fullstack=True, needs_names=True, proxyable=False), + 'channelz': test_options(), 'default_host': test_options(needs_fullstack=True, needs_dns=True, needs_names=True), 'disappearing_server': test_options(needs_fullstack=True,needs_names=True), diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index 9ed6f23798..2c5ee3b156 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -169,8 +169,8 @@ typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype; default: \ break; \ } \ - ssl_creds = \ - grpc_ssl_credentials_create(test_root_cert, key_cert_pair, NULL); \ + ssl_creds = grpc_ssl_credentials_create(test_root_cert, key_cert_pair, \ + NULL, NULL); \ grpc_arg ssl_name_override = { \ GRPC_ARG_STRING, \ const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), \ diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index d5984be93f..b2f398625a 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -66,7 +66,7 @@ grpc_channel* client_create(char* server_addr, grpc_ssl_session_cache* cache) { grpc_ssl_pem_key_cert_pair signed_client_key_cert_pair = { test_signed_client_key, test_signed_client_cert}; grpc_channel_credentials* client_creds = grpc_ssl_credentials_create( - test_root_cert, &signed_client_key_cert_pair, nullptr); + test_root_cert, &signed_client_key_cert_pair, nullptr, nullptr); grpc_arg args[] = { grpc_channel_arg_string_create( diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc new file mode 100644 index 0000000000..eb052119ca --- /dev/null +++ b/test/core/end2end/tests/channelz.cc @@ -0,0 +1,299 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include "src/core/lib/surface/channel.h" + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include "src/core/lib/gpr/string.h" +#include "test/core/end2end/cq_verifier.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +static void run_one_request(grpc_end2end_test_config config, + grpc_end2end_test_fixture f, + bool request_is_success) { + grpc_call* c; + grpc_call* s; + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.error_string = nullptr; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = + request_is_success ? GRPC_STATUS_OK : GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + GPR_ASSERT(0 == call_details.flags); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); +} + +static void test_channelz(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + grpc_arg client_a; + client_a.type = GRPC_ARG_INTEGER; + client_a.key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ); + client_a.value.integer = true; + grpc_channel_args client_args = {1, &client_a}; + + f = begin_test(config, "test_channelz", &client_args, nullptr); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(f.client); + + GPR_ASSERT(channelz_channel != nullptr); + char* json = channelz_channel->RenderJSON(); + GPR_ASSERT(json != nullptr); + GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"0\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"0\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"0\"")); + gpr_free(json); + + // one successful request + run_one_request(config, f, true); + + json = channelz_channel->RenderJSON(); + GPR_ASSERT(json != nullptr); + GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"0\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); + gpr_free(json); + + // one failed request + run_one_request(config, f, false); + + json = channelz_channel->RenderJSON(); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); + // channel tracing is not enables, so these should not be preset. + GPR_ASSERT(nullptr == strstr(json, "\"trace\"")); + GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\"")); + GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); + gpr_free(json); + + end_test(&f); + config.tear_down_data(&f); +} + +static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + grpc_arg client_a[2]; + client_a[0].type = GRPC_ARG_INTEGER; + client_a[0].key = + const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + client_a[0].value.integer = 5; + client_a[1].type = GRPC_ARG_INTEGER; + client_a[1].key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ); + client_a[1].value.integer = true; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; + + f = begin_test(config, "test_channelz_with_channel_trace", &client_args, + nullptr); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(f.client); + + GPR_ASSERT(channelz_channel != nullptr); + char* json = channelz_channel->RenderJSON(); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"trace\"")); + GPR_ASSERT(nullptr != strstr(json, "\"description\":\"Channel created\"")); + GPR_ASSERT(nullptr != strstr(json, "\"severity\":\"CT_INFO\"")); + gpr_free(json); + + end_test(&f); + config.tear_down_data(&f); +} + +static void test_channelz_disabled(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + f = begin_test(config, "test_channelz_disabled", nullptr, nullptr); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(f.client); + GPR_ASSERT(channelz_channel == nullptr); + // one successful request + run_one_request(config, f, true); + GPR_ASSERT(channelz_channel == nullptr); + end_test(&f); + config.tear_down_data(&f); +} + +void channelz(grpc_end2end_test_config config) { + test_channelz(config); + test_channelz_with_channel_trace(config); + test_channelz_disabled(config); +} + +void channelz_pre_init(void) {} diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index ae34947718..41f4338f8a 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -27,10 +27,12 @@ namespace testing { TEST(InlinedVectorTest, CreateAndIterate) { const int kNumElements = 9; InlinedVector<int, 2> v; + EXPECT_TRUE(v.empty()); for (int i = 0; i < kNumElements; ++i) { v.push_back(i); } EXPECT_EQ(static_cast<size_t>(kNumElements), v.size()); + EXPECT_FALSE(v.empty()); for (int i = 0; i < kNumElements; ++i) { EXPECT_EQ(i, v[i]); EXPECT_EQ(i, &v[i] - &v[0]); // Ensure contiguous allocation. diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index a3276b9343..712cd59197 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -82,3 +82,21 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "handshake_verify_peer_options", + srcs = ["verify_peer_options.cc"], + language = "C++", + data = [ + "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:server1.key", + "//src/core/tsi/test_creds:server1.pem", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + diff --git a/test/core/handshake/client_ssl.cc b/test/core/handshake/client_ssl.cc index 8ac763ac4b..467df6e229 100644 --- a/test/core/handshake/client_ssl.cc +++ b/test/core/handshake/client_ssl.cc @@ -251,8 +251,8 @@ static bool client_ssl_test(char* server_alpn_preferred) { reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); pem_key_cert_pair.cert_chain = reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); - grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(ca_cert, &pem_key_cert_pair, nullptr); + grpc_channel_credentials* ssl_creds = grpc_ssl_credentials_create( + ca_cert, &pem_key_cert_pair, nullptr, nullptr); // Establish a channel pointing at the TLS server. Since the gRPC runtime is // lazy, this won't necessarily establish a connection yet. diff --git a/test/core/handshake/verify_peer_options.cc b/test/core/handshake/verify_peer_options.cc new file mode 100644 index 0000000000..86c524b4a5 --- /dev/null +++ b/test/core/handshake/verify_peer_options.cc @@ -0,0 +1,275 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/port.h" + +// This test won't work except with posix sockets enabled +#ifdef GRPC_POSIX_SOCKET + +#include <arpa/inet.h> +#include <openssl/err.h> +#include <openssl/ssl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> + +#include <grpc/grpc.h> +#include <grpc/grpc_security.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/iomgr/load_file.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem" +#define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key" +#define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem" + +// Simple gRPC server. This listens until client_handshake_complete occurs. +static gpr_event client_handshake_complete; + +static void server_thread(void* arg) { + const int port = *static_cast<int*>(arg); + + // Load key pair and establish server SSL credentials. + grpc_ssl_pem_key_cert_pair pem_key_cert_pair; + grpc_slice ca_slice, cert_slice, key_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_CA_PATH, 1, &ca_slice))); + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); + const char* ca_cert = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); + pem_key_cert_pair.private_key = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); + pem_key_cert_pair.cert_chain = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); + grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create( + ca_cert, &pem_key_cert_pair, 1, 0, nullptr); + + // Start server listening on local port. + char* addr; + gpr_asprintf(&addr, "127.0.0.1:%d", port); + grpc_server* server = grpc_server_create(nullptr, nullptr); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds)); + free(addr); + + grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); + + grpc_server_register_completion_queue(server, cq, nullptr); + grpc_server_start(server); + + // Wait a bounded number of time until client_handshake_complete is set, + // sleeping between polls. The total time spent (deadline * retries) + // should be strictly greater than the client retry limit so that the + // client will always timeout first. + int retries = 60; + while (!gpr_event_get(&client_handshake_complete) && retries-- > 0) { + const gpr_timespec cq_deadline = grpc_timeout_seconds_to_deadline(1); + grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, nullptr); + GPR_ASSERT(ev.type == GRPC_QUEUE_TIMEOUT); + } + + gpr_log(GPR_INFO, "Shutting down server"); + grpc_server_shutdown_and_notify(server, cq, nullptr); + grpc_server_cancel_all_calls(server); + grpc_completion_queue_shutdown(cq); + + const gpr_timespec cq_deadline = grpc_timeout_seconds_to_deadline(60); + grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, nullptr); + GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); + + grpc_server_destroy(server); + grpc_completion_queue_destroy(cq); + grpc_server_credentials_release(ssl_creds); + grpc_slice_unref(cert_slice); + grpc_slice_unref(key_slice); + grpc_slice_unref(ca_slice); +} + +// This test launches a minimal TLS grpc server on a separate thread and then +// establishes a TLS handshake via the core library to the server. The client +// uses the supplied verify options. +static bool verify_peer_options_test(verify_peer_options* verify_options) { + bool success = true; + + grpc_init(); + int port = grpc_pick_unused_port_or_die(); + gpr_event_init(&client_handshake_complete); + + // Launch the gRPC server thread. + bool ok; + grpc_core::Thread thd("grpc_client_ssl_test", server_thread, &port, &ok); + GPR_ASSERT(ok); + thd.Start(); + + // Load key pair and establish client SSL credentials. + grpc_ssl_pem_key_cert_pair pem_key_cert_pair; + grpc_slice ca_slice, cert_slice, key_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_CA_PATH, 1, &ca_slice))); + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); + const char* ca_cert = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); + pem_key_cert_pair.private_key = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); + pem_key_cert_pair.cert_chain = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); + grpc_channel_credentials* ssl_creds = grpc_ssl_credentials_create( + ca_cert, &pem_key_cert_pair, verify_options, nullptr); + + // Establish a channel pointing at the TLS server. Since the gRPC runtime is + // lazy, this won't necessarily establish a connection yet. + char* target; + gpr_asprintf(&target, "127.0.0.1:%d", port); + grpc_arg ssl_name_override = { + GRPC_ARG_STRING, + const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + {const_cast<char*>("foo.test.google.fr")}}; + grpc_channel_args grpc_args; + grpc_args.num_args = 1; + grpc_args.args = &ssl_name_override; + grpc_channel* channel = + grpc_secure_channel_create(ssl_creds, target, &grpc_args, nullptr); + GPR_ASSERT(channel); + gpr_free(target); + + // Initially the channel will be idle, the + // grpc_channel_check_connectivity_state triggers an attempt to connect. + GPR_ASSERT(grpc_channel_check_connectivity_state( + channel, 1 /* try_to_connect */) == GRPC_CHANNEL_IDLE); + + // Wait a bounded number of times for the channel to be ready. When the + // channel is ready, the initial TLS handshake will have successfully + // completed. The total time spent on the client side (retries * deadline) + // should be greater than the server side time limit. + int retries = 10; + grpc_connectivity_state state = GRPC_CHANNEL_IDLE; + grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); + + while (state != GRPC_CHANNEL_READY && retries-- > 0) { + grpc_channel_watch_connectivity_state( + channel, state, grpc_timeout_seconds_to_deadline(3), cq, nullptr); + gpr_timespec cq_deadline = grpc_timeout_seconds_to_deadline(5); + grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, nullptr); + GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); + state = + grpc_channel_check_connectivity_state(channel, 0 /* try_to_connect */); + } + grpc_completion_queue_destroy(cq); + if (retries < 0) { + success = false; + } + + grpc_channel_destroy(channel); + grpc_channel_credentials_release(ssl_creds); + grpc_slice_unref(cert_slice); + grpc_slice_unref(key_slice); + grpc_slice_unref(ca_slice); + + // Now that the client is completely cleaned up, trigger the server to + // shutdown + gpr_event_set(&client_handshake_complete, &client_handshake_complete); + // Wait for the server to completely shutdown + thd.Join(); + + grpc_shutdown(); + + return success; +} + +static int callback_return_value = 0; +static char callback_target_host[4096]; +static char callback_target_pem[4096]; +static void* callback_userdata = nullptr; +static void* destruct_userdata = nullptr; + +static int verify_callback(const char* target_host, const char* target_pem, + void* userdata) { + if (target_host != nullptr) { + snprintf(callback_target_host, sizeof(callback_target_host), "%s", + target_host); + } else { + callback_target_host[0] = '\0'; + } + if (target_pem != nullptr) { + snprintf(callback_target_pem, sizeof(callback_target_pem), "%s", + target_pem); + } else { + callback_target_pem[0] = '\0'; + } + callback_userdata = userdata; + return callback_return_value; +} + +static void verify_destruct(void* userdata) { destruct_userdata = userdata; } + +int main(int argc, char* argv[]) { + int userdata = 42; + verify_peer_options verify_options; + + // Load the server's cert so that we can assert it gets passed to the callback + grpc_slice cert_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); + const char* server_cert = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); + + // Running with all-null values should have no effect + verify_options.verify_peer_callback = nullptr; + verify_options.verify_peer_callback_userdata = nullptr; + verify_options.verify_peer_destruct = nullptr; + GPR_ASSERT(verify_peer_options_test(&verify_options)); + GPR_ASSERT(strlen(callback_target_host) == 0); + GPR_ASSERT(strlen(callback_target_pem) == 0); + GPR_ASSERT(callback_userdata == nullptr); + GPR_ASSERT(destruct_userdata == nullptr); + + // Running with the callbacks and verify we get the expected values + verify_options.verify_peer_callback = verify_callback; + verify_options.verify_peer_callback_userdata = static_cast<void*>(&userdata); + verify_options.verify_peer_destruct = verify_destruct; + GPR_ASSERT(verify_peer_options_test(&verify_options)); + GPR_ASSERT(strcmp(callback_target_host, "foo.test.google.fr") == 0); + GPR_ASSERT(strcmp(callback_target_pem, server_cert) == 0); + GPR_ASSERT(callback_userdata == static_cast<void*>(&userdata)); + GPR_ASSERT(destruct_userdata == static_cast<void*>(&userdata)); + + // If the callback returns non-zero, initializing the channel should fail. + callback_return_value = 1; + GPR_ASSERT(!verify_peer_options_test(&verify_options)); + + grpc_slice_unref(cert_slice); + + return 0; +} + +#else /* GRPC_POSIX_SOCKET */ + +int main(int argc, char** argv) { return 1; } + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/test/core/security/BUILD b/test/core/security/BUILD index 70bcc8c9c3..12aa84d93b 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -183,6 +183,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", + "//test/core/util:gpr_test_util", ], ) @@ -195,6 +196,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", + "//test/core/util:gpr_test_util", ], ) @@ -206,6 +208,7 @@ grpc_cc_test( "//:alts_util", "//:gpr", "//:grpc", + "//test/core/util:gpr_test_util", ], ) @@ -220,5 +223,6 @@ grpc_cc_test( "//:grpc_secure", "//:tsi", "//:tsi_interface", + "//test/core/util:gpr_test_util", ], ) diff --git a/test/core/statistics/census_log_tests.h b/test/core/statistics/census_log_tests.h deleted file mode 100644 index ed808636e3..0000000000 --- a/test/core/statistics/census_log_tests.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H -#define GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H - -void test_invalid_record_size(); -void test_end_write_with_different_size(); -void test_read_pending_record(); -void test_read_beyond_pending_record(); -void test_detached_while_reading(); -void test_fill_log_no_fragmentation(); -void test_fill_circular_log_no_fragmentation(); -void test_fill_log_with_straddling_records(); -void test_fill_circular_log_with_straddling_records(); -void test_multiple_writers_circular_log(); -void test_multiple_writers(); -void test_performance(); -void test_small_log(); - -#endif /* GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H */ diff --git a/test/core/statistics/census_stub_test.cc b/test/core/statistics/census_stub_test.cc deleted file mode 100644 index 507ae0a9fa..0000000000 --- a/test/core/statistics/census_stub_test.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <stdio.h> -#include <stdlib.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include "src/core/ext/census/census_interface.h" -#include "src/core/ext/census/census_rpc_stats.h" -#include "test/core/util/test_config.h" - -/* Tests census noop stubs in a simulated rpc flow */ -void test_census_stubs(void) { - census_op_id op_id; - census_rpc_stats* stats = census_rpc_stats_create_empty(); - census_aggregated_rpc_stats data_map = {0, NULL}; - - /* Initializes census library at server start up time. */ - census_init(); - /* Starts tracing at the beginning of a rpc. */ - op_id = census_tracing_start_op(); - /* Appends custom annotations on a trace object. */ - census_tracing_print(op_id, "annotation foo"); - census_tracing_print(op_id, "annotation bar"); - /* Appends method tag on the trace object. */ - census_add_method_tag(op_id, "service_foo/method.bar"); - /* Either record client side stats or server side stats associated with the - op_id. Here for testing purpose, we record both. */ - census_record_rpc_client_stats(op_id, stats); - census_record_rpc_server_stats(op_id, stats); - /* Ends a tracing. */ - census_tracing_end_op(op_id); - /* In process stats queries. */ - census_get_server_stats(&data_map); - census_aggregated_rpc_stats_set_empty(&data_map); - census_get_client_stats(&data_map); - census_aggregated_rpc_stats_set_empty(&data_map); - gpr_free(stats); - census_shutdown(); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - test_census_stubs(); - return 0; -} diff --git a/test/core/statistics/multiple_writers_circular_buffer_test.cc b/test/core/statistics/multiple_writers_circular_buffer_test.cc deleted file mode 100644 index 6d3411289e..0000000000 --- a/test/core/statistics/multiple_writers_circular_buffer_test.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/statistics/census_log_tests.h" - -#include <stdlib.h> - -#include <grpc/support/time.h> -#include "test/core/util/test_config.h" - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - test_multiple_writers_circular_log(); - return 0; -} diff --git a/test/core/statistics/multiple_writers_test.cc b/test/core/statistics/multiple_writers_test.cc deleted file mode 100644 index 47410ab105..0000000000 --- a/test/core/statistics/multiple_writers_test.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/statistics/census_log_tests.h" - -#include <stdlib.h> - -#include <grpc/support/time.h> -#include "test/core/util/test_config.h" - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - test_multiple_writers(); - return 0; -} diff --git a/test/core/statistics/performance_test.cc b/test/core/statistics/performance_test.cc deleted file mode 100644 index 9d4fd6ef90..0000000000 --- a/test/core/statistics/performance_test.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/statistics/census_log_tests.h" - -#include <stdlib.h> - -#include <grpc/support/time.h> -#include "test/core/util/test_config.h" - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - test_performance(); - return 0; -} diff --git a/test/core/statistics/quick_test.cc b/test/core/statistics/quick_test.cc deleted file mode 100644 index 91ecdde818..0000000000 --- a/test/core/statistics/quick_test.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/statistics/census_log_tests.h" - -#include <stdlib.h> - -#include <grpc/support/time.h> -#include "test/core/util/test_config.h" - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - test_invalid_record_size(); - test_end_write_with_different_size(); - test_read_pending_record(); - test_read_beyond_pending_record(); - test_detached_while_reading(); - test_fill_log_no_fragmentation(); - test_fill_circular_log_no_fragmentation(); - test_fill_log_with_straddling_records(); - test_fill_circular_log_with_straddling_records(); - return 0; -} diff --git a/test/core/statistics/rpc_stats_test.cc b/test/core/statistics/rpc_stats_test.cc deleted file mode 100644 index a2a648e2ad..0000000000 --- a/test/core/statistics/rpc_stats_test.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/port_platform.h> -#include <grpc/support/string.h> -#include <grpc/support/time.h> - -#include "src/core/ext/census/census_interface.h" -#include "src/core/ext/census/census_rpc_stats.h" -#include "src/core/ext/census/census_tracing.h" -#include "test/core/util/test_config.h" - -/* Ensure all possible state transitions are called without causing problem */ -static void test_init_shutdown(void) { - census_stats_store_init(); - census_stats_store_init(); - census_stats_store_shutdown(); - census_stats_store_shutdown(); - census_stats_store_init(); -} - -static void test_create_and_destroy(void) { - census_rpc_stats* stats = NULL; - census_aggregated_rpc_stats agg_stats = {0, NULL}; - - stats = census_rpc_stats_create_empty(); - GPR_ASSERT(stats != NULL); - GPR_ASSERT(stats->cnt == 0 && stats->rpc_error_cnt == 0 && - stats->app_error_cnt == 0 && stats->elapsed_time_ms == 0.0 && - stats->api_request_bytes == 0 && stats->wire_request_bytes == 0 && - stats->api_response_bytes == 0 && stats->wire_response_bytes == 0); - gpr_free(stats); - - census_aggregated_rpc_stats_set_empty(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - GPR_ASSERT(agg_stats.stats == NULL); - agg_stats.num_entries = 1; - agg_stats.stats = (census_per_method_rpc_stats*)gpr_malloc( - sizeof(census_per_method_rpc_stats)); - agg_stats.stats[0].method = gpr_strdup("foo"); - census_aggregated_rpc_stats_set_empty(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - GPR_ASSERT(agg_stats.stats == NULL); -} - -#define ASSERT_NEAR(a, b) \ - GPR_ASSERT((a - b) * (a - b) < 1e-24 * (a + b) * (a + b)) - -static void test_record_and_get_stats(void) { - census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4}; - census_op_id id; - census_aggregated_rpc_stats agg_stats = {0, NULL}; - - /* Record client stats twice with the same op_id. */ - census_init(); - id = census_tracing_start_op(); - census_add_method_tag(id, "m1"); - census_record_rpc_client_stats(id, &stats); - census_record_rpc_client_stats(id, &stats); - census_tracing_end_op(id); - /* Server stats expect to be empty */ - census_get_server_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - GPR_ASSERT(agg_stats.stats == NULL); - /* Client stats expect to have one entry */ - census_get_client_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 1); - GPR_ASSERT(agg_stats.stats != NULL); - GPR_ASSERT(strcmp(agg_stats.stats[0].method, "m1") == 0); - GPR_ASSERT(agg_stats.stats[0].minute_stats.cnt == 2 && - agg_stats.stats[0].hour_stats.cnt == 2 && - agg_stats.stats[0].total_stats.cnt == 2); - ASSERT_NEAR(agg_stats.stats[0].minute_stats.wire_response_bytes, 16.8); - ASSERT_NEAR(agg_stats.stats[0].hour_stats.wire_response_bytes, 16.8); - ASSERT_NEAR(agg_stats.stats[0].total_stats.wire_response_bytes, 16.8); - /* Get stats again, results should be the same. */ - census_get_client_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 1); - census_aggregated_rpc_stats_set_empty(&agg_stats); - census_shutdown(); - - /* Record both server (once) and client (twice) stats with different op_ids. - */ - census_init(); - id = census_tracing_start_op(); - census_add_method_tag(id, "m2"); - census_record_rpc_client_stats(id, &stats); - census_tracing_end_op(id); - id = census_tracing_start_op(); - census_add_method_tag(id, "m3"); - census_record_rpc_server_stats(id, &stats); - census_tracing_end_op(id); - id = census_tracing_start_op(); - census_add_method_tag(id, "m4"); - census_record_rpc_client_stats(id, &stats); - census_tracing_end_op(id); - /* Check server stats */ - census_get_server_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 1); - GPR_ASSERT(strcmp(agg_stats.stats[0].method, "m3") == 0); - GPR_ASSERT(agg_stats.stats[0].minute_stats.app_error_cnt == 3 && - agg_stats.stats[0].hour_stats.app_error_cnt == 3 && - agg_stats.stats[0].total_stats.app_error_cnt == 3); - census_aggregated_rpc_stats_set_empty(&agg_stats); - /* Check client stats */ - census_get_client_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 2); - GPR_ASSERT(agg_stats.stats != NULL); - GPR_ASSERT((strcmp(agg_stats.stats[0].method, "m2") == 0 && - strcmp(agg_stats.stats[1].method, "m4") == 0) || - (strcmp(agg_stats.stats[0].method, "m4") == 0 && - strcmp(agg_stats.stats[1].method, "m2") == 0)); - GPR_ASSERT(agg_stats.stats[0].minute_stats.cnt == 1 && - agg_stats.stats[1].minute_stats.cnt == 1); - census_aggregated_rpc_stats_set_empty(&agg_stats); - census_shutdown(); -} - -static void test_record_stats_on_unknown_op_id(void) { - census_op_id unknown_id = {0xDEAD, 0xBEEF}; - census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4}; - census_aggregated_rpc_stats agg_stats = {0, NULL}; - - census_init(); - /* Tests that recording stats against unknown id is noop. */ - census_record_rpc_client_stats(unknown_id, &stats); - census_record_rpc_server_stats(unknown_id, &stats); - census_get_server_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - GPR_ASSERT(agg_stats.stats == NULL); - census_get_client_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - GPR_ASSERT(agg_stats.stats == NULL); - census_aggregated_rpc_stats_set_empty(&agg_stats); - census_shutdown(); -} - -/* Test that record stats is noop when trace store is uninitialized. */ -static void test_record_stats_with_trace_store_uninitialized(void) { - census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4}; - census_op_id id = {0, 0}; - census_aggregated_rpc_stats agg_stats = {0, NULL}; - - census_init(); - id = census_tracing_start_op(); - census_add_method_tag(id, "m"); - census_tracing_end_op(id); - /* shuts down trace store only. */ - census_tracing_shutdown(); - census_record_rpc_client_stats(id, &stats); - census_get_client_stats(&agg_stats); - GPR_ASSERT(agg_stats.num_entries == 0); - census_stats_store_shutdown(); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - test_init_shutdown(); - test_create_and_destroy(); - test_record_and_get_stats(); - test_record_stats_on_unknown_op_id(); - test_record_stats_with_trace_store_uninitialized(); - return 0; -} diff --git a/test/core/statistics/small_log_test.cc b/test/core/statistics/small_log_test.cc deleted file mode 100644 index fb8dfc9988..0000000000 --- a/test/core/statistics/small_log_test.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/statistics/census_log_tests.h" - -#include <stdlib.h> - -#include <grpc/support/time.h> -#include "test/core/util/test_config.h" - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - test_small_log(); - return 0; -} diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 467deeeaec..7b7a0b6dfc 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -168,7 +168,7 @@ static const test_fixture insecure_test = { static grpc_channel* secure_test_create_channel(const char* addr) { grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr); + grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr, nullptr); grpc_arg ssl_name_override = { GRPC_ARG_STRING, const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 52a1b03998..29083061bb 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -106,8 +106,6 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_insecure_channel_create); printf("%lx", (unsigned long) grpc_lame_client_channel_create); printf("%lx", (unsigned long) grpc_channel_destroy); - printf("%lx", (unsigned long) grpc_channel_get_trace); - printf("%lx", (unsigned long) grpc_channel_get_uuid); printf("%lx", (unsigned long) grpc_call_cancel); printf("%lx", (unsigned long) grpc_call_cancel_with_status); printf("%lx", (unsigned long) grpc_call_ref); diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 9aba4c499e..10562b3be9 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -144,7 +144,7 @@ static void secure_test_add_port(grpc_server* server, const char* addr) { static grpc_channel* secure_test_create_channel(const char* addr) { grpc_channel_credentials* ssl_creds = - grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr); + grpc_ssl_credentials_create(test_root_cert, nullptr, nullptr, nullptr); grpc_arg ssl_name_override = { GRPC_ARG_STRING, const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 84fb3a1421..7ca1c1d943 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -129,6 +129,7 @@ grpc_cc_test( language = "C++", deps = [ "//:grpc", + "//test/core/util:gpr_test_util", ], external_deps = [ "gtest", diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD index cf9dbca316..abe1e83656 100644 --- a/test/core/tsi/alts/crypt/BUILD +++ b/test/core/tsi/alts/crypt/BUILD @@ -27,6 +27,7 @@ grpc_cc_test( "//:alts_frame_protector", "//:gpr", "//:grpc", + "//test/core/util:gpr_test_util", ], ) diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD index dd1966b379..6ff3015f4d 100644 --- a/test/core/tsi/alts/frame_protector/BUILD +++ b/test/core/tsi/alts/frame_protector/BUILD @@ -27,6 +27,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) @@ -39,6 +40,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) @@ -54,6 +56,7 @@ grpc_cc_test( "//:tsi_interface", "//test/core/tsi/alts/crypt:alts_crypt_test_util", "//test/core/tsi:transport_security_test_lib", + "//test/core/util:gpr_test_util", ], ) @@ -67,5 +70,6 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD index 809742744c..3f1a681c1a 100644 --- a/test/core/tsi/alts/handshaker/BUILD +++ b/test/core/tsi/alts/handshaker/BUILD @@ -37,6 +37,7 @@ grpc_cc_test( "//:tsi", "//:tsi_interface", "//:grpc", + "//test/core/util:gpr_test_util", ], ) @@ -47,6 +48,7 @@ grpc_cc_test( deps = [ ":alts_handshaker_service_api_test_lib", "//:grpc", + "//test/core/util:gpr_test_util", ], ) @@ -60,6 +62,7 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//:tsi", + "//test/core/util:gpr_test_util", ], ) @@ -71,6 +74,7 @@ grpc_cc_test( ":alts_handshaker_service_api_test_lib", "//:grpc", "//:tsi", + "//test/core/util:gpr_test_util", ], ) @@ -81,6 +85,7 @@ grpc_cc_test( deps = [ "//:alts_util", "//:grpc", + "//test/core/util:gpr_test_util", ], ) diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD index 2b41dae043..a3b797327e 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/BUILD +++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD @@ -28,6 +28,7 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) @@ -40,6 +41,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) @@ -53,5 +55,6 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:gpr_test_util", ], ) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index f52570cde5..5492dcfa79 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -32,6 +32,11 @@ grpc_cc_library( "test_config.h", ], deps = ["//:gpr"], + data = [ + "lsan_suppressions.txt", + "tsan_suppressions.txt", + "ubsan_suppressions.txt", + ], ) grpc_cc_library( diff --git a/test/core/util/lsan_suppressions.txt b/test/core/util/lsan_suppressions.txt new file mode 100644 index 0000000000..204ddbef5e --- /dev/null +++ b/test/core/util/lsan_suppressions.txt @@ -0,0 +1,6 @@ +# this is busted in BoringSSL +leak:CRYPTO_set_thread_local +leak:err_get_state +leak:ERR_add_error_dataf +leak:err_add_error_vdata +leak:RAND_bytes_with_additional_data diff --git a/test/core/util/tsan_suppressions.txt b/test/core/util/tsan_suppressions.txt new file mode 100644 index 0000000000..e0c7907228 --- /dev/null +++ b/test/core/util/tsan_suppressions.txt @@ -0,0 +1,13 @@ +# OPENSSL_cleanse does racy access to a global +race:OPENSSL_cleanse +race:cleanse_ctr +# these are legitimate races in OpenSSL, and it appears those folks are looking at it +# https://www.mail-archive.com/openssl-dev@openssl.org/msg09019.html +race:ssleay_rand_add +race:ssleay_rand_bytes +race:__sleep_for +# protobuf has an idempotent write race in ByteSize/GetCachedSize +# https://github.com/google/protobuf/issues/2169 +race:ByteSize +race:ByteSizeLong +race:GetCachedSize diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt new file mode 100644 index 0000000000..2268adc169 --- /dev/null +++ b/test/core/util/ubsan_suppressions.txt @@ -0,0 +1,17 @@ +# boringssl stuff +nonnull-attribute:bn_wexpand +nonnull-attribute:CBB_add_bytes +nonnull-attribute:rsa_blinding_get +nonnull-attribute:ssl_copy_key_material +alignment:CRYPTO_cbc128_encrypt +alignment:CRYPTO_gcm128_encrypt +alignment:poly1305_block_copy +nonnull-attribute:google::protobuf::* +alignment:google::protobuf::* +nonnull-attribute:_tr_stored_block +# The following 5 suppressors should be removed as part of C++ cleanup +enum:client_fuzzer_one_entry +enum:message_compress_test +enum:transport_security_test +enum:algorithm_test +alignment:transport_security_test |