Skip to content

Commit

Permalink
fix: FormatException when reading ProcessorFrequency (#3541)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
  • Loading branch information
bitsandfoxes and jamescrosswell authored Aug 24, 2024
1 parent bddec9f commit de216fa
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

### Fixes

- On mobile devices, the SDK no longer throws a `FormatException` for `ProcessorFrequency` when trying to report native events ([#3541](https://github.com/getsentry/sentry-dotnet/pull/3541))
- Unfinished spans are now correctly stored and retrieved by the CachingTransport ([#3533](https://github.com/getsentry/sentry-dotnet/pull/3533))

### Dependencies
Expand Down
20 changes: 12 additions & 8 deletions src/Sentry/Protocol/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,16 +427,13 @@ public static Device FromJson(JsonElement json)
var modelId = json.GetPropertyOrNull("model_id")?.GetString();
var architecture = json.GetPropertyOrNull("arch")?.GetString();

// TODO: For next major: Remove this and change batteryLevel from short to float
// TODO: For next major: Remove this and change BatteryLevel from short to float
// The Java and Cocoa SDK report the battery as `float`
// Cocoa https://github.com/getsentry/sentry-cocoa/blob/e773cad622b86735f1673368414009475e4119fd/Sources/Sentry/include/SentryUIDeviceWrapper.h#L18
// Java https://github.com/getsentry/sentry-java/blob/25f1ca4e1636a801c17c1662f0145f888550bce8/sentry/src/main/java/io/sentry/protocol/Device.java#L231-L233
short? batteryLevel = null;
var batteryProperty = json.GetPropertyOrNull("battery_level");
if (batteryProperty.HasValue)
{
batteryLevel = (short)batteryProperty.Value.GetDouble();
}
var batteryLevel = json.GetPropertyOrNull("battery_level")?.TryGetDouble(out var level) is true
? (short)level
: (short?)null;

var isCharging = json.GetPropertyOrNull("charging")?.GetBoolean();
var isOnline = json.GetPropertyOrNull("online")?.GetBoolean();
Expand All @@ -456,7 +453,14 @@ public static Device FromJson(JsonElement json)
var bootTime = json.GetPropertyOrNull("boot_time")?.GetDateTimeOffset();
var processorCount = json.GetPropertyOrNull("processor_count")?.GetInt32();
var cpuDescription = json.GetPropertyOrNull("cpu_description")?.GetString();
var processorFrequency = json.GetPropertyOrNull("processor_frequency")?.GetInt32();

// TODO: For next major: Remove this and change ProcessorFrequency from int to float
// The Java SDK reports the processorFrequency as `double`
// Java https://github.com/getsentry/sentry-java/blob/9762f09afa51944b40a9b77e116a55e54636e6c5/sentry/src/main/java/io/sentry/protocol/Device.java#L130
var processorFrequency = json.GetPropertyOrNull("processor_frequency")?.TryGetDouble(out var frequency) is true
? (int)frequency
: (int?)null;

var deviceType = json.GetPropertyOrNull("device_type")?.GetString();
var batteryStatus = json.GetPropertyOrNull("battery_status")?.GetString();
var deviceUniqueIdentifier = json.GetPropertyOrNull("device_unique_identifier")?.GetString();
Expand Down
140 changes: 140 additions & 0 deletions test/Sentry.Tests/Protocol/DeviceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
namespace Sentry.Tests.Protocol;

public class DeviceTests
{
[Fact]
public void Clone_CopyValues()
{
// Arrange
var sut = TestDevice();

// Act
var result = sut.Clone();

// Assert
AssertAreEqual(result, sut);
}

[Fact]
public void WriteTo_FromJson_Symmetric()
{
// Arrange
var sut = TestDevice();

var json = sut.ToJsonString();
using var document = JsonDocument.Parse(json);
var jsonElement = document.RootElement;

// Act
var result = Device.FromJson(jsonElement);

// Assert
AssertAreEqual(result, sut);
}

[Fact]
public void FromJson_JavaTypes_CastCorrectly()
{
// Arrange
var sut = TestDevice();

var json = sut.ToJsonString()
// In the Java SDK, the Processor Frequency is stored as a Double
.Replace(@"""processor_frequency"": 12", @"""processor_frequency"": 12.0");

using var document = JsonDocument.Parse(json);
var jsonElement = document.RootElement;

// Act
var result = Device.FromJson(jsonElement);

// Assert
AssertAreEqual(result, sut);
}

private static Device TestDevice()
{
return new Device
{
Name = "TestName",
Manufacturer = "TestManufacturer",
Brand = "TestBrand",
Architecture = "TestArchitecture",
BatteryLevel = 1,
IsCharging = true,
IsOnline = true,
BootTime = new DateTimeOffset(2001, 06, 15, 12, 30, 0, TimeSpan.Zero),
ExternalFreeStorage = 2,
ExternalStorageSize = 3,
ScreenResolution = "800x600",
ScreenDensity = 1.2f,
ScreenDpi = 4,
Family = "TestFamily",
FreeMemory = 5,
FreeStorage = 6,
MemorySize = 7,
Model = "TestModel",
ModelId = "TestModelId",
Orientation = DeviceOrientation.Landscape,
Simulator = true,
StorageSize = 8,
Timezone = TimeZoneInfo.Utc,
UsableMemory = 9,
LowMemory = true,
ProcessorCount = 11,
CpuDescription = "TestCpuDescription",
ProcessorFrequency = 12,
SupportsVibration = true,
DeviceType = "TestDeviceType",
BatteryStatus = "TestBatteryStatus",
DeviceUniqueIdentifier = "TestDeviceUniqueIdentifier",
SupportsAccelerometer = true,
SupportsGyroscope = true,
SupportsAudio = true,
SupportsLocationService = true
};
}

private static void AssertAreEqual(Device actual, Device expected)
{
using (new AssertionScope())
{
actual.Name.Should().Be(expected.Name);
actual.Manufacturer.Should().Be(expected.Manufacturer);
actual.Brand.Should().Be(expected.Brand);
actual.Architecture.Should().Be(expected.Architecture);
actual.BatteryLevel.Should().Be(expected.BatteryLevel);
actual.IsCharging.Should().Be(expected.IsCharging);
actual.IsOnline.Should().Be(expected.IsOnline);
actual.BootTime.Should().Be(expected.BootTime);
actual.ExternalFreeStorage.Should().Be(expected.ExternalFreeStorage);
actual.ExternalStorageSize.Should().Be(expected.ExternalStorageSize);
actual.ScreenResolution.Should().Be(expected.ScreenResolution);
actual.ScreenDensity.Should().Be(expected.ScreenDensity);
actual.ScreenDpi.Should().Be(expected.ScreenDpi);
actual.Family.Should().Be(expected.Family);
actual.FreeMemory.Should().Be(expected.FreeMemory);
actual.FreeStorage.Should().Be(expected.FreeStorage);
actual.MemorySize.Should().Be(expected.MemorySize);
actual.Model.Should().Be(expected.Model);
actual.ModelId.Should().Be(expected.ModelId);
actual.Orientation.Should().Be(expected.Orientation);
actual.Simulator.Should().Be(expected.Simulator);
actual.StorageSize.Should().Be(expected.StorageSize);
actual.Timezone.Should().Be(expected.Timezone);
actual.UsableMemory.Should().Be(expected.UsableMemory);
actual.LowMemory.Should().Be(expected.LowMemory);
actual.ProcessorCount.Should().Be(expected.ProcessorCount);
actual.CpuDescription.Should().Be(expected.CpuDescription);
actual.ProcessorFrequency.Should().Be(expected.ProcessorFrequency);
actual.SupportsVibration.Should().Be(expected.SupportsVibration);
actual.DeviceType.Should().Be(expected.DeviceType);
actual.BatteryStatus.Should().Be(expected.BatteryStatus);
actual.DeviceUniqueIdentifier.Should().Be(expected.DeviceUniqueIdentifier);
actual.SupportsAccelerometer.Should().Be(expected.SupportsAccelerometer);
actual.SupportsGyroscope.Should().Be(expected.SupportsGyroscope);
actual.SupportsAudio.Should().Be(expected.SupportsAudio);
actual.SupportsLocationService.Should().Be(expected.SupportsLocationService);
}
}
}

0 comments on commit de216fa

Please sign in to comment.