| // |
| // |
| // Copyright 2020 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/ext/xds/file_watcher_certificate_provider_factory.h" |
| |
| #include <initializer_list> |
| #include <utility> |
| |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_format.h" |
| #include "gtest/gtest.h" |
| |
| #include <grpc/grpc.h> |
| |
| #include "src/core/lib/json/json_reader.h" |
| #include "test/core/util/test_config.h" |
| |
| namespace grpc_core { |
| namespace testing { |
| namespace { |
| |
| const char* kIdentityCertFile = "/path/to/identity_cert_file"; |
| const char* kPrivateKeyFile = "/path/to/private_key_file"; |
| const char* kRootCertFile = "/path/to/root_cert_file"; |
| const int kRefreshInterval = 400; |
| |
| absl::StatusOr<RefCountedPtr<FileWatcherCertificateProviderFactory::Config>> |
| ParseConfig(absl::string_view json_string) { |
| auto json = JsonParse(json_string); |
| if (!json.ok()) return json.status(); |
| ValidationErrors errors; |
| auto config = |
| FileWatcherCertificateProviderFactory().CreateCertificateProviderConfig( |
| *json, JsonArgs(), &errors); |
| if (!errors.ok()) { |
| return errors.status(absl::StatusCode::kInvalidArgument, |
| "validation errors"); |
| } |
| return std::move(config); |
| } |
| |
| TEST(FileWatcherConfigTest, Basic) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"certificate_file\": \"%s\"," |
| " \"private_key_file\": \"%s\"," |
| " \"ca_certificate_file\": \"%s\"," |
| " \"refresh_interval\": \"%ds\"" |
| "}", |
| kIdentityCertFile, kPrivateKeyFile, kRootCertFile, kRefreshInterval); |
| auto config = ParseConfig(json_str); |
| ASSERT_TRUE(config.ok()) << config.status(); |
| EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile); |
| EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile); |
| EXPECT_EQ((*config)->root_cert_file(), kRootCertFile); |
| EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(kRefreshInterval)); |
| } |
| |
| TEST(FileWatcherConfigTest, DefaultRefreshInterval) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"certificate_file\": \"%s\"," |
| " \"private_key_file\": \"%s\"," |
| " \"ca_certificate_file\": \"%s\"" |
| "}", |
| kIdentityCertFile, kPrivateKeyFile, kRootCertFile); |
| auto config = ParseConfig(json_str); |
| ASSERT_TRUE(config.ok()) << config.status(); |
| EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile); |
| EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile); |
| EXPECT_EQ((*config)->root_cert_file(), kRootCertFile); |
| EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600)); |
| } |
| |
| TEST(FileWatcherConfigTest, OnlyRootCertificatesFileProvided) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"ca_certificate_file\": \"%s\"" |
| "}", |
| kRootCertFile); |
| auto config = ParseConfig(json_str); |
| ASSERT_TRUE(config.ok()) << config.status(); |
| EXPECT_EQ((*config)->identity_cert_file(), ""); |
| EXPECT_EQ((*config)->private_key_file(), ""); |
| EXPECT_EQ((*config)->root_cert_file(), kRootCertFile); |
| EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600)); |
| } |
| |
| TEST(FileWatcherConfigTest, OnlyIdenityCertificatesAndPrivateKeyProvided) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"certificate_file\": \"%s\"," |
| " \"private_key_file\": \"%s\"" |
| "}", |
| kIdentityCertFile, kPrivateKeyFile); |
| auto config = ParseConfig(json_str); |
| ASSERT_TRUE(config.ok()) << config.status(); |
| EXPECT_EQ((*config)->identity_cert_file(), kIdentityCertFile); |
| EXPECT_EQ((*config)->private_key_file(), kPrivateKeyFile); |
| EXPECT_EQ((*config)->root_cert_file(), ""); |
| EXPECT_EQ((*config)->refresh_interval(), Duration::Seconds(600)); |
| } |
| |
| TEST(FileWatcherConfigTest, WrongTypes) { |
| const char* json_str = |
| "{" |
| " \"certificate_file\": 123," |
| " \"private_key_file\": 123," |
| " \"ca_certificate_file\": 123," |
| " \"refresh_interval\": 123" |
| "}"; |
| auto config = ParseConfig(json_str); |
| EXPECT_EQ(config.status().message(), |
| "validation errors: [" |
| "field:ca_certificate_file error:is not a string; " |
| "field:certificate_file error:is not a string; " |
| "field:private_key_file error:is not a string; " |
| "field:refresh_interval error:is not a string]") |
| << config.status(); |
| } |
| |
| TEST(FileWatcherConfigTest, IdentityCertProvidedButPrivateKeyMissing) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"certificate_file\": \"%s\"" |
| "}", |
| kIdentityCertFile); |
| auto config = ParseConfig(json_str); |
| EXPECT_EQ(config.status().message(), |
| "validation errors: [" |
| "field: error:fields \"certificate_file\" and " |
| "\"private_key_file\" must be both set or both unset]") |
| << config.status(); |
| } |
| |
| TEST(FileWatcherConfigTest, PrivateKeyProvidedButIdentityCertMissing) { |
| std::string json_str = absl::StrFormat( |
| "{" |
| " \"ca_certificate_file\": \"%s\"," |
| " \"private_key_file\": \"%s\"" |
| "}", |
| kRootCertFile, kPrivateKeyFile); |
| auto config = ParseConfig(json_str); |
| EXPECT_EQ(config.status().message(), |
| "validation errors: [" |
| "field: error:fields \"certificate_file\" and " |
| "\"private_key_file\" must be both set or both unset]") |
| << config.status(); |
| } |
| |
| TEST(FileWatcherConfigTest, EmptyJsonObject) { |
| std::string json_str = "{}"; |
| auto config = ParseConfig(json_str); |
| EXPECT_EQ(config.status().message(), |
| "validation errors: [" |
| "field: error:at least one of \"certificate_file\" and " |
| "\"ca_certificate_file\" must be specified]") |
| << config.status(); |
| } |
| |
| } // namespace |
| } // namespace testing |
| } // namespace grpc_core |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| grpc::testing::TestEnvironment env(&argc, argv); |
| grpc_init(); |
| auto result = RUN_ALL_TESTS(); |
| grpc_shutdown(); |
| return result; |
| } |