diff --git a/src/sentry_core.h b/src/sentry_core.h index 8040ef140..3ee88628a 100644 --- a/src/sentry_core.h +++ b/src/sentry_core.h @@ -88,4 +88,12 @@ void sentry__options_unlock(void); for (sentry_options_t *Options = sentry__options_lock(); Options; \ sentry__options_unlock(), Options = NULL) +// these for now are only needed for tests +#ifdef SENTRY_UNITTEST +bool sentry__is_unsampled(double sample_rate); +bool sentry__should_skip_transaction(sentry_value_t tx_cxt); +bool sentry__should_skip_event( + const sentry_options_t *options, sentry_value_t event); +#endif + #endif diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 91b908ba9..db18b0f95 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -29,6 +29,7 @@ add_executable(sentry_test_unit test_mpack.c test_path.c test_ratelimiter.c + test_sampling.c test_session.c test_slice.c test_symbolizer.c diff --git a/tests/unit/test_sampling.c b/tests/unit/test_sampling.c new file mode 100644 index 000000000..c9f0257fe --- /dev/null +++ b/tests/unit/test_sampling.c @@ -0,0 +1,67 @@ +#include "sentry_core.h" +#include "sentry_testsupport.h" + +SENTRY_TEST(sampling_decision) +{ + TEST_CHECK(sentry__is_unsampled(0.0)); + TEST_CHECK(sentry__is_unsampled(1.0) == false); + TEST_CHECK(sentry__is_unsampled(2.0) == false); +} + +SENTRY_TEST(sampling_transaction) +{ + sentry_options_t *options = sentry_options_new(); + TEST_CHECK(sentry_init(options) == 0); + + // TODO: replace with proper construction of a transaction, e.g. + // new_transaction_context -> transaction_context_set_sampled -> + // start_transaction + // using transaction context in place of a full transaction for now. + sentry_value_t tx_cxt = sentry_value_new_transaction_context("honk"); + + sentry_transaction_context_set_sampled(tx_cxt, 0); + TEST_CHECK(sentry__should_skip_transaction(tx_cxt)); + + sentry_transaction_context_set_sampled(tx_cxt, 1); + TEST_CHECK(sentry__should_skip_transaction(tx_cxt) == false); + + // fall back to default in sentry options (0.0) if sampled isn't there + sentry_transaction_context_remove_sampled(tx_cxt); + TEST_CHECK(sentry__should_skip_transaction(tx_cxt)); + + options = sentry_options_new(); + sentry_options_set_traces_sample_rate(options, 1.0); + TEST_CHECK(sentry_init(options) == 0); + + TEST_CHECK(sentry__should_skip_transaction(tx_cxt) == false); + + sentry_value_decref(tx_cxt); +} + +SENTRY_TEST(sampling_event) +{ + // default is to sample all (error) events, and to not sample any + // transactions + sentry_options_t *options = sentry_options_new(); + + sentry_value_t event = sentry_value_new_object(); + sentry_value_set_by_key(event, "sampled", sentry_value_new_bool(0)); + + // events ignore sampled field if they're not transactions + TEST_CHECK(sentry__should_skip_event(options, event) == false); + + // respect sampled field if it is a transaction + sentry_value_set_by_key( + event, "type", sentry_value_new_string("transaction")); + TEST_CHECK(sentry__should_skip_event(options, event)); + + // if the sampled field isn't set on a transaction, don't ever send + // transactions even if the option says to do so + sentry_value_remove_by_key(event, "sampled"); + TEST_CHECK(sentry__should_skip_event(options, event)); + sentry_options_set_traces_sample_rate(options, 1.0); + TEST_CHECK(sentry__should_skip_event(options, event)); + + sentry_value_decref(event); + sentry_options_free(options); +} diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index a8f055f03..e9ff84f2f 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -39,6 +39,9 @@ XX(procmaps_parser) XX(rate_limit_parsing) XX(recursive_paths) XX(sampling_before_send) +XX(sampling_decision) +XX(sampling_event) +XX(sampling_transaction) XX(serialize_envelope) XX(session_basics) XX(slice)