Skip to content

Commit

Permalink
feat: Implement Envelope::from_path and Envelope::from_reader
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilogorek committed Apr 14, 2022
1 parent 799f211 commit 7f883b3
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 6 deletions.
4 changes: 2 additions & 2 deletions sentry-contexts/src/utils.rs
Expand Up @@ -54,7 +54,7 @@ mod model_support {

pub fn get_macos_version() -> Option<String> {
let version = sysctlbyname_call("kern.osproductversion")?;
let dot_count = version.split(".").count() - 1;
let dot_count = version.split('.').count() - 1;
if dot_count < 2 {
return Some(version + ".0");
}
Expand Down Expand Up @@ -89,7 +89,7 @@ mod model_support {
fn test_macos_version_and_build() {
let v = get_macos_version().unwrap();
assert!(v.chars().all(|c| c.is_digit(10) || c == '.'));
let dot_count = v.split(".").count() - 1;
let dot_count = v.split('.').count() - 1;
assert_eq!(dot_count, 2);
let b = get_macos_build().unwrap();
assert!(b.chars().all(|c| c.is_ascii_alphabetic() || c.is_digit(10)));
Expand Down
7 changes: 5 additions & 2 deletions sentry-types/src/protocol/attachment.rs
@@ -1,7 +1,9 @@
use std::fmt;

use serde::Deserialize;

/// The different types an attachment can have.
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Deserialize)]
pub enum AttachmentType {
/// (default) A standard attachment without special meaning.
Attachment,
Expand Down Expand Up @@ -37,8 +39,9 @@ impl AttachmentType {
}
}

#[derive(Clone, PartialEq)]
/// Represents an attachment item.
#[derive(Clone, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Attachment {
/// The actual attachment data.
pub buffer: Vec<u8>,
Expand Down
96 changes: 94 additions & 2 deletions sentry-types/src/protocol/envelope.rs
@@ -1,5 +1,10 @@
use std::io::Write;
use std::{
fs::File,
io::{BufReader, Write},
path::Path,
};

use serde::Deserialize;
use uuid::Uuid;

use super::v7::{Attachment, Event, SessionAggregates, SessionUpdate, Transaction};
Expand All @@ -8,9 +13,10 @@ use super::v7::{Attachment, Event, SessionAggregates, SessionUpdate, Transaction
///
/// See the [documentation on Items](https://develop.sentry.dev/sdk/envelopes/#items)
/// for more details.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum EnvelopeItem {
/// An Event Item.
///
Expand Down Expand Up @@ -230,6 +236,25 @@ impl Envelope {

Ok(())
}

/// Creates a new Envelope from reader.
pub fn from_reader<R: std::io::BufRead>(reader: R) -> std::io::Result<Envelope> {
let mut envelope = Envelope::new();
// Ignore envelope header, as the event_id will eventually come from event or transaction item
for line in reader.lines().skip(1) {
if let Ok(item) = serde_json::from_str::<EnvelopeItem>(&line?) {
envelope.add_item(item);
}
}
Ok(envelope)
}

/// Creates a new Envelope from path.
pub fn from_path<P: AsRef<Path>>(path: P) -> std::io::Result<Envelope> {
let file = File::open(path)?;
let reader = BufReader::new(file);
Envelope::from_reader(reader)
}
}

impl From<Event<'static>> for Envelope {
Expand Down Expand Up @@ -296,6 +321,21 @@ mod test {
)
}

#[test]
fn test_deserialize_event() {
let event_id = Uuid::parse_str("22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c").unwrap();
let timestamp = timestamp("2020-07-20T14:51:14.296Z");
let event = Event {
event_id,
timestamp,
..Default::default()
};
let envelope: Envelope = event.into();
let serialized = to_str(envelope);
let deserialized = Envelope::from_reader(serialized.as_bytes()).unwrap();
assert_eq!(serialized, to_str(deserialized))
}

#[test]
fn test_session() {
let session_id = Uuid::parse_str("22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c").unwrap();
Expand Down Expand Up @@ -328,6 +368,34 @@ mod test {
)
}

#[test]
fn test_deserialize_session() {
let session_id = Uuid::parse_str("22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c").unwrap();
let started = timestamp("2020-07-20T14:51:14.296Z");
let session = SessionUpdate {
session_id,
distinct_id: Some("foo@bar.baz".to_owned()),
sequence: None,
timestamp: None,
started,
init: true,
duration: Some(1.234),
status: SessionStatus::Ok,
errors: 123,
attributes: SessionAttributes {
release: "foo-bar@1.2.3".into(),
environment: Some("production".into()),
ip_address: None,
user_agent: None,
},
};
let mut envelope = Envelope::new();
envelope.add_item(session);
let serialized = to_str(envelope);
let deserialized = Envelope::from_reader(serialized.as_bytes()).unwrap();
assert_eq!(serialized, to_str(deserialized))
}

#[test]
fn test_transaction() {
let event_id = Uuid::parse_str("22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c").unwrap();
Expand Down Expand Up @@ -355,4 +423,28 @@ mod test {
"#
)
}

#[test]
fn test_deserialize_transaction() {
let event_id = Uuid::parse_str("22d00b3f-d1b1-4b5d-8d20-49d138cd8a9c").unwrap();
let span_id = "d42cee9fc3e74f5c".parse().unwrap();
let trace_id = "335e53d614474acc9f89e632b776cc28".parse().unwrap();
let start_timestamp = timestamp("2020-07-20T14:51:14.296Z");
let spans = vec![Span {
span_id,
trace_id,
start_timestamp,
..Default::default()
}];
let transaction = Transaction {
event_id,
start_timestamp,
spans,
..Default::default()
};
let envelope: Envelope = transaction.into();
let serialized = to_str(envelope);
let deserialized = Envelope::from_reader(serialized.as_bytes()).unwrap();
assert_eq!(serialized, to_str(deserialized))
}
}
2 changes: 2 additions & 0 deletions sentry-types/src/protocol/session.rs
Expand Up @@ -90,6 +90,7 @@ fn is_false(val: &bool) -> bool {
/// Refer to the [Sessions](https://develop.sentry.dev/sdk/sessions/) documentation
/// for more details.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SessionUpdate<'a> {
/// The session identifier.
#[serde(rename = "sid", default = "Uuid::new_v4")]
Expand Down Expand Up @@ -169,6 +170,7 @@ pub struct SessionAggregateItem {
/// For *request-mode* sessions, sessions will be aggregated instead of being
/// sent as individual updates.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SessionAggregates<'a> {
/// A batch of sessions that were started.
#[serde(default)]
Expand Down
2 changes: 2 additions & 0 deletions sentry-types/src/protocol/v7.rs
Expand Up @@ -1510,6 +1510,7 @@ mod event {

/// Represents a full event for Sentry.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Event<'a> {
/// The ID of the event
#[serde(default = "event::default_id", serialize_with = "event::serialize_id")]
Expand Down Expand Up @@ -1895,6 +1896,7 @@ impl fmt::Display for SpanStatus {

/// Represents a tracing transaction.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Transaction<'a> {
/// The ID of the event
#[serde(default = "event::default_id", serialize_with = "event::serialize_id")]
Expand Down

0 comments on commit 7f883b3

Please sign in to comment.