From 17415a2d8e8bff6c1cc6fb1a63fdc67d3aad23bf Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 2 Jul 2026 15:47:17 +0200 Subject: [PATCH 1/2] fix(profiling): Fix accidentally correct Android profile_chunk parsing Fixes logic for parsing Android profile chunks that pass through AndroidOrV2ProfileChunk::parse (viz., Android trace profiles and Android ANR profiles). Prior to this commit, the ::parse implementation worked only because it had been tailored to the quirks of existing Android trace + ANR profiles. But that special-casing will break once the updates to ANR billing under [JAVA-548](https://linear.app/getsentry/issue/JAVA-548/bill-anr-profiles-as-ui-profile-hours-instead-of-continuous-profile0) are complete. Commit anticipates JAVA-548 by: 1. routing Android trace profile chunks by their payload shape, and allowing all ANR profiles to (rightly) be parsed as V2ProfileChunk's; and 2. parsing + serializing Android trace chunks with a new 2.android-trace version so downstream consumers can distinguish them from sample-format v2 chunks. Note: we now reject v1 and versionless Android trace profile chunks. They were always unwanted (and never existed in our reference Android SDK implementation); this commit makes that explicit. Co-Authored-By: Codex --- CHANGELOG.md | 4 +- relay-profiling/src/android/chunk.rs | 24 +++ relay-profiling/src/profile_chunk.rs | 187 +++++++++++++++++++++-- relay-profiling/src/sample/mod.rs | 3 + tests/integration/test_profile_chunks.py | 36 +++++ 5 files changed, 244 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c02ddb64173..4889ded1ab2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ **Bug Fixes**: +- Fix Android trace and ANR profile parsing. Serialize Android trace chunks with `version: "2.android-trace"`. Custom + Android trace `profile_chunk` producers must send `version: "2"` or `version: "2.android-trace"`; `version: "1"` and + versionless Android trace chunks are rejected. ([#6183](https://github.com/getsentry/relay/pull/6183)) - Defer dynamic sampling until metrics config is valid. ([#6246](https://github.com/getsentry/relay/pull/6246)) ## 26.7.1 @@ -47,7 +50,6 @@ - Set sentry.trace.status on segment spans. ([#6140](https://github.com/getsentry/relay/pull/6140)) - Don't modify segment information for V2 web vital spans. ([#6160](https://github.com/getsentry/relay/pull/6160)) - - Support compressed minidumps when the `relay-minidump-uploads` feature is enabled. ([#6151](https://github.com/getsentry/relay/pull/6151)) - Make `--log-level` and `--log-format` take effect again and accept them on all subcommands. ([#6198](https://github.com/getsentry/relay/pull/6198)) - Parse two-component versions in iOS and iPadOS `raw_description` into `version` instead of `kernel_version`. ([#6197](https://github.com/getsentry/relay/pull/6197)) diff --git a/relay-profiling/src/android/chunk.rs b/relay-profiling/src/android/chunk.rs index 62f14489e27..740dd71b342 100644 --- a/relay-profiling/src/android/chunk.rs +++ b/relay-profiling/src/android/chunk.rs @@ -17,6 +17,7 @@ use serde::{Deserialize, Serialize}; use crate::debug_image::get_proguard_image; use crate::measurements::ChunkMeasurement; +use crate::sample::Version; use crate::sample::v2::ProfileData; use crate::types::{ClientSdk, DebugMeta}; use crate::{MAX_PROFILE_CHUNK_DURATION, ProfileError}; @@ -35,6 +36,9 @@ pub struct Metadata { platform: String, release: String, + #[serde(default)] + version: Version, + #[serde(skip_serializing_if = "Option::is_none")] debug_meta: Option, @@ -114,6 +118,11 @@ impl Chunk { // Use duration given by the profiler and not reported by the SDK. profile.metadata.duration_ns = profile.profile.elapsed_time.as_nanos() as u64; + // Convert legacy Android trace version ("2") to the new wire version + // ("2.android-trace"). We do so during parsing rather than + // serialization because raw serde doesn't validate the trace payload. + profile.metadata.version = Version::V2AndroidTrace; + // If build_id is not empty but we don't have any DebugImage set, // we create the proper Proguard image and set the uuid. if !profile.metadata.build_id.is_empty() && profile.metadata.debug_meta.is_none() { @@ -179,6 +188,21 @@ mod tests { assert!(Chunk::parse(&(data.unwrap())[..]).is_ok()); } + #[test] + fn test_parse_canonicalizes_android_trace_profile_version() { + let payload = include_bytes!("../../tests/fixtures/android/chunk/valid.json"); + let input: serde_json::Value = serde_json::from_slice(payload).unwrap(); + assert_eq!(input["version"], "2"); + + let profile = Chunk::parse(payload).unwrap(); + assert_eq!(profile.metadata.version, Version::V2AndroidTrace); + + let output = serde_json::to_value(&profile).unwrap(); + + assert_eq!(output["version"], "2.android-trace"); + assert!(output.get("sampled_profile").is_none()); + } + #[test] fn test_remove_invalid_events() { let payload = diff --git a/relay-profiling/src/profile_chunk.rs b/relay-profiling/src/profile_chunk.rs index 78e928600b3..2d61891d1fc 100644 --- a/relay-profiling/src/profile_chunk.rs +++ b/relay-profiling/src/profile_chunk.rs @@ -94,6 +94,7 @@ impl relay_filter::Filterable for AnyProfileChunk { } /// Either an [`AndroidProfileChunk`] or a [`V2ProfileChunk`]. +#[derive(Debug)] pub enum AndroidOrV2ProfileChunk { Android(Box), V2(Box), @@ -123,6 +124,8 @@ impl AndroidOrV2ProfileChunk { platform: String, #[serde(default)] version: sample::Version, + #[serde(default)] + sampled_profile: Option, } let minimal: MinimalProfile = { @@ -130,16 +133,182 @@ impl AndroidOrV2ProfileChunk { serde_path_to_error::deserialize(d) }?; - match (minimal.platform.as_str(), minimal.version) { - // This has always been parsed with higher priority than `v2`, so this was kept as-is - // when refactoring, but from the looks of it, this may cause issues with v2 profiles - // which happen to be sent from android. - ("android", _) => AndroidProfileChunk::parse(data) + // Android SDKs produce two profile_chunk types that pass through this method: trace + // profiles and Application-Not-Responding (ANR) profiles. They come in multiple + // varieties, each of which needs to be accounted for. + + // Android trace profiles: + // --------------- + // Version: 2 (incorrect), 2.android-trace (corrected) + // Platform: android + // Content field: sampled_profile (i.e., Android Runtime's event-based format, aka + // "traces") + // Destination type: AndroidProfileChunk + + // Android ANR profiles: + // --------------- + // Version: 2 + // Platform: java (incorrect), android (corrected) + // Content field: profile (i.e., standardized stacks/frames/samples format) + // Destination type: V2ProfileChunk + + // We also need to handle non-Android profile chunks. + + // Non-Android profiles: + // --------------- + // Version: 2 + // Platform: cocoa, javascript, etc. + // Content field: profile (i.e., standardized stacks/frames/samples format) + // Destination type: V2ProfileChunk + + let is_android_trace_profile = minimal.version == sample::Version::V2AndroidTrace + // Account for legacy submissions that don't use the 2.android-trace version. + || (minimal.platform == "android" + && minimal.version == sample::Version::V2 + && minimal.sampled_profile.is_some()); + + if is_android_trace_profile { + AndroidProfileChunk::parse(data) .map(Box::new) - .map(Self::Android), - (_, sample::Version::V2) => V2ProfileChunk::parse(data).map(Box::new).map(Self::V2), - (_, sample::Version::V1) => Err(ProfileError::PlatformNotSupported), - (_, sample::Version::Unknown) => Err(ProfileError::PlatformNotSupported), + .map(Self::Android) + } else { + match minimal.version { + sample::Version::V2 => V2ProfileChunk::parse(data).map(Box::new).map(Self::V2), + sample::Version::V2AndroidTrace + | sample::Version::V1 + | sample::Version::Unknown => Err(ProfileError::PlatformNotSupported), + } + } + } +} + +#[cfg(test)] +mod tests { + use serde_json::{Value, json}; + + use super::*; + + #[test] + fn test_parse_properly_versioned_android_trace_profile_into_android_profile_chunk() { + let base_payload: Value = + serde_json::from_slice(include_bytes!("../tests/fixtures/android/chunk/valid.json")) + .unwrap(); + let mut payload = base_payload; + payload["version"] = json!("2.android-trace"); + let data = serde_json::to_vec(&payload).unwrap(); + + // 1. Fresh SDK-shaped payload: `sampled_profile` populated, `profile` absent. + let sdk_chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); + assert!( + matches!(sdk_chunk, AndroidOrV2ProfileChunk::Android(_)), + "expected Android profile chunk when sampled_profile is populated" + ); + + // 2. Relay's own re-serialized shape: `sampled_profile` absent, `profile` populated. + let AndroidOrV2ProfileChunk::Android(android_chunk) = sdk_chunk else { + unreachable!() + }; + let reserialized = serde_json::to_vec(&android_chunk).unwrap(); + let value: Value = serde_json::from_slice(&reserialized).unwrap(); + assert!(value.get("sampled_profile").is_none()); + assert!(value.get("profile").is_some()); + + let round_tripped = AndroidOrV2ProfileChunk::parse(&reserialized).unwrap(); + assert!( + matches!(round_tripped, AndroidOrV2ProfileChunk::Android(_)), + "expected Android profile chunk when profile is populated" + ); + } + + #[test] + fn test_parse_legacy_versioned_android_trace_profile_into_android_profile_chunk() { + let base_payload: Value = + serde_json::from_slice(include_bytes!("../tests/fixtures/android/chunk/valid.json")) + .unwrap(); + let mut payload = base_payload; + payload["version"] = json!("2"); + let data = serde_json::to_vec(&payload).unwrap(); + + let chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); + assert!( + matches!(chunk, AndroidOrV2ProfileChunk::Android(_)), + "expected Android profile chunk for legacy version 2 payload" + ); + } + + #[test] + fn test_parse_sample_v2_profile_into_v2_profile_chunk() { + let base_payload: Value = + serde_json::from_slice(include_bytes!("../tests/fixtures/sample/v2/valid.json")) + .unwrap(); + + for platform in ["android", "cocoa", "javascript", "python"] { + let mut payload = base_payload.clone(); + payload["platform"] = json!(platform); + let data = serde_json::to_vec(&payload).unwrap(); + + let chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); + + assert!( + matches!(chunk, AndroidOrV2ProfileChunk::V2(_)), + "expected v2 profile chunk for platform {platform:?}" + ); + } + } + + #[test] + fn test_return_error_for_version_1_profile() { + for (fixture, payload) in [ + ( + "sample v2 format", + &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], + ), + ( + "android trace format", + &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], + ), + ( + "react native android trace format", + &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], + ), + ] { + let mut payload: Value = serde_json::from_slice(payload).unwrap(); + payload["version"] = json!("1"); + let data = serde_json::to_vec(&payload).unwrap(); + + let err = AndroidOrV2ProfileChunk::parse(&data).unwrap_err(); + assert!( + matches!(err, ProfileError::PlatformNotSupported), + "expected unsupported platform error for {fixture}" + ); + } + } + + #[test] + fn test_return_error_for_unknown_version_profile() { + for (fixture, payload) in [ + ( + "sample v2 format", + &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], + ), + ( + "android trace format", + &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], + ), + ( + "react native android trace format", + &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], + ), + ] { + let mut payload: Value = serde_json::from_slice(payload).unwrap(); + payload.as_object_mut().unwrap().remove("version"); + let data = serde_json::to_vec(&payload).unwrap(); + + let err = AndroidOrV2ProfileChunk::parse(&data).unwrap_err(); + assert!( + matches!(err, ProfileError::PlatformNotSupported), + "expected unsupported platform error for {fixture}" + ); } } } diff --git a/relay-profiling/src/sample/mod.rs b/relay-profiling/src/sample/mod.rs index dd36828aebe..26348af8cce 100644 --- a/relay-profiling/src/sample/mod.rs +++ b/relay-profiling/src/sample/mod.rs @@ -15,6 +15,9 @@ pub enum Version { V1, #[serde(rename = "2")] V2, + /// Special-cased chunk format for Android trace profiles, distinct from sample v2 format. + #[serde(rename = "2.android-trace")] + V2AndroidTrace, } /// Holds information about a single stacktrace frame. diff --git a/tests/integration/test_profile_chunks.py b/tests/integration/test_profile_chunks.py index 0c4727758a2..92caded6884 100644 --- a/tests/integration/test_profile_chunks.py +++ b/tests/integration/test_profile_chunks.py @@ -1,3 +1,4 @@ +import json import uuid from copy import deepcopy from pathlib import Path @@ -321,6 +322,41 @@ def test_profile_chunk_outcomes_rate_limited_fast( assert mini_sentry.captured_envelopes.empty() +@pytest.mark.parametrize( + ["envelope_factory", "expected_version"], + [ + pytest.param(sample_profile_v2_envelope, "2", id="profile v2"), + pytest.param( + android_profile_chunk_envelope, + "2.android-trace", + id="android chunk", + ), + ], +) +def test_profile_chunk_version_is_forwarded( + mini_sentry, + relay_with_processing, + profiles_consumer, + envelope_factory, + expected_version, +): + profiles_consumer = profiles_consumer() + + project_id = 42 + project_config = mini_sentry.add_full_project_config(project_id)["config"] + + project_config.setdefault("features", []).append( + "organizations:continuous-profiling" + ) + + upstream = relay_with_processing(TEST_CONFIG) + upstream.send_envelope(project_id, envelope_factory()) + + profile, headers = profiles_consumer.get_profile() + assert headers == [("project_id", b"42")] + assert json.loads(profile["payload"])["version"] == expected_version + + @pytest.mark.parametrize( "platform, category, filter_context", [ From 6e9022865882a7207866383ecccf8db7c5de54d3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 27 Jul 2026 09:13:43 +0200 Subject: [PATCH 2/2] Address Dav1dde's comments + minor consistency updates --- CHANGELOG.md | 6 +- relay-profiling/src/android/chunk.rs | 4 +- relay-profiling/src/lib.rs | 2 +- relay-profiling/src/profile_chunk.rs | 105 +++++++++------------------ relay-profiling/src/sample/mod.rs | 4 +- 5 files changed, 42 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4889ded1ab2..22cfb2da5b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,9 @@ **Bug Fixes**: - Fix Android trace and ANR profile parsing. Serialize Android trace chunks with `version: "2.android-trace"`. Custom - Android trace `profile_chunk` producers must send `version: "2"` or `version: "2.android-trace"`; `version: "1"` and - versionless Android trace chunks are rejected. ([#6183](https://github.com/getsentry/relay/pull/6183)) + Android trace `profile_chunk` producers should send `version: "2.android-trace"`; legacy `version: "2"` is accepted + only for Android `sampled_profile` payloads. `version: "1"` and versionless Android trace chunks are rejected. + ([#6183](https://github.com/getsentry/relay/pull/6183)) - Defer dynamic sampling until metrics config is valid. ([#6246](https://github.com/getsentry/relay/pull/6246)) ## 26.7.1 @@ -50,6 +51,7 @@ - Set sentry.trace.status on segment spans. ([#6140](https://github.com/getsentry/relay/pull/6140)) - Don't modify segment information for V2 web vital spans. ([#6160](https://github.com/getsentry/relay/pull/6160)) + - Support compressed minidumps when the `relay-minidump-uploads` feature is enabled. ([#6151](https://github.com/getsentry/relay/pull/6151)) - Make `--log-level` and `--log-format` take effect again and accept them on all subcommands. ([#6198](https://github.com/getsentry/relay/pull/6198)) - Parse two-component versions in iOS and iPadOS `raw_description` into `version` instead of `kernel_version`. ([#6197](https://github.com/getsentry/relay/pull/6197)) diff --git a/relay-profiling/src/android/chunk.rs b/relay-profiling/src/android/chunk.rs index 740dd71b342..599777f25f2 100644 --- a/relay-profiling/src/android/chunk.rs +++ b/relay-profiling/src/android/chunk.rs @@ -118,7 +118,7 @@ impl Chunk { // Use duration given by the profiler and not reported by the SDK. profile.metadata.duration_ns = profile.profile.elapsed_time.as_nanos() as u64; - // Convert legacy Android trace version ("2") to the new wire version + // Convert legacy Android trace version ("2") to the corrected version // ("2.android-trace"). We do so during parsing rather than // serialization because raw serde doesn't validate the trace payload. profile.metadata.version = Version::V2AndroidTrace; @@ -189,7 +189,7 @@ mod tests { } #[test] - fn test_parse_canonicalizes_android_trace_profile_version() { + fn test_parse_corrects_android_trace_profile_version() { let payload = include_bytes!("../../tests/fixtures/android/chunk/valid.json"); let input: serde_json::Value = serde_json::from_slice(payload).unwrap(); assert_eq!(input["version"], "2"); diff --git a/relay-profiling/src/lib.rs b/relay-profiling/src/lib.rs index 30469e719fb..fc6c4ace868 100644 --- a/relay-profiling/src/lib.rs +++ b/relay-profiling/src/lib.rs @@ -33,7 +33,7 @@ //! Each item type expects a different format. //! //! For `Profile` item type, we expect the Sample format v1 or Android format. -//! For `ProfileChunk` item type, we expect the Sample format v2. +//! For `ProfileChunk` item type, we expect the Sample format v2 or Android trace chunk format. //! //! # Ingestion //! diff --git a/relay-profiling/src/profile_chunk.rs b/relay-profiling/src/profile_chunk.rs index 2d61891d1fc..9751642b58e 100644 --- a/relay-profiling/src/profile_chunk.rs +++ b/relay-profiling/src/profile_chunk.rs @@ -1,7 +1,8 @@ use serde::Deserialize; use crate::{ - AndroidProfileChunk, PerfettoProfileChunk, ProfileError, ProfileType, V2ProfileChunk, sample, + AndroidProfileChunk, PerfettoProfileChunk, ProfileError, ProfileType, V2ProfileChunk, + sample::Version, }; /// Minimum interface all profile chunk types must implement. @@ -123,7 +124,7 @@ impl AndroidOrV2ProfileChunk { struct MinimalProfile { platform: String, #[serde(default)] - version: sample::Version, + version: Version, #[serde(default)] sampled_profile: Option, } @@ -161,48 +162,42 @@ impl AndroidOrV2ProfileChunk { // Content field: profile (i.e., standardized stacks/frames/samples format) // Destination type: V2ProfileChunk - let is_android_trace_profile = minimal.version == sample::Version::V2AndroidTrace - // Account for legacy submissions that don't use the 2.android-trace version. - || (minimal.platform == "android" - && minimal.version == sample::Version::V2 - && minimal.sampled_profile.is_some()); + let is_android_trace_profile = + minimal.platform == "android" && minimal.sampled_profile.is_some(); - if is_android_trace_profile { - AndroidProfileChunk::parse(data) + match minimal.version { + Version::V2AndroidTrace => AndroidProfileChunk::parse(data) + .map(Box::new) + .map(Self::Android), + // Account for legacy submissions that don't use the 2.android-trace version. + Version::V2 if is_android_trace_profile => AndroidProfileChunk::parse(data) .map(Box::new) - .map(Self::Android) - } else { - match minimal.version { - sample::Version::V2 => V2ProfileChunk::parse(data).map(Box::new).map(Self::V2), - sample::Version::V2AndroidTrace - | sample::Version::V1 - | sample::Version::Unknown => Err(ProfileError::PlatformNotSupported), - } + .map(Self::Android), + Version::V2 => V2ProfileChunk::parse(data).map(Box::new).map(Self::V2), + Version::V1 | Version::Unknown => Err(ProfileError::PlatformNotSupported), } } } #[cfg(test)] mod tests { + use std::assert_matches; + use serde_json::{Value, json}; use super::*; #[test] - fn test_parse_properly_versioned_android_trace_profile_into_android_profile_chunk() { - let base_payload: Value = + fn test_parse_correctly_versioned_android_trace_profile_into_android_profile_chunk() { + let mut payload: Value = serde_json::from_slice(include_bytes!("../tests/fixtures/android/chunk/valid.json")) .unwrap(); - let mut payload = base_payload; payload["version"] = json!("2.android-trace"); let data = serde_json::to_vec(&payload).unwrap(); // 1. Fresh SDK-shaped payload: `sampled_profile` populated, `profile` absent. let sdk_chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); - assert!( - matches!(sdk_chunk, AndroidOrV2ProfileChunk::Android(_)), - "expected Android profile chunk when sampled_profile is populated" - ); + assert_matches!(sdk_chunk, AndroidOrV2ProfileChunk::Android(_)); // 2. Relay's own re-serialized shape: `sampled_profile` absent, `profile` populated. let AndroidOrV2ProfileChunk::Android(android_chunk) = sdk_chunk else { @@ -214,26 +209,19 @@ mod tests { assert!(value.get("profile").is_some()); let round_tripped = AndroidOrV2ProfileChunk::parse(&reserialized).unwrap(); - assert!( - matches!(round_tripped, AndroidOrV2ProfileChunk::Android(_)), - "expected Android profile chunk when profile is populated" - ); + assert_matches!(round_tripped, AndroidOrV2ProfileChunk::Android(_)); } #[test] fn test_parse_legacy_versioned_android_trace_profile_into_android_profile_chunk() { - let base_payload: Value = + let mut payload: Value = serde_json::from_slice(include_bytes!("../tests/fixtures/android/chunk/valid.json")) .unwrap(); - let mut payload = base_payload; payload["version"] = json!("2"); let data = serde_json::to_vec(&payload).unwrap(); let chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); - assert!( - matches!(chunk, AndroidOrV2ProfileChunk::Android(_)), - "expected Android profile chunk for legacy version 2 payload" - ); + assert_matches!(chunk, AndroidOrV2ProfileChunk::Android(_)); } #[test] @@ -249,66 +237,39 @@ mod tests { let chunk = AndroidOrV2ProfileChunk::parse(&data).unwrap(); - assert!( - matches!(chunk, AndroidOrV2ProfileChunk::V2(_)), - "expected v2 profile chunk for platform {platform:?}" - ); + assert_matches!(chunk, AndroidOrV2ProfileChunk::V2(_)); } } #[test] fn test_return_error_for_version_1_profile() { - for (fixture, payload) in [ - ( - "sample v2 format", - &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], - ), - ( - "android trace format", - &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], - ), - ( - "react native android trace format", - &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], - ), + for payload in [ + &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], + &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], + &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], ] { let mut payload: Value = serde_json::from_slice(payload).unwrap(); payload["version"] = json!("1"); let data = serde_json::to_vec(&payload).unwrap(); let err = AndroidOrV2ProfileChunk::parse(&data).unwrap_err(); - assert!( - matches!(err, ProfileError::PlatformNotSupported), - "expected unsupported platform error for {fixture}" - ); + assert_matches!(err, ProfileError::PlatformNotSupported); } } #[test] fn test_return_error_for_unknown_version_profile() { - for (fixture, payload) in [ - ( - "sample v2 format", - &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], - ), - ( - "android trace format", - &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], - ), - ( - "react native android trace format", - &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], - ), + for payload in [ + &include_bytes!("../tests/fixtures/sample/v2/valid.json")[..], + &include_bytes!("../tests/fixtures/android/chunk/valid.json")[..], + &include_bytes!("../tests/fixtures/android/chunk/valid-rn.json")[..], ] { let mut payload: Value = serde_json::from_slice(payload).unwrap(); payload.as_object_mut().unwrap().remove("version"); let data = serde_json::to_vec(&payload).unwrap(); let err = AndroidOrV2ProfileChunk::parse(&data).unwrap_err(); - assert!( - matches!(err, ProfileError::PlatformNotSupported), - "expected unsupported platform error for {fixture}" - ); + assert_matches!(err, ProfileError::PlatformNotSupported); } } } diff --git a/relay-profiling/src/sample/mod.rs b/relay-profiling/src/sample/mod.rs index 26348af8cce..59241d29657 100644 --- a/relay-profiling/src/sample/mod.rs +++ b/relay-profiling/src/sample/mod.rs @@ -6,7 +6,7 @@ use relay_event_schema::protocol::Addr; pub mod v1; pub mod v2; -/// Possible values for the version field of the Sample Format. +/// Possible values for profile payload versions. #[derive(Debug, Serialize, Deserialize, Copy, Clone, Default, PartialEq, Eq)] pub enum Version { #[default] @@ -15,7 +15,7 @@ pub enum Version { V1, #[serde(rename = "2")] V2, - /// Special-cased chunk format for Android trace profiles, distinct from sample v2 format. + /// Special-cased chunk format for Android trace profiles, distinct from Sample Format V2. #[serde(rename = "2.android-trace")] V2AndroidTrace, }