123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- #include <gtest/gtest.h>
- #include <stdint.h>
- #ifdef _WIN32
- # include <windows.h>
- #else
- # include <dlfcn.h>
- #endif
- #include "component_a.h"
- #include "component_b.h"
- #include "component_c.h"
- #include "component_d.h"
- #include "component_e.h"
- #include "component_f.h"
- #include "opentelemetry/common/key_value_iterable.h"
- #include "opentelemetry/nostd/shared_ptr.h"
- #include "opentelemetry/nostd/string_view.h"
- #include "opentelemetry/trace/default_span.h"
- #include "opentelemetry/trace/noop.h"
- #include "opentelemetry/trace/provider.h"
- #include "opentelemetry/trace/span.h"
- #include "opentelemetry/trace/span_context.h"
- #include "opentelemetry/trace/span_context_kv_iterable.h"
- #include "opentelemetry/trace/span_startoptions.h"
- #include "opentelemetry/trace/tracer.h"
- #include "opentelemetry/trace/tracer_provider.h"
- using namespace opentelemetry;
- void do_something()
- {
- do_something_in_a();
- do_something_in_b();
- do_something_in_c();
- do_something_in_d();
- do_something_in_e();
- do_something_in_f();
- /*
- See https://github.com/bazelbuild/bazel/issues/4218
- There is no way to set LD_LIBRARY_PATH in bazel,
- for dlopen() to find the library.
- Verified manually that dlopen("/full/path/to/libcomponent_g.so") works,
- and that the test passes in this case.
- */
- #ifndef BAZEL_BUILD
- /* Call do_something_in_g() */
- # ifdef _WIN32
- HMODULE component_g = LoadLibraryA("component_g.dll");
- # elif defined(__APPLE__)
- void *component_g = dlopen("libcomponent_g.dylib", RTLD_NOW);
- # else
- void *component_g = dlopen("libcomponent_g.so", RTLD_NOW);
- # endif
- EXPECT_NE(component_g, nullptr);
- # ifdef _WIN32
- auto *func_g = reinterpret_cast<void (*)()>(GetProcAddress(component_g, "do_something_in_g"));
- # else
- auto *func_g = reinterpret_cast<void (*)()>(dlsym(component_g, "do_something_in_g"));
- # endif
- EXPECT_NE(func_g, nullptr);
- (*func_g)();
- # ifdef _WIN32
- FreeLibrary(component_g);
- # else
- dlclose(component_g);
- # endif
- /* Call do_something_in_h() */
- # ifdef _WIN32
- HMODULE component_h = LoadLibraryA("component_h.dll");
- # elif defined(__APPLE__)
- void *component_h = dlopen("libcomponent_h.dylib", RTLD_NOW);
- # else
- void *component_h = dlopen("libcomponent_h.so", RTLD_NOW);
- # endif
- EXPECT_NE(component_h, nullptr);
- # ifdef _WIN32
- auto *func_h = reinterpret_cast<void (*)()>(GetProcAddress(component_h, "do_something_in_h"));
- # else
- auto *func_h = reinterpret_cast<void (*)()>(dlsym(component_h, "do_something_in_h"));
- # endif
- EXPECT_NE(func_h, nullptr);
- (*func_h)();
- # ifdef _WIN32
- FreeLibrary(component_h);
- # else
- dlclose(component_h);
- # endif
- #endif /* BAZEL_BUILD */
- }
- int span_a_lib_count = 0;
- int span_a_f1_count = 0;
- int span_a_f2_count = 0;
- int span_b_lib_count = 0;
- int span_b_f1_count = 0;
- int span_b_f2_count = 0;
- int span_c_lib_count = 0;
- int span_c_f1_count = 0;
- int span_c_f2_count = 0;
- int span_d_lib_count = 0;
- int span_d_f1_count = 0;
- int span_d_f2_count = 0;
- int span_e_lib_count = 0;
- int span_e_f1_count = 0;
- int span_e_f2_count = 0;
- int span_f_lib_count = 0;
- int span_f_f1_count = 0;
- int span_f_f2_count = 0;
- int span_g_lib_count = 0;
- int span_g_f1_count = 0;
- int span_g_f2_count = 0;
- int span_h_lib_count = 0;
- int span_h_f1_count = 0;
- int span_h_f2_count = 0;
- int unknown_span_count = 0;
- void reset_counts()
- {
- span_a_lib_count = 0;
- span_a_f1_count = 0;
- span_a_f2_count = 0;
- span_b_lib_count = 0;
- span_b_f1_count = 0;
- span_b_f2_count = 0;
- span_c_lib_count = 0;
- span_c_f1_count = 0;
- span_c_f2_count = 0;
- span_d_lib_count = 0;
- span_d_f1_count = 0;
- span_d_f2_count = 0;
- span_e_lib_count = 0;
- span_e_f1_count = 0;
- span_e_f2_count = 0;
- span_f_lib_count = 0;
- span_f_f1_count = 0;
- span_f_f2_count = 0;
- span_g_lib_count = 0;
- span_g_f1_count = 0;
- span_g_f2_count = 0;
- span_h_lib_count = 0;
- span_h_f1_count = 0;
- span_h_f2_count = 0;
- unknown_span_count = 0;
- }
- class MyTracer : public trace::Tracer
- {
- public:
- MyTracer()
- {
- #if OPENTELEMETRY_ABI_VERSION_NO >= 2
- UpdateEnabled(true);
- #endif
- }
- nostd::shared_ptr<trace::Span> StartSpan(
- nostd::string_view name,
- const common::KeyValueIterable & /* attributes */,
- const trace::SpanContextKeyValueIterable & /* links */,
- const trace::StartSpanOptions & /* options */) noexcept override
- {
- nostd::shared_ptr<trace::Span> result(new trace::DefaultSpan(trace::SpanContext::GetInvalid()));
- /*
- Unit test code, no need to be fancy.
- */
- if (name == "A::library")
- {
- span_a_lib_count++;
- }
- else if (name == "A::f1")
- {
- span_a_f1_count++;
- }
- else if (name == "A::f2")
- {
- span_a_f2_count++;
- }
- else if (name == "B::library")
- {
- span_b_lib_count++;
- }
- else if (name == "B::f1")
- {
- span_b_f1_count++;
- }
- else if (name == "B::f2")
- {
- span_b_f2_count++;
- }
- else if (name == "C::library")
- {
- span_c_lib_count++;
- }
- else if (name == "C::f1")
- {
- span_c_f1_count++;
- }
- else if (name == "C::f2")
- {
- span_c_f2_count++;
- }
- else if (name == "D::library")
- {
- span_d_lib_count++;
- }
- else if (name == "D::f1")
- {
- span_d_f1_count++;
- }
- else if (name == "D::f2")
- {
- span_d_f2_count++;
- }
- else if (name == "E::library")
- {
- span_e_lib_count++;
- }
- else if (name == "E::f1")
- {
- span_e_f1_count++;
- }
- else if (name == "E::f2")
- {
- span_e_f2_count++;
- }
- else if (name == "F::library")
- {
- span_f_lib_count++;
- }
- else if (name == "F::f1")
- {
- span_f_f1_count++;
- }
- else if (name == "F::f2")
- {
- span_f_f2_count++;
- }
- else if (name == "G::library")
- {
- span_g_lib_count++;
- }
- else if (name == "G::f1")
- {
- span_g_f1_count++;
- }
- else if (name == "G::f2")
- {
- span_g_f2_count++;
- }
- else if (name == "H::library")
- {
- span_h_lib_count++;
- }
- else if (name == "H::f1")
- {
- span_h_f1_count++;
- }
- else if (name == "H::f2")
- {
- span_h_f2_count++;
- }
- else
- {
- unknown_span_count++;
- }
- return result;
- }
- #if OPENTELEMETRY_ABI_VERSION_NO == 1
- void ForceFlushWithMicroseconds(uint64_t /* timeout */) noexcept override {}
- void CloseWithMicroseconds(uint64_t /* timeout */) noexcept override {}
- #endif /* OPENTELEMETRY_ABI_VERSION_NO */
- };
- class MyTracerProvider : public trace::TracerProvider
- {
- public:
- static std::shared_ptr<trace::TracerProvider> Create()
- {
- std::shared_ptr<trace::TracerProvider> result(new MyTracerProvider());
- return result;
- }
- #if OPENTELEMETRY_ABI_VERSION_NO >= 2
- nostd::shared_ptr<trace::Tracer> GetTracer(
- nostd::string_view /* name */,
- nostd::string_view /* version */,
- nostd::string_view /* schema_url */,
- const common::KeyValueIterable * /* attributes */) noexcept override
- {
- nostd::shared_ptr<trace::Tracer> result(new MyTracer());
- return result;
- }
- #else
- nostd::shared_ptr<trace::Tracer> GetTracer(nostd::string_view /* name */,
- nostd::string_view /* version */,
- nostd::string_view /* schema_url */) noexcept override
- {
- nostd::shared_ptr<trace::Tracer> result(new MyTracer());
- return result;
- }
- #endif
- };
- void setup_otel()
- {
- std::shared_ptr<opentelemetry::trace::TracerProvider> provider = MyTracerProvider::Create();
- // The whole point of this test is to make sure
- // that the API singleton behind SetTracerProvider()
- // works for all components, static and dynamic.
- // Set the global tracer provider
- trace_api::Provider::SetTracerProvider(provider);
- }
- void cleanup_otel()
- {
- std::shared_ptr<opentelemetry::trace::TracerProvider> provider(
- new opentelemetry::trace::NoopTracerProvider());
- // Set the global tracer provider
- trace_api::Provider::SetTracerProvider(provider);
- }
- // TODO: Remove once windows api singletons are supported.
- // See https://github.com/open-telemetry/opentelemetry-cpp/issues/2534
- #ifdef _WIN32
- # define RUN_FAILING_WINDOWS_TEST 0
- #else
- # define RUN_FAILING_WINDOWS_TEST 1
- #endif
- TEST(SingletonTest, Uniqueness)
- {
- do_something();
- EXPECT_EQ(span_a_lib_count, 0);
- EXPECT_EQ(span_a_f1_count, 0);
- EXPECT_EQ(span_a_f2_count, 0);
- EXPECT_EQ(span_b_lib_count, 0);
- EXPECT_EQ(span_b_f1_count, 0);
- EXPECT_EQ(span_b_f2_count, 0);
- EXPECT_EQ(span_c_lib_count, 0);
- EXPECT_EQ(span_c_f1_count, 0);
- EXPECT_EQ(span_c_f2_count, 0);
- EXPECT_EQ(span_d_lib_count, 0);
- EXPECT_EQ(span_d_f1_count, 0);
- EXPECT_EQ(span_d_f2_count, 0);
- EXPECT_EQ(span_e_lib_count, 0);
- EXPECT_EQ(span_e_f1_count, 0);
- EXPECT_EQ(span_e_f2_count, 0);
- EXPECT_EQ(span_f_lib_count, 0);
- EXPECT_EQ(span_f_f1_count, 0);
- EXPECT_EQ(span_f_f2_count, 0);
- EXPECT_EQ(span_g_lib_count, 0);
- EXPECT_EQ(span_g_f1_count, 0);
- EXPECT_EQ(span_g_f2_count, 0);
- EXPECT_EQ(span_h_lib_count, 0);
- EXPECT_EQ(span_h_f1_count, 0);
- EXPECT_EQ(span_h_f2_count, 0);
- EXPECT_EQ(unknown_span_count, 0);
- reset_counts();
- setup_otel();
- do_something();
- EXPECT_EQ(span_a_lib_count, 1);
- EXPECT_EQ(span_a_f1_count, 2);
- EXPECT_EQ(span_a_f2_count, 1);
- EXPECT_EQ(span_b_lib_count, 1);
- EXPECT_EQ(span_b_f1_count, 2);
- EXPECT_EQ(span_b_f2_count, 1);
- #if RUN_FAILING_WINDOWS_TEST
- EXPECT_EQ(span_c_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_c_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_c_f2_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_d_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_d_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_d_f2_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_e_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_e_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_e_f2_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_f_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_f_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_f_f2_count, 1); // Fails with shared libraries on Windows
- #endif
- #ifndef BAZEL_BUILD
- # if RUN_FAILING_WINDOWS_TEST
- EXPECT_EQ(span_g_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_g_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_g_f2_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_h_lib_count, 1); // Fails with shared libraries on Windows
- EXPECT_EQ(span_h_f1_count, 2); // Fails with shared libraries on Windows
- EXPECT_EQ(span_h_f2_count, 1); // Fails with shared libraries on Windows
- # endif
- #endif
- EXPECT_EQ(unknown_span_count, 0);
- reset_counts();
- cleanup_otel();
- do_something();
- EXPECT_EQ(span_a_lib_count, 0);
- EXPECT_EQ(span_a_f1_count, 0);
- EXPECT_EQ(span_a_f2_count, 0);
- EXPECT_EQ(span_b_lib_count, 0);
- EXPECT_EQ(span_b_f1_count, 0);
- EXPECT_EQ(span_b_f2_count, 0);
- EXPECT_EQ(span_c_lib_count, 0);
- EXPECT_EQ(span_c_f1_count, 0);
- EXPECT_EQ(span_c_f2_count, 0);
- EXPECT_EQ(span_d_lib_count, 0);
- EXPECT_EQ(span_d_f1_count, 0);
- EXPECT_EQ(span_d_f2_count, 0);
- EXPECT_EQ(span_e_lib_count, 0);
- EXPECT_EQ(span_e_f1_count, 0);
- EXPECT_EQ(span_e_f2_count, 0);
- EXPECT_EQ(span_f_lib_count, 0);
- EXPECT_EQ(span_f_f1_count, 0);
- EXPECT_EQ(span_f_f2_count, 0);
- EXPECT_EQ(span_g_lib_count, 0);
- EXPECT_EQ(span_g_f1_count, 0);
- EXPECT_EQ(span_g_f2_count, 0);
- EXPECT_EQ(span_h_lib_count, 0);
- EXPECT_EQ(span_h_f1_count, 0);
- EXPECT_EQ(span_h_f2_count, 0);
- EXPECT_EQ(unknown_span_count, 0);
- }
|