Skip to content

Commit

Permalink
[TEST] Expand api singleton test to cover explicit dlopen(). (#2164)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcalff authored Jul 3, 2023
1 parent 42709f4 commit ebbcd48
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 5 deletions.
49 changes: 49 additions & 0 deletions api/test/singleton/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,60 @@ cc_library(
],
)

# no cc_shared_library in bazel 4.2
cc_binary(
name = "component_g",
srcs = [
"component_g.cc",
],
copts = select({
"//bazel:windows": DEFAULT_WIN_COPTS,
"//conditions:default": DEFAULT_NOWIN_COPTS,
}),
linkshared = True,
deps = [
"//api",
],
)

# no cc_shared_library in bazel 4.2
cc_binary(
name = "component_h",
srcs = [
"component_h.cc",
],
copts = select({
"//bazel:windows": HIDDEN_WIN_COPTS,
"//conditions:default": HIDDEN_NOWIN_COPTS,
}),
linkshared = True,
deps = [
"//api",
],
)

#
# To build this test alone:
# - bazel build //api/test/singleton:singleton_test
# - bazel build //api/test/singleton:component_g
# - bazel build //api/test/singleton:component_h
#
# Note that singleton_test does not depend on
# component_g and component_h, on purpose.
#
# To run this test:
# bazel test //api/test/singleton:singleton_test
#

cc_test(
name = "singleton_test",
srcs = [
"singleton_test.cc",
],
defines = ["BAZEL_BUILD"],
linkopts = [
"-ldl",
],
linkstatic = False,
tags = [
"api",
Expand Down
10 changes: 10 additions & 0 deletions api/test/singleton/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,17 @@ if(NOT WIN32)
set_target_properties(component_f PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_libraries(component_f opentelemetry_api)

add_library(component_g SHARED component_g.cc)
set_target_properties(component_g PROPERTIES CXX_VISIBILITY_PRESET default)
target_link_libraries(component_g opentelemetry_api)

add_library(component_h SHARED component_h.cc)
set_target_properties(component_h PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_libraries(component_h opentelemetry_api)

add_executable(singleton_test singleton_test.cc)

# Not linking with component_g and component_h on purpose
target_link_libraries(
singleton_test
component_a
Expand All @@ -41,6 +50,7 @@ if(NOT WIN32)
component_f
${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
opentelemetry_api)

gtest_add_tests(
Expand Down
2 changes: 1 addition & 1 deletion api/test/singleton/component_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

#if defined(_MSC_VER)
// component_c is a DDL
// component_c is a DLL

# ifdef BUILD_COMPONENT_C
__declspec(dllexport)
Expand Down
2 changes: 1 addition & 1 deletion api/test/singleton/component_d.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Make the entry point visible, loaded dynamically

#if defined(_MSC_VER)
// component_d is a DDL
// component_d is a DLL

# ifdef BUILD_COMPONENT_D
__declspec(dllexport)
Expand Down
2 changes: 1 addition & 1 deletion api/test/singleton/component_e.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

#if defined(_MSC_VER)
// component_e is a DDL
// component_e is a DLL

# ifdef BUILD_COMPONENT_E
__declspec(dllexport)
Expand Down
2 changes: 1 addition & 1 deletion api/test/singleton/component_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Make the entry point visible, loaded dynamically

#if defined(_MSC_VER)
// component_f is a DDL
// component_f is a DLL

# ifdef BUILD_COMPONENT_F
__declspec(dllexport)
Expand Down
42 changes: 42 additions & 0 deletions api/test/singleton/component_g.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/version.h"

namespace trace = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;

static nostd::shared_ptr<trace::Tracer> get_tracer()
{
auto provider = trace::Provider::GetTracerProvider();
return provider->GetTracer("G", "70.7");
}

static void f1()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("G::f1"));
}

static void f2()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("G::f2"));

f1();
f1();
}

extern "C"

#if defined(_MSC_VER)
// component_g is a DLL
__declspec(dllexport)
#endif

void do_something_in_g()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("G::library"));

f2();
}
48 changes: 48 additions & 0 deletions api/test/singleton/component_h.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/version.h"

namespace trace = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;

static nostd::shared_ptr<trace::Tracer> get_tracer()
{
auto provider = trace::Provider::GetTracerProvider();
return provider->GetTracer("H", "80.8");
}

static void f1()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("H::f1"));
}

static void f2()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("H::f2"));

f1();
f1();
}

extern "C"

#if defined(_MSC_VER)
// component_h is a DLL

__declspec(dllexport)

#else
// component_h is a shared library (*.so)
// component_h is compiled with visibility("hidden"),
__attribute__((visibility("default")))
#endif

void do_something_in_h()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("H::library"));

f2();
}
104 changes: 103 additions & 1 deletion api/test/singleton/singleton_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@

#include <gtest/gtest.h>

#include <assert.h>
/*
TODO:
Once singleton are supported for windows,
expand this test to use ::LoadLibrary, ::GetProcAddress, ::FreeLibrary
*/
#ifndef _WIN32
# include <dlfcn.h>
#endif

#include <iostream>

#include "component_a.h"
Expand All @@ -30,6 +38,42 @@ void do_something()
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() */

void *component_g = dlopen("libcomponent_g.so", RTLD_NOW);
EXPECT_NE(component_g, nullptr);

auto *func_g = (void (*)())dlsym(component_g, "do_something_in_g");
EXPECT_NE(func_g, nullptr);

(*func_g)();

dlclose(component_g);

/* Call do_something_in_h() */

void *component_h = dlopen("libcomponent_h.so", RTLD_NOW);
EXPECT_NE(component_h, nullptr);

auto *func_h = (void (*)())dlsym(component_h, "do_something_in_h");
EXPECT_NE(func_h, nullptr);

(*func_h)();

dlclose(component_h);
#endif
}

int span_a_lib_count = 0;
Expand All @@ -50,6 +94,12 @@ 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()
Expand All @@ -72,6 +122,12 @@ void reset_counts()
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;
}

Expand Down Expand Up @@ -162,6 +218,30 @@ class MyTracer : public trace::Tracer
{
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++;
Expand Down Expand Up @@ -236,6 +316,12 @@ TEST(SingletonTest, Uniqueness)
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();
Expand All @@ -261,6 +347,16 @@ TEST(SingletonTest, Uniqueness)
EXPECT_EQ(span_f_lib_count, 1);
EXPECT_EQ(span_f_f1_count, 2);
EXPECT_EQ(span_f_f2_count, 1);

#ifndef BAZEL_BUILD
EXPECT_EQ(span_g_lib_count, 1);
EXPECT_EQ(span_g_f1_count, 2);
EXPECT_EQ(span_g_f2_count, 1);
EXPECT_EQ(span_h_lib_count, 1);
EXPECT_EQ(span_h_f1_count, 2);
EXPECT_EQ(span_h_f2_count, 1);
#endif

EXPECT_EQ(unknown_span_count, 0);

reset_counts();
Expand All @@ -286,5 +382,11 @@ TEST(SingletonTest, Uniqueness)
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);
}

0 comments on commit ebbcd48

Please sign in to comment.