trace_id_ratio_sampler_test.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <gtest/gtest.h>
  4. #include <stdint.h>
  5. #include <map>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "opentelemetry/common/key_value_iterable_view.h"
  10. #include "opentelemetry/nostd/span.h"
  11. #include "opentelemetry/sdk/trace/sampler.h"
  12. #include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"
  13. #include "opentelemetry/trace/span_context.h"
  14. #include "opentelemetry/trace/span_context_kv_iterable_view.h"
  15. #include "opentelemetry/trace/span_id.h"
  16. #include "opentelemetry/trace/span_metadata.h"
  17. #include "opentelemetry/trace/trace_flags.h"
  18. #include "opentelemetry/trace/trace_id.h"
  19. #include "src/common/random.h"
  20. using opentelemetry::sdk::common::Random;
  21. using opentelemetry::sdk::trace::Decision;
  22. using opentelemetry::sdk::trace::TraceIdRatioBasedSampler;
  23. namespace trace_api = opentelemetry::trace;
  24. namespace common = opentelemetry::common;
  25. namespace
  26. {
  27. /*
  28. * Helper function for running TraceIdBased sampler tests.
  29. * Given a span context, sampler, and number of iterations this function
  30. * will return the number of RECORD_AND_SAMPLE decision based on randomly
  31. * generated traces.
  32. *
  33. * @param context a required valid span context
  34. * @param sampler a required valid sampler
  35. * @param iterations a required number specifying the number of times to
  36. * generate a random trace_id and check if it should sample using the provided
  37. * provider and context
  38. */
  39. int RunShouldSampleCountDecision(trace_api::SpanContext &context,
  40. TraceIdRatioBasedSampler &sampler,
  41. int iterations)
  42. {
  43. int actual_count = 0;
  44. trace_api::SpanKind span_kind = trace_api::SpanKind::kInternal;
  45. using M = std::map<std::string, int>;
  46. M m1 = {{}};
  47. using L = std::vector<std::pair<trace_api::SpanContext, std::map<std::string, std::string>>>;
  48. L l1 = {{trace_api::SpanContext(false, false), {}}, {trace_api::SpanContext(false, false), {}}};
  49. common::KeyValueIterableView<M> view{m1};
  50. trace_api::SpanContextKeyValueIterableView<L> links{l1};
  51. for (int i = 0; i < iterations; ++i)
  52. {
  53. uint8_t buf[16] = {0};
  54. Random::GenerateRandomBuffer(buf);
  55. trace_api::TraceId trace_id(buf);
  56. auto result = sampler.ShouldSample(context, trace_id, "", span_kind, view, links);
  57. if (result.decision == Decision::RECORD_AND_SAMPLE)
  58. {
  59. ++actual_count;
  60. }
  61. }
  62. return actual_count;
  63. }
  64. } // namespace
  65. TEST(TraceIdRatioBasedSampler, ShouldSampleWithoutContext)
  66. {
  67. trace_api::TraceId invalid_trace_id;
  68. trace_api::SpanKind span_kind = trace_api::SpanKind::kInternal;
  69. using M = std::map<std::string, int>;
  70. M m1 = {{}};
  71. using L = std::vector<std::pair<trace_api::SpanContext, std::map<std::string, std::string>>>;
  72. L l1 = {{trace_api::SpanContext(false, false), {}}, {trace_api::SpanContext(false, false), {}}};
  73. common::KeyValueIterableView<M> view{m1};
  74. trace_api::SpanContextKeyValueIterableView<L> links{l1};
  75. TraceIdRatioBasedSampler s1(0.01);
  76. auto sampling_result = s1.ShouldSample(trace_api::SpanContext::GetInvalid(), invalid_trace_id, "",
  77. span_kind, view, links);
  78. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  79. ASSERT_EQ(nullptr, sampling_result.attributes);
  80. constexpr uint8_t buf[] = {0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0};
  81. trace_api::TraceId valid_trace_id(buf);
  82. sampling_result = s1.ShouldSample(trace_api::SpanContext::GetInvalid(), valid_trace_id, "",
  83. span_kind, view, links);
  84. ASSERT_EQ(Decision::DROP, sampling_result.decision);
  85. ASSERT_EQ(nullptr, sampling_result.attributes);
  86. TraceIdRatioBasedSampler s2(0.50000001);
  87. sampling_result = s2.ShouldSample(trace_api::SpanContext::GetInvalid(), valid_trace_id, "",
  88. span_kind, view, links);
  89. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  90. ASSERT_EQ(nullptr, sampling_result.attributes);
  91. TraceIdRatioBasedSampler s3(0.49999999);
  92. sampling_result = s3.ShouldSample(trace_api::SpanContext::GetInvalid(), valid_trace_id, "",
  93. span_kind, view, links);
  94. ASSERT_EQ(Decision::DROP, sampling_result.decision);
  95. ASSERT_EQ(nullptr, sampling_result.attributes);
  96. TraceIdRatioBasedSampler s4(0.50000000);
  97. sampling_result = s4.ShouldSample(trace_api::SpanContext::GetInvalid(), valid_trace_id, "",
  98. span_kind, view, links);
  99. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  100. ASSERT_EQ(nullptr, sampling_result.attributes);
  101. }
  102. TEST(TraceIdRatioBasedSampler, ShouldSampleWithContext)
  103. {
  104. uint8_t trace_id_buffer[trace_api::TraceId::kSize] = {1};
  105. trace_api::TraceId trace_id{trace_id_buffer};
  106. uint8_t span_id_buffer[trace_api::SpanId::kSize] = {1};
  107. trace_api::SpanId span_id{span_id_buffer};
  108. trace_api::SpanKind span_kind = trace_api::SpanKind::kInternal;
  109. trace_api::SpanContext c1(trace_id, span_id, trace_api::TraceFlags{0}, false);
  110. trace_api::SpanContext c2(trace_id, span_id, trace_api::TraceFlags{1}, false);
  111. trace_api::SpanContext c3(trace_id, span_id, trace_api::TraceFlags{0}, true);
  112. trace_api::SpanContext c4(trace_id, span_id, trace_api::TraceFlags{1}, true);
  113. using M = std::map<std::string, int>;
  114. M m1 = {{}};
  115. using L = std::vector<std::pair<trace_api::SpanContext, std::map<std::string, std::string>>>;
  116. L l1 = {{trace_api::SpanContext(false, false), {}}, {trace_api::SpanContext(false, false), {}}};
  117. common::KeyValueIterableView<M> view{m1};
  118. trace_api::SpanContextKeyValueIterableView<L> links{l1};
  119. TraceIdRatioBasedSampler s1(0.01);
  120. auto sampling_result = s1.ShouldSample(c1, trace_id, "", span_kind, view, links);
  121. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  122. ASSERT_EQ(nullptr, sampling_result.attributes);
  123. sampling_result = s1.ShouldSample(c2, trace_id, "", span_kind, view, links);
  124. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  125. ASSERT_EQ(nullptr, sampling_result.attributes);
  126. sampling_result = s1.ShouldSample(c3, trace_id, "", span_kind, view, links);
  127. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  128. ASSERT_EQ(nullptr, sampling_result.attributes);
  129. sampling_result = s1.ShouldSample(c4, trace_id, "", span_kind, view, links);
  130. ASSERT_EQ(Decision::RECORD_AND_SAMPLE, sampling_result.decision);
  131. ASSERT_EQ(nullptr, sampling_result.attributes);
  132. }
  133. TEST(TraceIdRatioBasedSampler, TraceIdRatioBasedSamplerHalf)
  134. {
  135. double ratio = 0.5;
  136. int iterations = 100000;
  137. int expected_count = static_cast<int>(iterations * ratio);
  138. int variance = static_cast<int>(iterations * 0.01);
  139. trace_api::SpanContext c(true, true);
  140. TraceIdRatioBasedSampler s(ratio);
  141. int actual_count = RunShouldSampleCountDecision(c, s, iterations);
  142. ASSERT_TRUE(actual_count < (expected_count + variance));
  143. ASSERT_TRUE(actual_count > (expected_count - variance));
  144. }
  145. TEST(TraceIdRatioBasedSampler, TraceIdRatioBasedSamplerOnePercent)
  146. {
  147. double ratio = 0.01;
  148. int iterations = 100000;
  149. int expected_count = static_cast<int>(iterations * ratio);
  150. int variance = static_cast<int>(iterations * 0.01);
  151. trace_api::SpanContext c(true, true);
  152. TraceIdRatioBasedSampler s(ratio);
  153. int actual_count = RunShouldSampleCountDecision(c, s, iterations);
  154. ASSERT_TRUE(actual_count < (expected_count + variance));
  155. ASSERT_TRUE(actual_count > (expected_count - variance));
  156. }
  157. TEST(TraceIdRatioBasedSampler, TraceIdRatioBasedSamplerAll)
  158. {
  159. double ratio = 1.0;
  160. int iterations = 100000;
  161. int expected_count = static_cast<int>(iterations * ratio);
  162. trace_api::SpanContext c(true, true);
  163. TraceIdRatioBasedSampler s(ratio);
  164. int actual_count = RunShouldSampleCountDecision(c, s, iterations);
  165. ASSERT_EQ(actual_count, expected_count);
  166. }
  167. TEST(TraceIdRatioBasedSampler, TraceIdRatioBasedSamplerNone)
  168. {
  169. double ratio = 0.0;
  170. int iterations = 100000;
  171. int expected_count = static_cast<int>(iterations * ratio);
  172. trace_api::SpanContext c(true, true);
  173. TraceIdRatioBasedSampler s(ratio);
  174. int actual_count = RunShouldSampleCountDecision(c, s, iterations);
  175. ASSERT_EQ(actual_count, expected_count);
  176. }
  177. TEST(TraceIdRatioBasedSampler, GetDescription)
  178. {
  179. TraceIdRatioBasedSampler s1(0.01);
  180. ASSERT_EQ("TraceIdRatioBasedSampler{0.010000}", s1.GetDescription());
  181. TraceIdRatioBasedSampler s2(0.00);
  182. ASSERT_EQ("TraceIdRatioBasedSampler{0.000000}", s2.GetDescription());
  183. TraceIdRatioBasedSampler s3(1.00);
  184. ASSERT_EQ("TraceIdRatioBasedSampler{1.000000}", s3.GetDescription());
  185. TraceIdRatioBasedSampler s4(0.102030405);
  186. ASSERT_EQ("TraceIdRatioBasedSampler{0.102030}", s4.GetDescription());
  187. TraceIdRatioBasedSampler s5(3.00);
  188. ASSERT_EQ("TraceIdRatioBasedSampler{1.000000}", s5.GetDescription());
  189. TraceIdRatioBasedSampler s6(-3.00);
  190. ASSERT_EQ("TraceIdRatioBasedSampler{0.000000}", s6.GetDescription());
  191. TraceIdRatioBasedSampler s7(1.00000000001);
  192. ASSERT_EQ("TraceIdRatioBasedSampler{1.000000}", s7.GetDescription());
  193. TraceIdRatioBasedSampler s8(-1.00000000001);
  194. ASSERT_EQ("TraceIdRatioBasedSampler{0.000000}", s8.GetDescription());
  195. TraceIdRatioBasedSampler s9(0.50);
  196. ASSERT_EQ("TraceIdRatioBasedSampler{0.500000}", s9.GetDescription());
  197. }