1 //
2 //
3 // Copyright 2020 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include "src/core/ext/xds/xds_certificate_provider.h"
20
21 #include "absl/status/status.h"
22 #include "absl/types/optional.h"
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25
26 #include <grpc/grpc.h>
27
28 #include "src/core/lib/gpr/useful.h"
29 #include "src/core/lib/gprpp/status_helper.h"
30 #include "src/core/lib/iomgr/error.h"
31 #include "src/core/lib/security/security_connector/ssl_utils.h"
32 #include "test/core/util/test_config.h"
33 #include "test/core/util/tls_utils.h"
34
35 namespace grpc_core {
36 namespace testing {
37 namespace {
38
39 constexpr const char* kRootCert1 = "root_cert_1_contents";
40 constexpr const char* kRootCert2 = "root_cert_2_contents";
41 constexpr const char* kIdentityCert1PrivateKey = "identity_private_key_1";
42 constexpr const char* kIdentityCert1 = "identity_cert_1_contents";
43 constexpr const char* kIdentityCert2PrivateKey = "identity_private_key_2";
44 constexpr const char* kIdentityCert2 = "identity_cert_2_contents";
45 constexpr const char* kRootErrorMessage = "root_error_message";
46 constexpr const char* kIdentityErrorMessage = "identity_error_message";
47
MakeKeyCertPairsType1()48 PemKeyCertPairList MakeKeyCertPairsType1() {
49 return MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1);
50 }
51
MakeKeyCertPairsType2()52 PemKeyCertPairList MakeKeyCertPairsType2() {
53 return MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2);
54 }
55
56 class TestCertProvider : public grpc_tls_certificate_provider {
57 public:
TestCertProvider()58 TestCertProvider()
59 : distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()) {}
60
type() const61 UniqueTypeName type() const override {
62 static UniqueTypeName::Factory kFactory("Xds");
63 return kFactory.Create();
64 }
65
distributor() const66 RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
67 return distributor_;
68 }
69
70 private:
CompareImpl(const grpc_tls_certificate_provider * other) const71 int CompareImpl(const grpc_tls_certificate_provider* other) const override {
72 return QsortCompare(this, static_cast<const TestCertProvider*>(other));
73 }
74
75 RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
76 };
77
78 class TestCertificatesWatcher
79 : public grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface {
80 public:
~TestCertificatesWatcher()81 ~TestCertificatesWatcher() override {}
82
OnCertificatesChanged(absl::optional<absl::string_view> root_certs,absl::optional<PemKeyCertPairList> key_cert_pairs)83 void OnCertificatesChanged(
84 absl::optional<absl::string_view> root_certs,
85 absl::optional<PemKeyCertPairList> key_cert_pairs) override {
86 if (root_certs.has_value()) {
87 if (!root_certs_.has_value() ||
88 (root_certs_.has_value() &&
89 std::string(root_certs.value()) != root_certs_.value())) {
90 root_cert_error_ = absl::OkStatus();
91 }
92 root_certs_.emplace(std::string(root_certs.value()));
93 }
94 if (key_cert_pairs.has_value()) {
95 if (key_cert_pairs != key_cert_pairs_) {
96 identity_cert_error_ = absl::OkStatus();
97 key_cert_pairs_ = key_cert_pairs;
98 }
99 }
100 }
101
OnError(grpc_error_handle root_cert_error,grpc_error_handle identity_cert_error)102 void OnError(grpc_error_handle root_cert_error,
103 grpc_error_handle identity_cert_error) override {
104 root_cert_error_ = root_cert_error;
105 identity_cert_error_ = identity_cert_error;
106 }
107
root_certs() const108 const absl::optional<std::string>& root_certs() const { return root_certs_; }
109
key_cert_pairs() const110 const absl::optional<PemKeyCertPairList>& key_cert_pairs() const {
111 return key_cert_pairs_;
112 }
113
root_cert_error() const114 grpc_error_handle root_cert_error() const { return root_cert_error_; }
115
identity_cert_error() const116 grpc_error_handle identity_cert_error() const { return identity_cert_error_; }
117
118 private:
119 absl::optional<std::string> root_certs_;
120 absl::optional<PemKeyCertPairList> key_cert_pairs_;
121 grpc_error_handle root_cert_error_;
122 grpc_error_handle identity_cert_error_;
123 };
124
TEST(XdsCertificateProviderTest,RootCertDistributorDifferentFromIdentityCertDistributorDifferentCertNames)125 TEST(
126 XdsCertificateProviderTest,
127 RootCertDistributorDifferentFromIdentityCertDistributorDifferentCertNames) {
128 auto root_provider = MakeRefCounted<TestCertProvider>();
129 auto identity_provider = MakeRefCounted<TestCertProvider>();
130 XdsCertificateProvider provider(root_provider, "root", identity_provider,
131 "identity", {});
132 auto* watcher = new TestCertificatesWatcher;
133 provider.distributor()->WatchTlsCertificates(
134 std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
135 EXPECT_EQ(watcher->root_certs(), absl::nullopt);
136 EXPECT_EQ(watcher->key_cert_pairs(), absl::nullopt);
137 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
138 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
139 // Update both root certs and identity certs
140 root_provider->distributor()->SetKeyMaterials("root", kRootCert1,
141 absl::nullopt);
142 identity_provider->distributor()->SetKeyMaterials("identity", absl::nullopt,
143 MakeKeyCertPairsType1());
144 EXPECT_EQ(watcher->root_certs(), kRootCert1);
145 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
146 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
147 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
148 // Second update for just root certs
149 root_provider->distributor()->SetKeyMaterials(
150 "root", kRootCert2,
151 MakeKeyCertPairsType2() /* does not have an effect */);
152 EXPECT_EQ(watcher->root_certs(), kRootCert2);
153 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
154 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
155 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
156 // Second update for identity certs
157 identity_provider->distributor()->SetKeyMaterials(
158 "identity", kRootCert1 /* does not have an effect */,
159 MakeKeyCertPairsType2());
160 EXPECT_EQ(watcher->root_certs(), kRootCert2);
161 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
162 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
163 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
164 // Set error for both root and identity
165 root_provider->distributor()->SetErrorForCert(
166 "root", GRPC_ERROR_CREATE(kRootErrorMessage), absl::nullopt);
167 identity_provider->distributor()->SetErrorForCert(
168 "identity", absl::nullopt, GRPC_ERROR_CREATE(kIdentityErrorMessage));
169 EXPECT_EQ(watcher->root_certs(), kRootCert2);
170 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
171 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
172 ::testing::HasSubstr(kRootErrorMessage));
173 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
174 ::testing::HasSubstr(kIdentityErrorMessage));
175 // Send an update for root certs. Test that the root cert error is reset.
176 root_provider->distributor()->SetKeyMaterials("root", kRootCert1,
177 absl::nullopt);
178 EXPECT_EQ(watcher->root_certs(), kRootCert1);
179 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
180 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
181 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
182 ::testing::HasSubstr(kIdentityErrorMessage));
183 // Send an update for identity certs. Test that the identity cert error is
184 // reset.
185 identity_provider->distributor()->SetKeyMaterials("identity", absl::nullopt,
186 MakeKeyCertPairsType1());
187 EXPECT_EQ(watcher->root_certs(), kRootCert1);
188 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
189 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
190 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
191 }
192
TEST(XdsCertificateProviderTest,RootCertDistributorDifferentFromIdentityCertDistributorSameCertNames)193 TEST(XdsCertificateProviderTest,
194 RootCertDistributorDifferentFromIdentityCertDistributorSameCertNames) {
195 auto root_provider = MakeRefCounted<TestCertProvider>();
196 auto identity_provider = MakeRefCounted<TestCertProvider>();
197 XdsCertificateProvider provider(root_provider, "test", identity_provider,
198 "test", {});
199 auto* watcher = new TestCertificatesWatcher;
200 provider.distributor()->WatchTlsCertificates(
201 std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
202 EXPECT_EQ(watcher->root_certs(), absl::nullopt);
203 EXPECT_EQ(watcher->key_cert_pairs(), absl::nullopt);
204 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
205 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
206 // Update both root certs and identity certs
207 root_provider->distributor()->SetKeyMaterials("test", kRootCert1,
208 absl::nullopt);
209 identity_provider->distributor()->SetKeyMaterials("test", absl::nullopt,
210 MakeKeyCertPairsType1());
211 EXPECT_EQ(watcher->root_certs(), kRootCert1);
212 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
213 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
214 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
215 // Second update for just root certs
216 root_provider->distributor()->SetKeyMaterials("test", kRootCert2,
217 absl::nullopt);
218 EXPECT_EQ(watcher->root_certs(), kRootCert2);
219 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
220 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
221 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
222 // Second update for identity certs
223 identity_provider->distributor()->SetKeyMaterials("test", absl::nullopt,
224 MakeKeyCertPairsType2());
225 EXPECT_EQ(watcher->root_certs(), kRootCert2);
226 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
227 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
228 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
229 // Set error for both root and identity
230 root_provider->distributor()->SetErrorForCert(
231 "test", GRPC_ERROR_CREATE(kRootErrorMessage), absl::nullopt);
232 identity_provider->distributor()->SetErrorForCert(
233 "test", absl::nullopt, GRPC_ERROR_CREATE(kIdentityErrorMessage));
234 EXPECT_EQ(watcher->root_certs(), kRootCert2);
235 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
236 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
237 ::testing::HasSubstr(kRootErrorMessage));
238 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
239 ::testing::HasSubstr(kIdentityErrorMessage));
240 // Send an update for root certs. Test that the root cert error is reset.
241 root_provider->distributor()->SetKeyMaterials("test", kRootCert1,
242 absl::nullopt);
243 EXPECT_EQ(watcher->root_certs(), kRootCert1);
244 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
245 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
246 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
247 ::testing::HasSubstr(kIdentityErrorMessage));
248 // Send an update for identity certs. Test that the identity cert error is
249 // reset.
250 identity_provider->distributor()->SetKeyMaterials("test", absl::nullopt,
251 MakeKeyCertPairsType1());
252 EXPECT_EQ(watcher->root_certs(), kRootCert1);
253 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
254 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
255 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
256 // Test update on unwatched cert name
257 identity_provider->distributor()->SetKeyMaterials("identity", kRootCert2,
258 MakeKeyCertPairsType2());
259 root_provider->distributor()->SetKeyMaterials("root", kRootCert1,
260 MakeKeyCertPairsType1());
261 }
262
TEST(XdsCertificateProviderTest,RootCertDistributorSameAsIdentityCertDistributorDifferentCertNames)263 TEST(XdsCertificateProviderTest,
264 RootCertDistributorSameAsIdentityCertDistributorDifferentCertNames) {
265 auto root_and_identity_provider = MakeRefCounted<TestCertProvider>();
266 auto distributor = root_and_identity_provider->distributor();
267 XdsCertificateProvider provider(root_and_identity_provider, "root",
268 root_and_identity_provider, "identity", {});
269 auto* watcher = new TestCertificatesWatcher;
270 provider.distributor()->WatchTlsCertificates(
271 std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
272 EXPECT_EQ(watcher->root_certs(), absl::nullopt);
273 EXPECT_EQ(watcher->key_cert_pairs(), absl::nullopt);
274 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
275 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
276 // Update both root certs and identity certs
277 distributor->SetKeyMaterials("root", kRootCert1, MakeKeyCertPairsType2());
278 distributor->SetKeyMaterials("identity", kRootCert2, MakeKeyCertPairsType1());
279 EXPECT_EQ(watcher->root_certs(), kRootCert1);
280 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
281 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
282 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
283 // Second update for just root certs
284 distributor->SetKeyMaterials("root", kRootCert2, MakeKeyCertPairsType2());
285 EXPECT_EQ(watcher->root_certs(), kRootCert2);
286 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
287 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
288 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
289 // Second update for identity certs
290 distributor->SetKeyMaterials("identity", kRootCert1, MakeKeyCertPairsType2());
291 EXPECT_EQ(watcher->root_certs(), kRootCert2);
292 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
293 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
294 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
295 // Set error for root
296 distributor->SetErrorForCert("root", GRPC_ERROR_CREATE(kRootErrorMessage),
297 GRPC_ERROR_CREATE(kRootErrorMessage));
298 EXPECT_EQ(watcher->root_certs(), kRootCert2);
299 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
300 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
301 ::testing::HasSubstr(kRootErrorMessage));
302 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
303 distributor->SetErrorForCert("identity",
304 GRPC_ERROR_CREATE(kIdentityErrorMessage),
305 GRPC_ERROR_CREATE(kIdentityErrorMessage));
306 EXPECT_EQ(watcher->root_certs(), kRootCert2);
307 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
308 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
309 ::testing::HasSubstr(kRootErrorMessage));
310 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
311 ::testing::HasSubstr(kIdentityErrorMessage));
312 // Send an update for root
313 distributor->SetKeyMaterials("root", kRootCert1, MakeKeyCertPairsType1());
314 EXPECT_EQ(watcher->root_certs(), kRootCert1);
315 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
316 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
317 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
318 ::testing::HasSubstr(kIdentityErrorMessage));
319 // Send an update for identity
320 distributor->SetKeyMaterials("identity", kRootCert2, MakeKeyCertPairsType1());
321 EXPECT_EQ(watcher->root_certs(), kRootCert1);
322 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
323 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
324 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
325 }
326
TEST(XdsCertificateProviderTest,RootCertDistributorSameAsIdentityCertDistributorSameCertNames)327 TEST(XdsCertificateProviderTest,
328 RootCertDistributorSameAsIdentityCertDistributorSameCertNames) {
329 auto root_and_identity_provider = MakeRefCounted<TestCertProvider>();
330 auto distributor = root_and_identity_provider->distributor();
331 XdsCertificateProvider provider(root_and_identity_provider, "",
332 root_and_identity_provider, "", {});
333 auto* watcher = new TestCertificatesWatcher;
334 provider.distributor()->WatchTlsCertificates(
335 std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
336 EXPECT_EQ(watcher->root_certs(), absl::nullopt);
337 EXPECT_EQ(watcher->key_cert_pairs(), absl::nullopt);
338 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
339 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
340 // Update both root certs and identity certs
341 distributor->SetKeyMaterials("", kRootCert1, MakeKeyCertPairsType1());
342 EXPECT_EQ(watcher->root_certs(), kRootCert1);
343 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
344 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
345 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
346 // Second update for just root certs
347 distributor->SetKeyMaterials("", kRootCert2, absl::nullopt);
348 EXPECT_EQ(watcher->root_certs(), kRootCert2);
349 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
350 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
351 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
352 // Second update for identity certs
353 distributor->SetKeyMaterials("", absl::nullopt, MakeKeyCertPairsType2());
354 EXPECT_EQ(watcher->root_certs(), kRootCert2);
355 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
356 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
357 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
358 // Set error for root
359 distributor->SetErrorForCert("", GRPC_ERROR_CREATE(kRootErrorMessage),
360 absl::nullopt);
361 EXPECT_EQ(watcher->root_certs(), kRootCert2);
362 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
363 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
364 ::testing::HasSubstr(kRootErrorMessage));
365 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
366 // Set error for identity
367 distributor->SetErrorForCert("", absl::nullopt,
368 GRPC_ERROR_CREATE(kIdentityErrorMessage));
369 EXPECT_EQ(watcher->root_certs(), kRootCert2);
370 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
371 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
372 ::testing::HasSubstr(kRootErrorMessage));
373 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
374 ::testing::HasSubstr(kIdentityErrorMessage));
375 // Send an update for root
376 distributor->SetKeyMaterials("", kRootCert1, absl::nullopt);
377 EXPECT_EQ(watcher->root_certs(), kRootCert1);
378 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType2());
379 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
380 EXPECT_THAT(StatusToString(watcher->identity_cert_error()),
381 ::testing::HasSubstr(kIdentityErrorMessage));
382 // Send an update for identity
383 distributor->SetKeyMaterials("", absl::nullopt, MakeKeyCertPairsType1());
384 EXPECT_EQ(watcher->root_certs(), kRootCert1);
385 EXPECT_EQ(watcher->key_cert_pairs(), MakeKeyCertPairsType1());
386 EXPECT_EQ(watcher->root_cert_error(), absl::OkStatus());
387 EXPECT_EQ(watcher->identity_cert_error(), absl::OkStatus());
388 }
389
TEST(XdsCertificateProviderTest,UnknownCertName)390 TEST(XdsCertificateProviderTest, UnknownCertName) {
391 XdsCertificateProvider provider(nullptr, "", nullptr, "", {});
392 auto* watcher = new TestCertificatesWatcher;
393 provider.distributor()->WatchTlsCertificates(
394 std::unique_ptr<TestCertificatesWatcher>(watcher), "test", "test");
395 EXPECT_THAT(StatusToString(watcher->root_cert_error()),
396 ::testing::HasSubstr(
397 "No certificate provider available for root certificates"));
398 EXPECT_THAT(
399 StatusToString(watcher->identity_cert_error()),
400 ::testing::HasSubstr(
401 "No certificate provider available for identity certificates"));
402 }
403
404 } // namespace
405 } // namespace testing
406 } // namespace grpc_core
407
main(int argc,char ** argv)408 int main(int argc, char** argv) {
409 ::testing::InitGoogleTest(&argc, argv);
410 grpc::testing::TestEnvironment env(&argc, argv);
411 grpc_init();
412 auto result = RUN_ALL_TESTS();
413 grpc_shutdown();
414 return result;
415 }
416