diff --git a/src/jaegertracing/ConfigTest.cpp b/src/jaegertracing/ConfigTest.cpp index 7236bdff..225d8e31 100644 --- a/src/jaegertracing/ConfigTest.cpp +++ b/src/jaegertracing/ConfigTest.cpp @@ -19,6 +19,7 @@ #include "jaegertracing/propagation/HeadersConfig.h" #include "jaegertracing/samplers/Config.h" #include "jaegertracing/utils/YAML.h" +#include "jaegertracing/testutils/EnvVariable.h" #include #include @@ -95,15 +96,6 @@ TEST(Config, testZeroSamplingParam) #endif // JAEGERTRACING_WITH_YAML_CPP - -void setEnv(const char *variable, const char *value) { -#ifdef WIN32 - _putenv_s(variable, value); -#else - setenv(variable, value, true); -#endif -} - TEST(Config, testFromEnv) { std::vector tags; @@ -139,20 +131,20 @@ TEST(Config, testFromEnv) ASSERT_EQ(.7, config.sampler().param()); ASSERT_EQ(std::string("probabilistic"), config.sampler().type()); - setEnv("JAEGER_AGENT_HOST", "host33"); - setEnv("JAEGER_AGENT_PORT", "45"); - setEnv("JAEGER_ENDPOINT", "http://host34:56567"); + testutils::EnvVariable::setEnv("JAEGER_AGENT_HOST", "host33"); + testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "45"); + testutils::EnvVariable::setEnv("JAEGER_ENDPOINT", "http://host34:56567"); - setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", "33"); - setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", "45"); - setEnv("JAEGER_REPORTER_LOG_SPANS", "true"); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", "33"); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", "45"); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_LOG_SPANS", "true"); - setEnv("JAEGER_SAMPLER_TYPE", "remote"); - setEnv("JAEGER_SAMPLER_PARAM", "0.33"); - setEnv("JAEGER_SAMPLING_ENDPOINT", "http://myagent:1234"); + testutils::EnvVariable::setEnv("JAEGER_SAMPLER_TYPE", "remote"); + testutils::EnvVariable::setEnv("JAEGER_SAMPLER_PARAM", "0.33"); + testutils::EnvVariable::setEnv("JAEGER_SAMPLING_ENDPOINT", "http://myagent:1234"); - setEnv("JAEGER_SERVICE_NAME", "AService"); - setEnv("JAEGER_TAGS", "hostname=foobar,my.app.version=4.5.6"); + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService"); + testutils::EnvVariable::setEnv("JAEGER_TAGS", "hostname=foobar,my.app.version=4.5.6"); config.fromEnv(); @@ -179,13 +171,25 @@ TEST(Config, testFromEnv) ASSERT_EQ(false, config.disabled()); - setEnv("JAEGER_DISABLED", "TRue"); // case-insensitive - setEnv("JAEGER_AGENT_PORT", "445"); + testutils::EnvVariable::setEnv("JAEGER_DISABLED", "TRue"); // case-insensitive + testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "445"); config.fromEnv(); ASSERT_EQ(true, config.disabled()); ASSERT_EQ(std::string("host33:445"), config.reporter().localAgentHostPort()); + + testutils::EnvVariable::setEnv("JAEGER_AGENT_HOST", ""); + testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", ""); + testutils::EnvVariable::setEnv("JAEGER_ENDPOINT", ""); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", ""); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", ""); + testutils::EnvVariable::setEnv("JAEGER_REPORTER_LOG_SPANS", ""); + testutils::EnvVariable::setEnv("JAEGER_SAMPLER_PARAM", ""); + testutils::EnvVariable::setEnv("JAEGER_SAMPLER_TYPE", ""); + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", ""); + testutils::EnvVariable::setEnv("JAEGER_TAGS", ""); + testutils::EnvVariable::setEnv("JAEGER_DISABLED", ""); } } // namespace jaegertracing diff --git a/src/jaegertracing/DynamicLoad.cpp b/src/jaegertracing/DynamicLoad.cpp index 7c6f4637..6a114774 100644 --- a/src/jaegertracing/DynamicLoad.cpp +++ b/src/jaegertracing/DynamicLoad.cpp @@ -41,7 +41,8 @@ static int makeTracerFactory(const char* opentracingVersion, return opentracing::incompatible_library_versions_error.value(); } - *tracerFactory = new (std::nothrow) jaegertracing::TracerFactory{}; + const auto jaegerTracerFactory = new (std::nothrow) jaegertracing::TracerFactory(true); + *tracerFactory = jaegerTracerFactory; if (*tracerFactory == nullptr) { *errorCategory = static_cast(&std::generic_category()); return static_cast(std::errc::not_enough_memory); @@ -50,4 +51,4 @@ static int makeTracerFactory(const char* opentracingVersion, return 0; } -OPENTRACING_DECLARE_IMPL_FACTORY(makeTracerFactory) \ No newline at end of file +OPENTRACING_DECLARE_IMPL_FACTORY(makeTracerFactory) diff --git a/src/jaegertracing/TracerFactory.cpp b/src/jaegertracing/TracerFactory.cpp index d743d7eb..fcc70983 100644 --- a/src/jaegertracing/TracerFactory.cpp +++ b/src/jaegertracing/TracerFactory.cpp @@ -38,19 +38,18 @@ TracerFactory::MakeTracer(const char* configuration, opentracing::configuration_parse_error); } - const auto serviceNameNode = yaml["service_name"]; - if (!serviceNameNode) { - errorMessage = "`service_name` not provided"; - return opentracing::make_unexpected( - opentracing::invalid_configuration_error); + auto tracerConfig = jaegertracing::Config::parse(yaml); + + if (_readFromEnv) { + tracerConfig.fromEnv(); } - if (!serviceNameNode.IsScalar()) { - errorMessage = "`service_name` must be a string"; + + if (tracerConfig.serviceName().empty()) { + errorMessage = "`service_name` not provided"; return opentracing::make_unexpected( opentracing::invalid_configuration_error); } - const auto tracerConfig = jaegertracing::Config::parse(yaml); return jaegertracing::Tracer::make(tracerConfig); #endif // JAEGERTRACING_WITH_YAML_CPP } catch (const std::bad_alloc&) { diff --git a/src/jaegertracing/TracerFactory.h b/src/jaegertracing/TracerFactory.h index 7369ac29..90428a7d 100644 --- a/src/jaegertracing/TracerFactory.h +++ b/src/jaegertracing/TracerFactory.h @@ -26,6 +26,18 @@ class TracerFactory : public opentracing::TracerFactory { opentracing::expected> MakeTracer(const char* configuration, std::string& errorMessage) const noexcept override; + + TracerFactory() + : TracerFactory(false) + { + } + + TracerFactory(bool readFromEnv) + : _readFromEnv(readFromEnv) + { + } + private: + bool _readFromEnv; }; } // namespace jaegertracing diff --git a/src/jaegertracing/TracerFactoryTest.cpp b/src/jaegertracing/TracerFactoryTest.cpp index cc6a3e31..3ce186b1 100644 --- a/src/jaegertracing/TracerFactoryTest.cpp +++ b/src/jaegertracing/TracerFactoryTest.cpp @@ -14,8 +14,10 @@ * limitations under the License. */ +#include "jaegertracing/Tracer.h" #include "jaegertracing/TracerFactory.h" #include "jaegertracing/Constants.h" +#include "jaegertracing/testutils/EnvVariable.h" #include namespace jaegertracing { @@ -27,7 +29,7 @@ TEST(TracerFactory, testInvalidConfig) R"({ "service_name": {} })" }; - TracerFactory tracerFactory; + TracerFactory tracerFactory(true); for (auto&& invalidConfig : invalidConfigTestCases) { std::string errorMessage; auto tracerMaybe = @@ -65,17 +67,68 @@ TEST(TracerFactory, testValidConfig) "refreshInterval": 60 } })"; - TracerFactory tracerFactory; + TracerFactory tracerFactory(true); std::string errorMessage; auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage); ASSERT_EQ(errorMessage, ""); ASSERT_TRUE(tracerMaybe); } + +TEST(TracerFactory, testWithoutReadFromEnv) +{ + const char* config = ""; + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService"); + TracerFactory tracerFactory(false); + std::string errorMessage; + auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage); + ASSERT_FALSE(tracerMaybe); + ASSERT_NE(errorMessage, ""); + + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", ""); +} + +TEST(TracerFactory, testWithReadFromEnv) +{ + const char* config = ""; + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "AService"); + TracerFactory tracerFactory(true); + std::string errorMessage; + auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage); + ASSERT_EQ(errorMessage, ""); + ASSERT_TRUE(tracerMaybe); + + auto tracer = tracerMaybe.value(); + const auto jaegerTracer = std::dynamic_pointer_cast(tracer); + ASSERT_EQ(std::string("AService"), jaegerTracer->serviceName()); + + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", ""); +} + +TEST(TracerFactory, testEnvTakesPrecedence) +{ + + const char* config = R"( + { + "service_name": "Ignored" + })"; + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", "test"); + TracerFactory tracerFactory(true); + std::string errorMessage; + auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage); + ASSERT_EQ(errorMessage, ""); + ASSERT_TRUE(tracerMaybe); + + auto tracer = tracerMaybe.value(); + const auto jaegerTracer = std::dynamic_pointer_cast(tracer); + ASSERT_EQ(std::string("test"), jaegerTracer->serviceName()); + + testutils::EnvVariable::setEnv("JAEGER_SERVICE_NAME", ""); +} #else TEST(TracerFactory, failsWithoutYAML) { const char* config = ""; - TracerFactory tracerFactory; + TracerFactory tracerFactory(true); std::string errorMessage; auto tracerMaybe = tracerFactory.MakeTracer(config, errorMessage); ASSERT_NE(errorMessage, ""); diff --git a/src/jaegertracing/testutils/EnvVariable.cpp b/src/jaegertracing/testutils/EnvVariable.cpp new file mode 100644 index 00000000..726bbb23 --- /dev/null +++ b/src/jaegertracing/testutils/EnvVariable.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2019 The Jaeger 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 "jaegertracing/testutils/EnvVariable.h" diff --git a/src/jaegertracing/testutils/EnvVariable.h b/src/jaegertracing/testutils/EnvVariable.h new file mode 100644 index 00000000..ec612140 --- /dev/null +++ b/src/jaegertracing/testutils/EnvVariable.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 The Jaeger 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. + */ + +#ifndef JAEGERTRACING_TESTUTILS_ENVVARIABLE_H +#define JAEGERTRACING_TESTUTILS_ENVVARIABLE_H + +#include + +namespace jaegertracing { +namespace testutils { +namespace EnvVariable { + +inline void setEnv(const char *variable, const char *value) { +#ifdef WIN32 + _putenv_s(variable, value); +#else + setenv(variable, value, true); +#endif +} + +} // namespace EnvVariable +} // namespace testutils +} // namespace jaegertracing + +#endif // JAEGERTRACING_TESTUTILS_ENVVARIABLE_H diff --git a/src/jaegertracing/utils/EnvVariable.h b/src/jaegertracing/utils/EnvVariable.h index 8696248a..dc34f823 100644 --- a/src/jaegertracing/utils/EnvVariable.h +++ b/src/jaegertracing/utils/EnvVariable.h @@ -62,4 +62,4 @@ inline std::pair getBoolVariable(const char* envVar) } // namespace utils } // namespace jaegertracing -#endif // JAEGERTRACING_UTILS_HEXPARSING_H +#endif // JAEGERTRACING_UTILS_ENV_VARIABLE_H