The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) https://grpc.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

212 lines
6.5 KiB

//
// Copyright 2022 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/cpp/ext/gcp/observability_config.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <grpc/support/alloc.h>
#include "src/core/lib/gpr/tmpfile.h"
#include "src/core/lib/gprpp/env.h"
#include "test/core/util/test_config.h"
namespace grpc {
namespace internal {
namespace {
TEST(GcpObservabilityConfigJsonParsingTest, Basic) {
const char* json_str = R"json({
"cloud_logging": {
"disabled": true
},
"cloud_monitoring": {
"disabled": true
},
"cloud_trace": {
"disabled": true,
"sampling_rate": 0.05
},
"project_id": "project"
})json";
auto json = grpc_core::Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_core::ErrorList errors;
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>(
*json, grpc_core::JsonArgs(), &errors);
ASSERT_TRUE(errors.ok()) << errors.status();
EXPECT_TRUE(config.cloud_logging.disabled);
EXPECT_TRUE(config.cloud_monitoring.disabled);
EXPECT_TRUE(config.cloud_trace.disabled);
EXPECT_FLOAT_EQ(config.cloud_trace.sampling_rate, 0.05);
EXPECT_EQ(config.project_id, "project");
}
TEST(GcpObservabilityConfigJsonParsingTest, Defaults) {
const char* json_str = R"json({
})json";
auto json = grpc_core::Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_core::ErrorList errors;
auto config = grpc_core::LoadFromJson<GcpObservabilityConfig>(
*json, grpc_core::JsonArgs(), &errors);
ASSERT_TRUE(errors.ok()) << errors.status();
EXPECT_FALSE(config.cloud_logging.disabled);
EXPECT_FALSE(config.cloud_monitoring.disabled);
EXPECT_FALSE(config.cloud_trace.disabled);
EXPECT_FLOAT_EQ(config.cloud_trace.sampling_rate, 0);
EXPECT_TRUE(config.project_id.empty());
}
TEST(GcpEnvParsingTest, NoEnvironmentVariableSet) {
auto config = GcpObservabilityConfig::ReadFromEnv();
EXPECT_EQ(config.status(),
absl::FailedPreconditionError(
"Environment variables GRPC_OBSERVABILITY_CONFIG_FILE or "
"GRPC_OBSERVABILITY_CONFIG "
"not defined"));
}
TEST(GcpEnvParsingTest, ConfigFileDoesNotExist) {
grpc_core::SetEnv("GRPC_OBSERVABILITY_CONFIG_FILE",
"/tmp/gcp_observability_config_does_not_exist");
auto config = GcpObservabilityConfig::ReadFromEnv();
EXPECT_EQ(config.status(),
absl::FailedPreconditionError("Failed to load file"));
grpc_core::UnsetEnv("GRPC_OBSERVABILITY_CONFIG_FILE");
}
class EnvParsingTestType {
public:
enum class ConfigSource {
kFile,
kEnvVar,
};
EnvParsingTestType& set_config_source(ConfigSource config_source) {
config_source_ = config_source;
return *this;
}
ConfigSource config_source() const { return config_source_; }
std::string ToString() const {
std::string ret_val;
if (config_source_ == ConfigSource::kFile) {
absl::StrAppend(&ret_val, "ConfigFromFile");
} else if (config_source_ == ConfigSource::kEnvVar) {
absl::StrAppend(&ret_val, "ConfigFromEnvVar");
}
return ret_val;
}
static std::string Name(
const ::testing::TestParamInfo<EnvParsingTestType>& info) {
return info.param.ToString();
}
private:
ConfigSource config_source_;
};
class EnvParsingTest : public ::testing::TestWithParam<EnvParsingTestType> {
protected:
~EnvParsingTest() override {
if (GetParam().config_source() == EnvParsingTestType::ConfigSource::kFile) {
if (tmp_file_name != nullptr) {
grpc_core::UnsetEnv("GRPC_OBSERVABILITY_CONFIG_FILE");
remove(tmp_file_name);
gpr_free(tmp_file_name);
}
} else if (GetParam().config_source() ==
EnvParsingTestType::ConfigSource::kEnvVar) {
grpc_core::UnsetEnv("GRPC_OBSERVABILITY_CONFIG");
}
}
void SetConfig(const char* json) {
if (GetParam().config_source() == EnvParsingTestType::ConfigSource::kFile) {
ASSERT_EQ(tmp_file_name, nullptr);
FILE* tmp_config_file =
gpr_tmpfile("gcp_observability_config", &tmp_file_name);
fputs(json, tmp_config_file);
fclose(tmp_config_file);
grpc_core::SetEnv("GRPC_OBSERVABILITY_CONFIG_FILE", tmp_file_name);
} else if (GetParam().config_source() ==
EnvParsingTestType::ConfigSource::kEnvVar) {
grpc_core::SetEnv("GRPC_OBSERVABILITY_CONFIG", json);
}
}
private:
char* tmp_file_name = nullptr;
};
TEST_P(EnvParsingTest, Basic) {
SetConfig(R"json({
"project_id": "project"
})json");
auto config = GcpObservabilityConfig::ReadFromEnv();
ASSERT_TRUE(config.ok());
EXPECT_EQ(config->project_id, "project");
}
// Test that JSON parsing errors are propagated as expected.
TEST_P(EnvParsingTest, BadJson) {
SetConfig("{");
auto config = GcpObservabilityConfig::ReadFromEnv();
EXPECT_EQ(config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(config.status().message(),
::testing::HasSubstr("JSON parsing failed"))
<< config.status().message();
}
// Make sure that GCP config errors are propagated as expected.
TEST_P(EnvParsingTest, BadGcpConfig) {
SetConfig(R"json({
"project_id": 123
})json");
auto config = GcpObservabilityConfig::ReadFromEnv();
EXPECT_EQ(config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(config.status().message(),
::testing::HasSubstr("field:project_id error:is not a string"))
<< config.status().message();
}
INSTANTIATE_TEST_SUITE_P(
GcpObservabilityConfigTest, EnvParsingTest,
::testing::Values(EnvParsingTestType().set_config_source(
EnvParsingTestType::ConfigSource::kFile),
EnvParsingTestType().set_config_source(
EnvParsingTestType::ConfigSource::kEnvVar)),
&EnvParsingTestType::Name);
} // namespace
} // namespace internal
} // namespace grpc
int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(&argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}