21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
24 #include "absl/strings/numbers.h"
25 #include "absl/strings/str_format.h"
39 TEST(XdsBootstrapTest, Basic) {
40 gpr_setenv(
"GRPC_EXPERIMENTAL_XDS_FEDERATION",
"true");
41 const char* json_str =
45 " \"server_uri\": \"fake:///lb\","
46 " \"channel_creds\": ["
48 " \"type\": \"fake\","
55 " \"server_uri\": \"ignored\","
56 " \"channel_creds\": ["
58 " \"type\": \"ignored\","
69 " \"xds.example.com\": {"
70 " \"client_listener_resource_name_template\": "
71 "\"xdstp://xds.example.com/envoy.config.listener.v3.Listener/grpc/server/"
75 " \"server_uri\": \"fake:///xds_server\","
76 " \"channel_creds\": ["
81 " \"server_features\": [\"xds_v3\"]"
85 " \"xds.example2.com\": {"
86 " \"client_listener_resource_name_template\": "
87 "\"xdstp://xds.example2.com/envoy.config.listener.v3.Listener/grpc/"
91 " \"server_uri\": \"fake:///xds_server2\","
92 " \"channel_creds\": ["
97 " \"server_features\": [\"xds_v3\"]"
104 " \"cluster\": \"bar\","
106 " \"region\": \"milky_way\","
107 " \"zone\": \"sol_system\","
108 " \"sub_zone\": \"earth\","
115 " \"ignore\": \"whee\""
117 " \"server_listener_resource_name_template\": \"example/resource\","
125 EXPECT_EQ(bootstrap.server().server_uri,
"fake:///lb");
126 EXPECT_EQ(bootstrap.server().channel_creds_type,
"fake");
127 EXPECT_EQ(bootstrap.server().channel_creds_config.type(),
129 EXPECT_EQ(bootstrap.authorities().size(), 2);
130 const XdsBootstrap::Authority* authority1 =
131 bootstrap.LookupAuthority(
"xds.example.com");
133 EXPECT_EQ(authority1->client_listener_resource_name_template,
134 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/grpc/"
136 EXPECT_EQ(authority1->xds_servers.size(), 1);
137 EXPECT_EQ(authority1->xds_servers[0].server_uri,
"fake:///xds_server");
138 EXPECT_EQ(authority1->xds_servers[0].channel_creds_type,
"fake");
139 EXPECT_EQ(authority1->xds_servers[0].channel_creds_config.type(),
141 const XdsBootstrap::Authority* authority2 =
142 bootstrap.LookupAuthority(
"xds.example2.com");
144 EXPECT_EQ(authority2->client_listener_resource_name_template,
145 "xdstp://xds.example2.com/envoy.config.listener.v3.Listener/grpc/"
147 EXPECT_EQ(authority2->xds_servers.size(), 1);
148 EXPECT_EQ(authority2->xds_servers[0].server_uri,
"fake:///xds_server2");
149 EXPECT_EQ(authority2->xds_servers[0].channel_creds_type,
"fake");
150 EXPECT_EQ(authority2->xds_servers[0].channel_creds_config.type(),
154 EXPECT_EQ(bootstrap.node()->cluster,
"bar");
155 EXPECT_EQ(bootstrap.node()->locality_region,
"milky_way");
156 EXPECT_EQ(bootstrap.node()->locality_zone,
"sol_system");
157 EXPECT_EQ(bootstrap.node()->locality_sub_zone,
"earth");
159 EXPECT_THAT(bootstrap.node()->metadata.object_value(),
171 EXPECT_EQ(bootstrap.server_listener_resource_name_template(),
176 TEST(XdsBootstrapTest, ValidWithoutNode) {
177 const char* json_str =
179 " \"xds_servers\": ["
181 " \"server_uri\": \"fake:///lb\","
182 " \"channel_creds\": [{\"type\": \"fake\"}]"
191 EXPECT_EQ(bootstrap.server().server_uri,
"fake:///lb");
192 EXPECT_EQ(bootstrap.server().channel_creds_type,
"fake");
196 TEST(XdsBootstrapTest, InsecureCreds) {
197 const char* json_str =
199 " \"xds_servers\": ["
201 " \"server_uri\": \"fake:///lb\","
202 " \"channel_creds\": [{\"type\": \"insecure\"}]"
211 EXPECT_EQ(bootstrap.server().server_uri,
"fake:///lb");
212 EXPECT_EQ(bootstrap.server().channel_creds_type,
"insecure");
216 TEST(XdsBootstrapTest, GoogleDefaultCreds) {
218 const char token_str[] =
219 "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
220 " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
221 " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
222 " \"type\": \"authorized_user\"}";
233 const char* json_str =
235 " \"xds_servers\": ["
237 " \"server_uri\": \"fake:///lb\","
238 " \"channel_creds\": [{\"type\": \"google_default\"}]"
247 EXPECT_EQ(bootstrap.server().server_uri,
"fake:///lb");
248 EXPECT_EQ(bootstrap.server().channel_creds_type,
"google_default");
252 TEST(XdsBootstrapTest, MissingChannelCreds) {
253 const char* json_str =
255 " \"xds_servers\": ["
257 " \"server_uri\": \"fake:///lb\""
271 TEST(XdsBootstrapTest, NoKnownChannelCreds) {
272 const char* json_str =
274 " \"xds_servers\": ["
276 " \"server_uri\": \"fake:///lb\","
277 " \"channel_creds\": [{\"type\": \"unknown\"}]"
287 "no known creds type found in \"channel_creds\""));
291 TEST(XdsBootstrapTest, MissingXdsServers) {
301 TEST(XdsBootstrapTest, TopFieldsWrongTypes) {
302 const char* json_str =
304 " \"xds_servers\":1,"
306 " \"server_listener_resource_name_template\":1,"
307 " \"certificate_providers\":1"
315 "\"node\" field is not an object.*"
316 "\"server_listener_resource_name_"
317 "template\" field is not a string.*"));
320 "\"certificate_providers\" field is not an object"));
324 TEST(XdsBootstrapTest, XdsServerMissingServerUri) {
325 const char* json_str =
327 " \"xds_servers\":[{}]"
336 "errors parsing index 0.*"
337 "errors parsing xds server.*"
338 "field:server_uri error:does not exist."));
342 TEST(XdsBootstrapTest, XdsServerUriAndCredsWrongTypes) {
343 const char* json_str =
348 " \"channel_creds\":1"
358 "errors parsing \"xds_servers\" array.*"
359 "errors parsing index 0.*"
360 "errors parsing xds server.*"
361 "field:server_uri error:type should be STRING.*"
362 "field:channel_creds error:type should be ARRAY"));
366 TEST(XdsBootstrapTest, ChannelCredsFieldsWrongTypes) {
367 const char* json_str =
371 " \"server_uri\":\"foo\","
372 " \"channel_creds\":["
388 "errors parsing index 0.*"
389 "errors parsing xds server.*"
390 "errors parsing \"channel_creds\" array.*"
391 "errors parsing index 0.*"
392 "field:type error:type should be STRING.*"
393 "field:config error:type should be OBJECT"));
397 TEST(XdsBootstrapTest, NodeFieldsWrongTypes) {
398 const char* json_str =
413 "\"id\" field is not a string.*"
414 "\"cluster\" field is not a string.*"
415 "\"locality\" field is not an object.*"
416 "\"metadata\" field is not an object"));
420 TEST(XdsBootstrapTest, LocalityFieldsWrongType) {
421 const char* json_str =
437 "errors parsing \"locality\" object.*"
438 "\"region\" field is not a string.*"
439 "\"zone\" field is not a string.*"
440 "\"sub_zone\" field is not a string"));
444 TEST(XdsBootstrapTest, CertificateProvidersElementWrongType) {
445 const char* json_str =
447 " \"xds_servers\": ["
449 " \"server_uri\": \"fake:///lb\","
450 " \"channel_creds\": [{\"type\": \"fake\"}]"
453 " \"certificate_providers\": {"
463 "errors parsing \"certificate_providers\" object.*"
464 "element \"plugin\" is not an object"));
468 TEST(XdsBootstrapTest, CertificateProvidersPluginNameWrongType) {
469 const char* json_str =
471 " \"xds_servers\": ["
473 " \"server_uri\": \"fake:///lb\","
474 " \"channel_creds\": [{\"type\": \"fake\"}]"
477 " \"certificate_providers\": {"
489 "errors parsing \"certificate_providers\" object.*"
490 "errors parsing element \"plugin\".*"
491 "\"plugin_name\" field is not a string"));
495 TEST(XdsBootstrapTest, CertificateProvidersUnrecognizedPluginName) {
496 const char* json_str =
498 " \"xds_servers\": ["
500 " \"server_uri\": \"fake:///lb\","
501 " \"channel_creds\": [{\"type\": \"fake\"}]"
504 " \"certificate_providers\": {"
506 " \"plugin_name\":\"unknown\""
516 "errors parsing \"certificate_providers\" object.*"
517 "errors parsing element \"plugin\".*"
518 "Unrecognized plugin name: unknown"));
522 TEST(XdsBootstrapTest, AuthorityXdsServerInvalidResourceTemplate) {
523 gpr_setenv(
"GRPC_EXPERIMENTAL_XDS_FEDERATION",
"true");
524 const char* json_str =
526 " \"xds_servers\": ["
528 " \"server_uri\": \"fake:///lb\","
529 " \"channel_creds\": [{\"type\": \"fake\"}]"
532 " \"authorities\": {"
533 " \"xds.example.com\": {"
534 " \"client_listener_resource_name_template\": "
535 "\"xds://xds.example.com/envoy.config.listener.v3.Listener/grpc/server/"
537 " \"xds_servers\": ["
539 " \"server_uri\": \"fake:///xds_server\","
540 " \"channel_creds\": ["
542 " \"type\": \"fake\""
545 " \"server_features\": [\"xds_v3\"]"
557 "errors parsing \"authorities\".*"
558 "errors parsing authority xds.example.com.*"
559 "field must begin with \"xdstp://xds.example.com/\""));
564 TEST(XdsBootstrapTest, AuthorityXdsServerMissingServerUri) {
565 gpr_setenv(
"GRPC_EXPERIMENTAL_XDS_FEDERATION",
"true");
566 const char* json_str =
568 " \"xds_servers\": ["
570 " \"server_uri\": \"fake:///lb\","
571 " \"channel_creds\": [{\"type\": \"fake\"}]"
574 " \"authorities\": {"
575 " \"xds.example.com\": {"
576 " \"client_listener_resource_name_template\": "
577 "\"xdstp://xds.example.com/envoy.config.listener.v3.Listener/grpc/server/"
579 " \"xds_servers\":[{}]"
590 "errors parsing authority xds.example.com.*"
591 "errors parsing \"xds_servers\" array.*"
592 "errors parsing index 0.*"
593 "errors parsing xds server.*"
594 "field:server_uri error:does not exist."));
599 class FakeCertificateProviderFactory :
public CertificateProviderFactory {
607 const char*
name()
const override {
return "fake"; }
621 const char*
name()
const override {
return "fake"; }
623 RefCountedPtr<CertificateProviderFactory::Config>
624 CreateCertificateProviderConfig(
const Json& config_json,
626 std::vector<grpc_error_handle> error_list;
628 auto it = config_json.object_value().find(
"value");
629 if (
it == config_json.object_value().end()) {
630 return MakeRefCounted<FakeCertificateProviderFactory::Config>(0);
633 "field:config field:value not of type number");
637 return MakeRefCounted<FakeCertificateProviderFactory::Config>(
value);
642 RefCountedPtr<grpc_tls_certificate_provider> CreateCertificateProvider(
643 RefCountedPtr<CertificateProviderFactory::Config> )
override {
648 TEST(XdsBootstrapTest, CertificateProvidersFakePluginParsingError) {
649 const char* json_str =
651 " \"xds_servers\": ["
653 " \"server_uri\": \"fake:///lb\","
654 " \"channel_creds\": [{\"type\": \"fake\"}]"
657 " \"certificate_providers\": {"
658 " \"fake_plugin\": {"
659 " \"plugin_name\": \"fake\","
672 "errors parsing \"certificate_providers\" object.*"
673 "errors parsing element \"fake_plugin\".*"
674 "field:config field:value not of type number"));
678 TEST(XdsBootstrapTest, CertificateProvidersFakePluginParsingSuccess) {
679 const char* json_str =
681 " \"xds_servers\": ["
683 " \"server_uri\": \"fake:///lb\","
684 " \"channel_creds\": [{\"type\": \"fake\"}]"
687 " \"certificate_providers\": {"
688 " \"fake_plugin\": {"
689 " \"plugin_name\": \"fake\","
701 const CertificateProviderStore::PluginDefinition& fake_plugin =
702 bootstrap.certificate_providers().at(
"fake_plugin");
703 ASSERT_EQ(fake_plugin.plugin_name,
"fake");
705 ASSERT_EQ(
static_cast<RefCountedPtr<FakeCertificateProviderFactory::Config>
>(
711 TEST(XdsBootstrapTest, CertificateProvidersFakePluginEmptyConfig) {
712 const char* json_str =
714 " \"xds_servers\": ["
716 " \"server_uri\": \"fake:///lb\","
717 " \"channel_creds\": [{\"type\": \"fake\"}]"
720 " \"certificate_providers\": {"
721 " \"fake_plugin\": {"
722 " \"plugin_name\": \"fake\""
731 const CertificateProviderStore::PluginDefinition& fake_plugin =
732 bootstrap.certificate_providers().at(
"fake_plugin");
733 ASSERT_EQ(fake_plugin.plugin_name,
"fake");
735 ASSERT_EQ(
static_cast<RefCountedPtr<FakeCertificateProviderFactory::Config>
>(
741 TEST(XdsBootstrapTest, XdsServerToJsonAndParse) {
742 gpr_setenv(
"GRPC_EXPERIMENTAL_XDS_FEDERATION",
"true");
743 const char* json_str =
745 " \"server_uri\": \"fake:///lb\","
746 " \"channel_creds\": ["
748 " \"type\": \"fake\","
757 XdsBootstrap::XdsServer xds_server =
761 XdsBootstrap::XdsServer output_xds_server =
771 int main(
int argc,
char** argv) {
776 absl::make_unique<grpc_core::testing::FakeCertificateProviderFactory>());