diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eaa1b765..3e8caed84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Add custom attributes API for logs. When `logs_with_attributes` is set to `true`, treats the first `varg` passed into `sentry_logs_X(message,...)` as a `sentry_value_t` object of attributes. ([#1435](https://github.com/getsentry/sentry-native/pull/1435)) - Add runtime API to query user consent requirement. ([#1443](https://github.com/getsentry/sentry-native/pull/1443)) - Add logs flush on `sentry_flush()`. ([#1434](https://github.com/getsentry/sentry-native/pull/1434)) +- Add global attributes API. These are added to all `sentry_log_X` calls. ([#1450](https://github.com/getsentry/sentry-native/pull/1450)) ## 0.12.1 diff --git a/include/sentry.h b/include/sentry.h index f9870d5aa..ca5874f68 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -326,11 +326,12 @@ SENTRY_API sentry_value_t sentry_value_new_user_n(const char *id, size_t id_len, /** * Creates a new attribute object. - * value` is required, `unit` is optional. + * value is required, unit is optional. * - *'value' must be a bool, int, double or string (not null, list, object) + * value must be a bool, int, double or string `sentry_value_t` + * OR a list of bool, int, double or string (with all items being the same type) * - * Moves ownership of `value` into the object. The caller does not + * Moves ownership of value into the object. The caller does not * have to call `sentry_value_decref` on it. */ SENTRY_API sentry_value_t sentry_value_new_attribute( @@ -1858,6 +1859,17 @@ SENTRY_API void sentry_scope_set_extra_n(sentry_scope_t *scope, const char *key, SENTRY_API void sentry_remove_extra(const char *key); SENTRY_API void sentry_remove_extra_n(const char *key, size_t key_len); +/** + * Sets attributes created with `sentry_value_new_attribute` to be applied to + * all: + * - logs + */ +SENTRY_API void sentry_set_attribute(const char *key, sentry_value_t attribute); +SENTRY_API void sentry_set_attribute_n( + const char *key, size_t key_len, sentry_value_t attribute); +SENTRY_API void sentry_remove_attribute(const char *key); +SENTRY_API void sentry_remove_attribute_n(const char *key, size_t key_len); + /** * Sets a context object. */ diff --git a/src/sentry_core.c b/src/sentry_core.c index 16b3146f0..465379813 100644 --- a/src/sentry_core.c +++ b/src/sentry_core.c @@ -941,6 +941,39 @@ sentry_remove_extra_n(const char *key, size_t key_len) } } +void +sentry_set_attribute(const char *key, sentry_value_t attribute) +{ + SENTRY_WITH_SCOPE_MUT (scope) { + sentry__scope_set_attribute(scope, key, attribute); + } +} + +void +sentry_set_attribute_n( + const char *key, size_t key_len, sentry_value_t attribute) +{ + SENTRY_WITH_SCOPE_MUT (scope) { + sentry__scope_set_attribute_n(scope, key, key_len, attribute); + } +} + +void +sentry_remove_attribute(const char *key) +{ + SENTRY_WITH_SCOPE_MUT (scope) { + sentry__scope_remove_attribute(scope, key); + } +} + +void +sentry_remove_attribute_n(const char *key, size_t key_len) +{ + SENTRY_WITH_SCOPE_MUT (scope) { + sentry__scope_remove_attribute_n(scope, key, key_len); + } +} + void sentry_set_context(const char *key, sentry_value_t value) { diff --git a/src/sentry_logs.c b/src/sentry_logs.c index c8cbfff75..50dfec020 100644 --- a/src/sentry_logs.c +++ b/src/sentry_logs.c @@ -671,7 +671,10 @@ static sentry_value_t construct_log(sentry_level_t level, const char *message, va_list args) { sentry_value_t log = sentry_value_new_object(); - sentry_value_t attributes = sentry_value_new_object(); + sentry_value_t attributes = sentry_value_new_null(); + SENTRY_WITH_SCOPE (scope) { + attributes = sentry__value_clone(scope->attributes); + } SENTRY_WITH_OPTIONS (options) { // Extract custom attributes if the option is enabled diff --git a/src/sentry_scope.c b/src/sentry_scope.c index 07bfeb4bb..9ae5575a9 100644 --- a/src/sentry_scope.c +++ b/src/sentry_scope.c @@ -74,6 +74,7 @@ init_scope(sentry_scope_t *scope) scope->user = sentry_value_new_null(); scope->tags = sentry_value_new_object(); scope->extra = sentry_value_new_object(); + scope->attributes = sentry_value_new_object(); scope->contexts = sentry_value_new_object(); scope->propagation_context = sentry_value_new_object(); scope->breadcrumbs = sentry__ringbuffer_new(SENTRY_BREADCRUMBS_MAX); @@ -110,6 +111,7 @@ cleanup_scope(sentry_scope_t *scope) sentry_value_decref(scope->user); sentry_value_decref(scope->tags); sentry_value_decref(scope->extra); + sentry_value_decref(scope->attributes); sentry_value_decref(scope->contexts); sentry_value_decref(scope->propagation_context); sentry__ringbuffer_free(scope->breadcrumbs); @@ -588,6 +590,38 @@ sentry_scope_set_extra_n(sentry_scope_t *scope, const char *key, size_t key_len, sentry_value_set_by_key_n(scope->extra, key, key_len, value); } +void +sentry__scope_set_attribute( + sentry_scope_t *scope, const char *key, sentry_value_t attribute) +{ + sentry__scope_set_attribute_n(scope, key, strlen(key), attribute); +} + +void +sentry__scope_set_attribute_n(sentry_scope_t *scope, const char *key, + size_t key_len, sentry_value_t attribute) +{ + if (sentry_value_is_null(sentry_value_get_by_key(attribute, "value")) + || sentry_value_is_null(sentry_value_get_by_key(attribute, "type"))) { + SENTRY_DEBUG("Cannot set attribute with missing 'value' or 'type'"); + return; + } + sentry_value_set_by_key_n(scope->attributes, key, key_len, attribute); +} + +void +sentry__scope_remove_attribute(sentry_scope_t *scope, const char *key) +{ + sentry_value_remove_by_key(scope->attributes, key); +} + +void +sentry__scope_remove_attribute_n( + sentry_scope_t *scope, const char *key, size_t key_len) +{ + sentry_value_remove_by_key_n(scope->attributes, key, key_len); +} + void sentry_scope_set_context( sentry_scope_t *scope, const char *key, sentry_value_t value) diff --git a/src/sentry_scope.h b/src/sentry_scope.h index ba1b0f683..38b5c76cd 100644 --- a/src/sentry_scope.h +++ b/src/sentry_scope.h @@ -17,6 +17,7 @@ struct sentry_scope_s { sentry_value_t user; sentry_value_t tags; sentry_value_t extra; + sentry_value_t attributes; sentry_value_t contexts; sentry_value_t propagation_context; sentry_ringbuffer_t *breadcrumbs; @@ -96,6 +97,21 @@ void sentry__scope_set_fingerprint_va( void sentry__scope_set_fingerprint_nva(sentry_scope_t *scope, const char *fingerprint, size_t fingerprint_len, va_list va); +/** + * Internal scope-based attribute functions. + * For now, these are only used by the non-scope API functions that operate + * on the global scope. + * Once we have attributes for events or scope-based logs/metrics/spans APIs + * these can become part of the public API too. + */ +void sentry__scope_set_attribute( + sentry_scope_t *scope, const char *key, sentry_value_t attribute); +void sentry__scope_set_attribute_n(sentry_scope_t *scope, const char *key, + size_t key_len, sentry_value_t attribute); +void sentry__scope_remove_attribute(sentry_scope_t *scope, const char *key); +void sentry__scope_remove_attribute_n( + sentry_scope_t *scope, const char *key, size_t key_len); + /** * These are convenience macros to automatically lock/unlock the global scope * inside a code block. diff --git a/src/sentry_value.c b/src/sentry_value.c index fb217e699..3d6e3a08d 100644 --- a/src/sentry_value.c +++ b/src/sentry_value.c @@ -509,33 +509,67 @@ sentry_value_new_user(const char *id, const char *username, const char *email, ip_address, ip_address ? strlen(ip_address) : 0); } -sentry_value_t -sentry_value_new_attribute_n( - sentry_value_t value, const char *unit, size_t unit_len) +/** + * Converts a sentry_value_t attribute to its type string representation. + * For lists, checks the first element to determine the array type. + * Returns NULL for unsupported types (NULL, OBJECT). + * https://develop.sentry.dev/sdk/telemetry/spans/span-protocol/#attribute-object-properties + */ +static const char * +attribute_value_type_to_str(sentry_value_t value) { - char *type; switch (sentry_value_get_type(value)) { case SENTRY_VALUE_TYPE_BOOL: - type = "boolean"; - break; + return "boolean"; case SENTRY_VALUE_TYPE_INT32: case SENTRY_VALUE_TYPE_INT64: case SENTRY_VALUE_TYPE_UINT64: - type = "integer"; - break; + return "integer"; case SENTRY_VALUE_TYPE_DOUBLE: - type = "double"; - break; + return "double"; case SENTRY_VALUE_TYPE_STRING: - type = "string"; - break; + return "string"; + case SENTRY_VALUE_TYPE_LIST: { + sentry_value_t first_item = sentry_value_get_by_index(value, 0); + if (sentry_value_is_null(first_item)) { + return NULL; + } + // Determine type based on first element + switch (sentry_value_get_type(first_item)) { + case SENTRY_VALUE_TYPE_BOOL: + return "boolean[]"; + case SENTRY_VALUE_TYPE_INT32: + case SENTRY_VALUE_TYPE_INT64: + case SENTRY_VALUE_TYPE_UINT64: + return "integer[]"; + case SENTRY_VALUE_TYPE_DOUBLE: + return "double[]"; + case SENTRY_VALUE_TYPE_STRING: + return "string[]"; + case SENTRY_VALUE_TYPE_NULL: + case SENTRY_VALUE_TYPE_OBJECT: + case SENTRY_VALUE_TYPE_LIST: + default: + return NULL; + } + } case SENTRY_VALUE_TYPE_NULL: - case SENTRY_VALUE_TYPE_LIST: case SENTRY_VALUE_TYPE_OBJECT: default: + return NULL; + } +} + +sentry_value_t +sentry_value_new_attribute_n( + sentry_value_t value, const char *unit, size_t unit_len) +{ + const char *type = attribute_value_type_to_str(value); + if (!type) { sentry_value_decref(value); return sentry_value_new_null(); } + sentry_value_t attribute = sentry_value_new_object(); sentry_value_set_by_key( diff --git a/tests/unit/test_scope.c b/tests/unit/test_scope.c index aba4c808f..83a6cdfd8 100644 --- a/tests/unit/test_scope.c +++ b/tests/unit/test_scope.c @@ -602,3 +602,236 @@ SENTRY_TEST(scope_breadcrumbs) sentry_close(); } + +SENTRY_TEST(scope_global_attributes) +{ + SENTRY_TEST_OPTIONS_NEW(options); + sentry_init(options); + + // Test setting a valid attribute on the global scope + sentry_value_t valid_attr = sentry_value_new_attribute( + sentry_value_new_string("test_value"), NULL); + sentry_set_attribute("valid_key", valid_attr); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + sentry_value_t retrieved_attr + = sentry_value_get_by_key(attributes, "valid_key"); + + // Check that the attribute was set + TEST_CHECK(!sentry_value_is_null(retrieved_attr)); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + retrieved_attr, "type")), + "string"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + retrieved_attr, "value")), + "test_value"); + } + + // Test that invalid attributes (missing 'value' or 'type') are not set + sentry_value_t invalid_attr_no_value = sentry_value_new_object(); + sentry_value_set_by_key( + invalid_attr_no_value, "type", sentry_value_new_string("string")); + // Missing 'value' field + sentry_set_attribute("invalid_no_value", invalid_attr_no_value); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + sentry_value_t retrieved_attr + = sentry_value_get_by_key(attributes, "invalid_no_value"); + + // Check that the attribute was NOT set + TEST_CHECK(sentry_value_is_null(retrieved_attr)); + } + sentry_value_decref(invalid_attr_no_value); + + // Test invalid attribute missing 'type' + sentry_value_t invalid_attr_no_type = sentry_value_new_object(); + sentry_value_set_by_key( + invalid_attr_no_type, "value", sentry_value_new_string("some_value")); + // Missing 'type' field + sentry_set_attribute("invalid_no_type", invalid_attr_no_type); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + sentry_value_t retrieved_attr + = sentry_value_get_by_key(attributes, "invalid_no_type"); + + // Check that the attribute was NOT set + TEST_CHECK(sentry_value_is_null(retrieved_attr)); + } + sentry_value_decref(invalid_attr_no_type); + + // Test removing an attribute + sentry_remove_attribute("valid_key"); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + sentry_value_t retrieved_attr + = sentry_value_get_by_key(attributes, "valid_key"); + + // Check that the attribute was removed + TEST_CHECK(sentry_value_is_null(retrieved_attr)); + } + + // Test setting attribute with _n variant + sentry_value_t attr_n + = sentry_value_new_attribute(sentry_value_new_int32(42), "percent"); + sentry_set_attribute_n("key_n", 5, attr_n); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + sentry_value_t retrieved_attr + = sentry_value_get_by_key(attributes, "key_n"); + + // Check that the attribute was set + TEST_CHECK(!sentry_value_is_null(retrieved_attr)); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + retrieved_attr, "type")), + "integer"); + TEST_CHECK(sentry_value_as_int32( + sentry_value_get_by_key(retrieved_attr, "value")) + == 42); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + retrieved_attr, "unit")), + "percent"); + } + + sentry_close(); +} + +SENTRY_TEST(scope_local_attributes) +{ + SENTRY_TEST_OPTIONS_NEW(options); + sentry_init(options); + + // global: + // {"all":"global","scope":"global","global":"global"} + sentry_set_attribute("all", + sentry_value_new_attribute(sentry_value_new_string("global"), NULL)); + sentry_set_attribute("global", + sentry_value_new_attribute(sentry_value_new_string("global"), NULL)); + sentry_set_attribute("scope", + sentry_value_new_attribute(sentry_value_new_string("global"), NULL)); + + SENTRY_WITH_SCOPE (global_scope) { + sentry_value_t attributes = global_scope->attributes; + + // Verify global attributes are set + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(attributes, "all"), "value")), + "global"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(attributes, "global"), "value")), + "global"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(attributes, "scope"), "value")), + "global"); + } + + SENTRY_WITH_SCOPE (global_scope) { + // local: + // {"all":"local","scope":"local","local":"local"} + sentry_scope_t *local_scope = sentry_local_scope_new(); + sentry__scope_set_attribute(local_scope, "all", + sentry_value_new_attribute(sentry_value_new_string("local"), NULL)); + sentry__scope_set_attribute(local_scope, "local", + sentry_value_new_attribute(sentry_value_new_string("local"), NULL)); + sentry__scope_set_attribute(local_scope, "scope", + sentry_value_new_attribute(sentry_value_new_string("local"), NULL)); + + sentry_value_t local_attributes = local_scope->attributes; + + // Verify local attributes are set + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(local_attributes, "all"), "value")), + "local"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(local_attributes, "local"), "value")), + "local"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(local_attributes, "scope"), "value")), + "local"); + + // Verify global scope still has its own attributes + sentry_value_t global_attributes = global_scope->attributes; + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(global_attributes, "all"), "value")), + "global"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key( + sentry_value_get_by_key(global_attributes, "global"), "value")), + "global"); + + sentry__scope_free(local_scope); + } + + // Test removing attributes from global scope + sentry_remove_attribute("all"); + + SENTRY_WITH_SCOPE (scope) { + sentry_value_t attributes = scope->attributes; + TEST_CHECK( + sentry_value_is_null(sentry_value_get_by_key(attributes, "all"))); + // Other attributes should still exist + TEST_CHECK(!sentry_value_is_null( + sentry_value_get_by_key(attributes, "global"))); + TEST_CHECK(!sentry_value_is_null( + sentry_value_get_by_key(attributes, "scope"))); + } + + // Test _n variants with local scope + SENTRY_WITH_SCOPE (global_scope) { + sentry_scope_t *local_scope = sentry_local_scope_new(); + sentry__scope_set_attribute_n(local_scope, "test_key", 8, + sentry_value_new_attribute(sentry_value_new_int32(100), "percent")); + + sentry_value_t local_attributes = local_scope->attributes; + sentry_value_t attr + = sentry_value_get_by_key(local_attributes, "test_key"); + + TEST_CHECK(!sentry_value_is_null(attr)); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(attr, "type")), + "integer"); + TEST_CHECK(sentry_value_as_int32(sentry_value_get_by_key(attr, "value")) + == 100); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(attr, "unit")), + "percent"); + + // Remove using _n variant + sentry__scope_remove_attribute_n(local_scope, "test_key", 8); + TEST_CHECK(sentry_value_is_null( + sentry_value_get_by_key(local_attributes, "test_key"))); + + sentry__scope_free(local_scope); + } + + // Test that invalid attributes are not set on local scope + SENTRY_WITH_SCOPE (global_scope) { + sentry_scope_t *local_scope = sentry_local_scope_new(); + + // Try to set invalid attribute (missing 'value') + sentry_value_t invalid_attr = sentry_value_new_object(); + sentry_value_set_by_key( + invalid_attr, "type", sentry_value_new_string("string")); + sentry__scope_set_attribute(local_scope, "invalid", invalid_attr); + + sentry_value_t local_attributes = local_scope->attributes; + TEST_CHECK(sentry_value_is_null( + sentry_value_get_by_key(local_attributes, "invalid"))); + sentry_value_decref(invalid_attr); + + sentry__scope_free(local_scope); + } + + sentry_close(); +} diff --git a/tests/unit/test_uninit.c b/tests/unit/test_uninit.c index 55b7fb688..03ff3209d 100644 --- a/tests/unit/test_uninit.c +++ b/tests/unit/test_uninit.c @@ -19,6 +19,9 @@ SENTRY_TEST(uninitialized) sentry_remove_tag("foo"); sentry_set_extra("foo", sentry_value_new_null()); sentry_remove_extra("foo"); + sentry_set_attribute("foo", + sentry_value_new_attribute(sentry_value_new_string("bar"), NULL)); + sentry_remove_attribute("foo"); sentry_set_context("foo", sentry_value_new_object()); sentry_remove_context("foo"); sentry_set_fingerprint("foo", "bar", NULL); diff --git a/tests/unit/test_value.c b/tests/unit/test_value.c index 09389be67..318a6e9f9 100644 --- a/tests/unit/test_value.c +++ b/tests/unit/test_value.c @@ -536,6 +536,84 @@ SENTRY_TEST(value_attribute) sentry_value_as_string(sentry_value_get_by_key(string_attr_n, "unit")), "bytes"); sentry_value_decref(string_attr_n); + + // Test list attribute types (arrays) + sentry_value_t string_list = sentry_value_new_list(); + sentry_value_append(string_list, sentry_value_new_string("foo")); + sentry_value_append(string_list, sentry_value_new_string("bar")); + sentry_value_t string_list_attr + = sentry_value_new_attribute(string_list, NULL); + TEST_CHECK( + sentry_value_get_type(string_list_attr) == SENTRY_VALUE_TYPE_OBJECT); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + string_list_attr, "type")), + "string[]"); + sentry_value_t string_list_value + = sentry_value_get_by_key(string_list_attr, "value"); + TEST_CHECK( + sentry_value_get_type(string_list_value) == SENTRY_VALUE_TYPE_LIST); + TEST_CHECK(sentry_value_get_length(string_list_value) == 2); + sentry_value_decref(string_list_attr); + + sentry_value_t integer_list = sentry_value_new_list(); + sentry_value_append(integer_list, sentry_value_new_int32(1)); + sentry_value_append(integer_list, sentry_value_new_int32(2)); + sentry_value_append(integer_list, sentry_value_new_int32(3)); + sentry_value_t integer_list_attr + = sentry_value_new_attribute(integer_list, NULL); + TEST_CHECK( + sentry_value_get_type(integer_list_attr) == SENTRY_VALUE_TYPE_OBJECT); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + integer_list_attr, "type")), + "integer[]"); + sentry_value_decref(integer_list_attr); + + sentry_value_t double_list = sentry_value_new_list(); + sentry_value_append(double_list, sentry_value_new_double(1.1)); + sentry_value_append(double_list, sentry_value_new_double(2.2)); + sentry_value_t double_list_attr + = sentry_value_new_attribute(double_list, NULL); + TEST_CHECK( + sentry_value_get_type(double_list_attr) == SENTRY_VALUE_TYPE_OBJECT); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + double_list_attr, "type")), + "double[]"); + sentry_value_decref(double_list_attr); + + sentry_value_t boolean_list = sentry_value_new_list(); + sentry_value_append(boolean_list, sentry_value_new_bool(true)); + sentry_value_append(boolean_list, sentry_value_new_bool(false)); + sentry_value_t boolean_list_attr + = sentry_value_new_attribute(boolean_list, NULL); + TEST_CHECK( + sentry_value_get_type(boolean_list_attr) == SENTRY_VALUE_TYPE_OBJECT); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + boolean_list_attr, "type")), + "boolean[]"); + sentry_value_decref(boolean_list_attr); + + // Test empty list (should return null since first element is null) + sentry_value_t empty_list = sentry_value_new_list(); + sentry_value_t empty_list_attr + = sentry_value_new_attribute(empty_list, NULL); + TEST_CHECK(sentry_value_is_null(empty_list_attr)); + sentry_value_decref(empty_list_attr); + + // Test list with nested list (unsupported, should return null) + sentry_value_t nested_list = sentry_value_new_list(); + sentry_value_append(nested_list, sentry_value_new_list()); + sentry_value_t nested_list_attr + = sentry_value_new_attribute(nested_list, NULL); + TEST_CHECK(sentry_value_is_null(nested_list_attr)); + sentry_value_decref(nested_list_attr); + + // Test list with object (unsupported, should return null) + sentry_value_t object_list = sentry_value_new_list(); + sentry_value_append(object_list, sentry_value_new_object()); + sentry_value_t object_list_attr + = sentry_value_new_attribute(object_list, NULL); + TEST_CHECK(sentry_value_is_null(object_list_attr)); + sentry_value_decref(object_list_attr); } SENTRY_TEST(value_freezing) diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index f8fa3c920..e3619c762 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -8,7 +8,6 @@ XX(attachments_bytes) XX(attachments_extend) XX(background_worker) XX(basic_consent_tracking) -XX(query_consent_requirement) XX(basic_function_transport) XX(basic_function_transport_transaction) XX(basic_function_transport_transaction_ts) @@ -122,6 +121,7 @@ XX(process_invalid) XX(process_spawn) XX(procmaps_parser) XX(propagation_context_init) +XX(query_consent_requirement) XX(rate_limit_parsing) XX(read_envelope_from_file) XX(read_write_envelope_to_file_null) @@ -143,7 +143,9 @@ XX(scope_breadcrumbs) XX(scope_contexts) XX(scope_extra) XX(scope_fingerprint) +XX(scope_global_attributes) XX(scope_level) +XX(scope_local_attributes) XX(scope_tags) XX(scope_user) XX(scoped_txn)