diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e388f56c..005c30435 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ be done manually. Creates a python virtualenv, and runs all the tests through `pytest`. -**Running integration-tests manually**: +**Running integration tests manually**: $ pytest --verbose --maxfail=1 --capture=no tests/ @@ -47,13 +47,20 @@ can also be invoked directly. The `maxfail` parameter will abort after the first failure, and `capture=no` will print the complete compiler output, and test log. -**Running unit-tests manually**: +**Running unit tests**: + + $ make test-unit + +Unit tests also have a dedicated `make` target, if they need to be run separately +from the integration tests. + +**Running unit tests manually**: $ cmake -B build -D CMAKE_RUNTIME_OUTPUT_DIRECTORY=$(pwd)/build $ cmake --build build --target sentry_test_unit $ ./build/sentry_test_unit -The unit-tests are a separate executable target and can be built and run on +The unit tests are a separate executable target and can be built and run on their own. ## How to interpret CI failures diff --git a/Makefile b/Makefile index cf14522f9..71e63094d 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,10 @@ build/sentry_test_unit: build test: update-test-discovery test-integration .PHONY: test +test-unit: update-test-discovery build/sentry_test_unit + ./build/sentry_test_unit +.PHONY: test-unit + test-integration: setup-venv .venv/bin/pytest tests --verbose .PHONY: test-integration diff --git a/include/sentry.h b/include/sentry.h index a57452f7e..3c78e57f2 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -193,7 +193,7 @@ SENTRY_API sentry_value_t sentry_value_new_int32(int32_t value); SENTRY_API sentry_value_t sentry_value_new_double(double value); /** - * Creates a new boolen value. + * Creates a new boolean value. */ SENTRY_API sentry_value_t sentry_value_new_bool(int value); @@ -582,7 +582,7 @@ SENTRY_API int sentry_envelope_write_to_file( /** * The Sentry Client Options. * - * See https://docs.sentry.io/error-reporting/configuration/ + * See https://docs.sentry.io/platforms/native/configuration/ */ struct sentry_options_s; typedef struct sentry_options_s sentry_options_t; diff --git a/src/sentry_uuid.c b/src/sentry_uuid.c index 1ebcd929b..ad5e34999 100644 --- a/src/sentry_uuid.c +++ b/src/sentry_uuid.c @@ -1,6 +1,7 @@ #include "sentry_boot.h" #include "sentry_random.h" +#include "sentry_uuid.h" #include #include @@ -101,6 +102,27 @@ sentry_uuid_as_string(const sentry_uuid_t *uuid, char str[37]) #undef B } +void +sentry__internal_uuid_as_string(const sentry_uuid_t *uuid, char str[37]) +{ +#define B(X) (unsigned char)uuid->bytes[X] + snprintf(str, 33, + "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%" + "02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + B(0), B(1), B(2), B(3), B(4), B(5), B(6), B(7), B(8), B(9), B(10), + B(11), B(12), B(13), B(14), B(15)); +#undef B +} + +void +sentry__span_uuid_as_string(const sentry_uuid_t *uuid, char str[17]) +{ +#define B(X) (unsigned char)uuid->bytes[X] + snprintf(str, 17, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", B(0), + B(1), B(2), B(3), B(4), B(5), B(6), B(7)); +#undef B +} + #ifdef SENTRY_PLATFORM_WINDOWS sentry_uuid_t sentry__uuid_from_native(const GUID *guid) diff --git a/src/sentry_uuid.h b/src/sentry_uuid.h index aacd6bbe6..00a17a27d 100644 --- a/src/sentry_uuid.h +++ b/src/sentry_uuid.h @@ -3,11 +3,22 @@ #include "sentry_boot.h" +/** + * Converts a sentry UUID to a string representation used for internal + * sentry UUIDs such as event IDs. + */ +void sentry__internal_uuid_as_string(const sentry_uuid_t *uuid, char str[37]); + +/** + * Converts a sentry UUID to a string representation used for span IDs. + */ +void sentry__span_uuid_as_string(const sentry_uuid_t *uuid, char str[17]); + #ifdef SENTRY_PLATFORM_WINDOWS /** * Create a new UUID from the windows-native GUID type. */ -sentry_uuid_t sentry__uuid_from_native(GUID *guid); +sentry_uuid_t sentry__uuid_from_native(const GUID *guid); #endif #endif diff --git a/src/sentry_value.c b/src/sentry_value.c index 0fb51df69..c45ce748b 100644 --- a/src/sentry_value.c +++ b/src/sentry_value.c @@ -24,6 +24,7 @@ #include "sentry_string.h" #include "sentry_sync.h" #include "sentry_utils.h" +#include "sentry_uuid.h" #include "sentry_value.h" /** @@ -973,6 +974,30 @@ sentry__value_new_hexstring(const uint8_t *bytes, size_t len) return sentry__value_new_string_owned(buf); } +sentry_value_t +sentry__value_new_span_uuid(const sentry_uuid_t *uuid) +{ + char *buf = sentry_malloc(17); + if (!buf) { + return sentry_value_new_null(); + } + sentry__span_uuid_as_string(uuid, buf); + buf[16] = '\0'; + return sentry__value_new_string_owned(buf); +} + +sentry_value_t +sentry__value_new_internal_uuid(const sentry_uuid_t *uuid) +{ + char *buf = sentry_malloc(33); + if (!buf) { + return sentry_value_new_null(); + } + sentry__internal_uuid_as_string(uuid, buf); + buf[32] = '\0'; + return sentry__value_new_string_owned(buf); +} + sentry_value_t sentry__value_new_uuid(const sentry_uuid_t *uuid) { diff --git a/src/sentry_value.h b/src/sentry_value.h index 375cb70ca..2eb5004f1 100644 --- a/src/sentry_value.h +++ b/src/sentry_value.h @@ -25,6 +25,20 @@ sentry_value_t sentry__value_new_addr(uint64_t addr); */ sentry_value_t sentry__value_new_hexstring(const uint8_t *bytes, size_t len); +/** + * Creates a new String Value from the `uuid` that conforms to + * the structure of a span ID. + * See also `sentry__span_uuid_as_string`. + */ +sentry_value_t sentry__value_new_span_uuid(const sentry_uuid_t *uuid); + +/** + * Creates a new String Value from the `uuid` in a form meant for + * ingestion as an internal ID. + * See also `sentry_internal_uuid_as_string`. + */ +sentry_value_t sentry__value_new_internal_uuid(const sentry_uuid_t *uuid); + /** * Creates a new String Value from the `uuid`. * See also `sentry_uuid_as_string`. diff --git a/tests/unit/test_uuid.c b/tests/unit/test_uuid.c index ade91da99..6be5044f3 100644 --- a/tests/unit/test_uuid.c +++ b/tests/unit/test_uuid.c @@ -1,5 +1,6 @@ #include "sentry_testsupport.h" #include +#include SENTRY_TEST(uuid_api) { @@ -25,4 +26,23 @@ SENTRY_TEST(uuid_v4) sentry_uuid_as_bytes(&uuid, bytes); TEST_CHECK(bytes[6] >> 4 == 4); } -} \ No newline at end of file +} + +SENTRY_TEST(internal_uuid_api) +{ + sentry_uuid_t uuid + = sentry_uuid_from_string("f391fdc0bb2743b18c0c183bc217d42b"); + TEST_CHECK(!sentry_uuid_is_nil(&uuid)); + char ibuf[37]; + sentry__internal_uuid_as_string(&uuid, ibuf); + TEST_CHECK_STRING_EQUAL(ibuf, "f391fdc0bb2743b18c0c183bc217d42b"); + + char sbuf[17]; + sentry__span_uuid_as_string(&uuid, sbuf); + TEST_CHECK_STRING_EQUAL(sbuf, "f391fdc0bb2743b1"); + + sentry_uuid_t span_id = sentry_uuid_from_string("f391fdc0bb2743b1"); + TEST_CHECK(!sentry_uuid_is_nil(&span_id)); + sentry__span_uuid_as_string(&span_id, sbuf); + TEST_CHECK_STRING_EQUAL(sbuf, "f391fdc0bb2743b1"); +} diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index eb1626160..51615be37 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -15,6 +15,7 @@ XX(dsn_store_url_without_path) XX(empty_transport) XX(fuzz_json) XX(init_failure) +XX(internal_uuid_api) XX(invalid_dsn) XX(invalid_proxy) XX(iso_time)