| 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#endifTEST(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);}
 |