xref: /aosp_15_r20/external/grpc-grpc/test/core/xds/file_watcher_certificate_provider_factory_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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/file_watcher_certificate_provider_factory.h"
20 
21 #include <utility>
22 
23 #include "absl/status/status.h"
24 #include "absl/status/statusor.h"
25 #include "absl/strings/str_format.h"
26 #include "gtest/gtest.h"
27 
28 #include <grpc/grpc.h>
29 
30 #include "src/core/lib/json/json_reader.h"
31 #include "test/core/util/test_config.h"
32 
33 namespace grpc_core {
34 namespace testing {
35 namespace {
36 
37 const char* kIdentityCertFile = "/path/to/identity_cert_file";
38 const char* kPrivateKeyFile = "/path/to/private_key_file";
39 const char* kRootCertFile = "/path/to/root_cert_file";
40 const int kRefreshInterval = 400;
41 
42 absl::StatusOr<RefCountedPtr<FileWatcherCertificateProviderFactory::Config>>
ParseConfig(absl::string_view json_string)43 ParseConfig(absl::string_view json_string) {
44   auto json = JsonParse(json_string);
45   if (!json.ok()) return json.status();
46   ValidationErrors errors;
47   auto config =
48       FileWatcherCertificateProviderFactory().CreateCertificateProviderConfig(
49           *json, JsonArgs(), &errors);
50   if (!errors.ok()) {
51     return errors.status(absl::StatusCode::kInvalidArgument,
52                          "validation errors");
53   }
54   return config.TakeAsSubclass<FileWatcherCertificateProviderFactory::Config>();
55 }
56 
TEST(FileWatcherConfigTest,Basic)57 TEST(FileWatcherConfigTest, Basic) {
58   std::string json_str = absl::StrFormat(
59       "{"
60       "  \"certificate_file\": \"%s\","
61       "  \"private_key_file\": \"%s\","
62       "  \"ca_certificate_file\": \"%s\","
63       "  \"refresh_interval\": \"%ds\""
64       "}",
65       kIdentityCertFile, kPrivateKeyFile, kRootCertFile, kRefreshInterval);
66   auto config = ParseConfig(json_str);
67   ASSERT_TRUE(config.ok()) << config.status();
68   EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile);
69   EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile);
70   EXPECT_EQ((*config)->root_cert_file(), kRootCertFile);
71   EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(kRefreshInterval));
72 }
73 
TEST(FileWatcherConfigTest,DefaultRefreshInterval)74 TEST(FileWatcherConfigTest, DefaultRefreshInterval) {
75   std::string json_str = absl::StrFormat(
76       "{"
77       "  \"certificate_file\": \"%s\","
78       "  \"private_key_file\": \"%s\","
79       "  \"ca_certificate_file\": \"%s\""
80       "}",
81       kIdentityCertFile, kPrivateKeyFile, kRootCertFile);
82   auto config = ParseConfig(json_str);
83   ASSERT_TRUE(config.ok()) << config.status();
84   EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile);
85   EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile);
86   EXPECT_EQ((*config)->root_cert_file(), kRootCertFile);
87   EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600));
88 }
89 
TEST(FileWatcherConfigTest,OnlyRootCertificatesFileProvided)90 TEST(FileWatcherConfigTest, OnlyRootCertificatesFileProvided) {
91   std::string json_str = absl::StrFormat(
92       "{"
93       "  \"ca_certificate_file\": \"%s\""
94       "}",
95       kRootCertFile);
96   auto config = ParseConfig(json_str);
97   ASSERT_TRUE(config.ok()) << config.status();
98   EXPECT_EQ((*config)->identity_cert_file(), "");
99   EXPECT_EQ((*config)->private_key_file(), "");
100   EXPECT_EQ((*config)->root_cert_file(), kRootCertFile);
101   EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600));
102 }
103 
TEST(FileWatcherConfigTest,OnlyIdenityCertificatesAndPrivateKeyProvided)104 TEST(FileWatcherConfigTest, OnlyIdenityCertificatesAndPrivateKeyProvided) {
105   std::string json_str = absl::StrFormat(
106       "{"
107       "  \"certificate_file\": \"%s\","
108       "  \"private_key_file\": \"%s\""
109       "}",
110       kIdentityCertFile, kPrivateKeyFile);
111   auto config = ParseConfig(json_str);
112   ASSERT_TRUE(config.ok()) << config.status();
113   EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile);
114   EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile);
115   EXPECT_EQ((*config)->root_cert_file(), "");
116   EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600));
117 }
118 
TEST(FileWatcherConfigTest,WrongTypes)119 TEST(FileWatcherConfigTest, WrongTypes) {
120   const char* json_str =
121       "{"
122       "  \"certificate_file\": 123,"
123       "  \"private_key_file\": 123,"
124       "  \"ca_certificate_file\": 123,"
125       "  \"refresh_interval\": 123"
126       "}";
127   auto config = ParseConfig(json_str);
128   EXPECT_EQ(config.status().message(),
129             "validation errors: ["
130             "field:ca_certificate_file error:is not a string; "
131             "field:certificate_file error:is not a string; "
132             "field:private_key_file error:is not a string; "
133             "field:refresh_interval error:is not a string]")
134       << config.status();
135 }
136 
TEST(FileWatcherConfigTest,IdentityCertProvidedButPrivateKeyMissing)137 TEST(FileWatcherConfigTest, IdentityCertProvidedButPrivateKeyMissing) {
138   std::string json_str = absl::StrFormat(
139       "{"
140       "  \"certificate_file\": \"%s\""
141       "}",
142       kIdentityCertFile);
143   auto config = ParseConfig(json_str);
144   EXPECT_EQ(config.status().message(),
145             "validation errors: ["
146             "field: error:fields \"certificate_file\" and "
147             "\"private_key_file\" must be both set or both unset]")
148       << config.status();
149 }
150 
TEST(FileWatcherConfigTest,PrivateKeyProvidedButIdentityCertMissing)151 TEST(FileWatcherConfigTest, PrivateKeyProvidedButIdentityCertMissing) {
152   std::string json_str = absl::StrFormat(
153       "{"
154       "  \"ca_certificate_file\": \"%s\","
155       "  \"private_key_file\": \"%s\""
156       "}",
157       kRootCertFile, kPrivateKeyFile);
158   auto config = ParseConfig(json_str);
159   EXPECT_EQ(config.status().message(),
160             "validation errors: ["
161             "field: error:fields \"certificate_file\" and "
162             "\"private_key_file\" must be both set or both unset]")
163       << config.status();
164 }
165 
TEST(FileWatcherConfigTest,EmptyJsonObject)166 TEST(FileWatcherConfigTest, EmptyJsonObject) {
167   std::string json_str = "{}";
168   auto config = ParseConfig(json_str);
169   EXPECT_EQ(config.status().message(),
170             "validation errors: ["
171             "field: error:at least one of \"certificate_file\" and "
172             "\"ca_certificate_file\" must be specified]")
173       << config.status();
174 }
175 
176 }  // namespace
177 }  // namespace testing
178 }  // namespace grpc_core
179 
main(int argc,char ** argv)180 int main(int argc, char** argv) {
181   ::testing::InitGoogleTest(&argc, argv);
182   grpc::testing::TestEnvironment env(&argc, argv);
183   grpc_init();
184   auto result = RUN_ALL_TESTS();
185   grpc_shutdown();
186   return result;
187 }
188