Skip to main content

antithesis_sdk/
lifecycle.rs

1#[cfg(feature = "full")]
2use crate::{details, internal};
3use serde::Serialize;
4#[cfg(feature = "full")]
5use serde_json::{json, Map, Value};
6
7#[cfg(feature = "full")]
8#[derive(Serialize, Debug)]
9struct AntithesisSetupData<'a> {
10    status: &'a str,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    details: Option<Map<String, Value>>,
13}
14
15#[cfg(feature = "full")]
16#[derive(Serialize, Debug)]
17struct SetupCompleteData<'a> {
18    antithesis_setup: AntithesisSetupData<'a>,
19}
20
21/// Indicates to Antithesis that setup has completed. Call this function when
22/// your system and workload are fully initialized. After this function is
23/// called, Antithesis will take a snapshot of your system and begin
24/// [injecting faults]( https://antithesis.com/docs/environment/fault_injection/).
25///
26/// Calling this function multiple times or from multiple processes will have no
27/// effect. Antithesis will treat the first time any process called this
28/// function as the moment that the setup was completed.
29///
30/// Details may be any borrowed value implementing `Serialize`. Objects are
31/// preserved; other non-null JSON values are wrapped under `"value"`, for
32/// example `3` becomes `{"value": 3}`. Pass `&()` or `&Value::Null` for no
33/// details; an explicit empty object is preserved. Serialization errors emit an
34/// `antithesis_error` message and omit details; the setup event is still
35/// emitted. With the `full` feature disabled, details are not serialized.
36///
37/// # Example
38///
39/// ```
40/// use serde_json::{json, Value};
41/// use antithesis_sdk::lifecycle;
42///
43/// let (num_nodes, main_id) = (10, "n-001");
44///
45/// let startup_data: Value = json!({
46///     "num_nodes": num_nodes,
47///     "main_node_id": main_id,
48/// });
49///
50/// lifecycle::setup_complete(&startup_data);
51/// ```
52pub fn setup_complete<T: Serialize + ?Sized>(details: &T) {
53    #[cfg(feature = "full")]
54    {
55        let antithesis_setup = AntithesisSetupData {
56            status: "complete",
57            details: details::object(details, "setup_complete"),
58        };
59        internal::dispatch_output(&SetupCompleteData { antithesis_setup });
60    }
61    #[cfg(not(feature = "full"))]
62    let _ = details;
63}
64
65/// Indicates to Antithesis that a certain event has been reached. It sends a
66/// structured log message to Antithesis that you may later use to aid
67/// debugging.
68///
69/// In addition to ``details``, you also provide ``name``, which is the name of
70/// the event that you are logging.
71///
72/// Details may be any borrowed value implementing `Serialize`. Objects are
73/// preserved; other non-null JSON values are wrapped under `"value"`, for
74/// example `3` becomes `{"value": 3}`. Null and serialization errors produce an
75/// empty event body `{}`. Serialization errors also emit an `antithesis_error`
76/// message. With the `full` feature disabled, details are not serialized.
77///
78/// # Example
79///
80/// ```
81/// use serde_json::{json, Value};
82/// use antithesis_sdk::lifecycle;
83///
84/// let info_value: Value = json!({
85///     "month": "July",
86///     "day": 17
87/// });
88///
89/// lifecycle::send_event("start_day", &info_value);
90/// ```
91pub fn send_event<T: Serialize + ?Sized>(name: &str, details: &T) {
92    // The name is passed through verbatim, like every other SDK: renaming
93    // or trimming here would make the same program emit different events
94    // depending on which SDK it was written against.
95    #[cfg(feature = "full")]
96    {
97        let json_event = json!({ name: details::object(details, name).unwrap_or_default() });
98        internal::dispatch_output(&json_event);
99    }
100    #[cfg(not(feature = "full"))]
101    let _ = (name, details);
102}
103
104#[cfg(test)]
105mod tests {
106    use super::*;
107    use serde_json::{json, Value};
108
109    #[test]
110    fn setup_complete_without_details() {
111        eprintln!("setup_complete");
112        let details: Value = json!({});
113        setup_complete(&details);
114    }
115
116    #[test]
117    fn setup_complete_with_details() {
118        let details: Value = json!({
119            "name": "Meow Cat",
120            "age": 11,
121            "phones": [
122                "+1 2126581356",
123                "+1 2126581384"
124            ]
125        });
126        setup_complete(&details);
127    }
128
129    #[test]
130    fn send_event_without_details() {
131        let details: Value = json!({});
132        send_event("my event", &details);
133    }
134
135    #[test]
136    fn send_event_with_details() {
137        let details: Value = json!({
138            "name": "Tweety Bird",
139            "age": 4,
140            "phones": [
141                "+1 9734970340"
142            ]
143        });
144        send_event("my event 2", &details);
145    }
146
147    #[test]
148    fn send_event_unnamed_without_details() {
149        let details: Value = json!({});
150        send_event("", &details);
151    }
152
153    #[test]
154    fn send_event_unnamed_with_details() {
155        let details: Value = json!({
156            "color": "red"
157        });
158        send_event("   ", &details);
159    }
160}