antithesis_sdk/
lifecycle.rs

1use crate::internal;
2use serde::Serialize;
3use serde_json::{json, Value};
4
5#[derive(Serialize, Debug)]
6struct AntithesisSetupData<'a, 'b> {
7    status: &'a str,
8    details: &'b Value,
9}
10
11#[derive(Serialize, Debug)]
12struct SetupCompleteData<'a> {
13    antithesis_setup: AntithesisSetupData<'a, 'a>,
14}
15
16/// Indicates to Antithesis that setup has completed. Call this function when your system and workload are fully initialized.
17/// After this function is called, Antithesis will take a snapshot of your system and begin [injecting faults]( https://antithesis.com/docs/environment/fault_injection/).
18///
19/// Calling this function multiple times or from multiple processes will have no effect.
20/// Antithesis will treat the first time any process called this function as the moment that the setup was completed.
21///
22/// # Example
23///
24/// ```
25/// use serde_json::{json, Value};
26/// use antithesis_sdk::lifecycle;
27///
28/// let (num_nodes, main_id) = (10, "n-001");
29///
30/// let startup_data: Value = json!({
31///     "num_nodes": num_nodes,
32///     "main_node_id": main_id,
33/// });
34///
35/// lifecycle::setup_complete(&startup_data);
36/// ```
37pub fn setup_complete(details: &Value) {
38    let status = "complete";
39    let antithesis_setup = AntithesisSetupData::<'_, '_> { status, details };
40
41    let setup_complete_data = SetupCompleteData { antithesis_setup };
42
43    internal::dispatch_output(&setup_complete_data)
44}
45
46/// Indicates to Antithesis that a certain event has been reached. It sends a structured log message to Antithesis that you may later use to aid debugging.
47///
48/// In addition to ``details``, you also provide ``name``, which is the name of the event that you are logging.
49///
50/// # Example
51///
52/// ```
53/// use serde_json::{json, Value};
54/// use antithesis_sdk::lifecycle;
55///
56/// let info_value: Value = json!({
57///     "month": "July",
58///     "day": 17
59/// });
60///
61/// lifecycle::send_event("start_day", &info_value);
62/// ```
63pub fn send_event(name: &str, details: &Value) {
64    let trimmed_name = name.trim();
65    let owned_name: String = if trimmed_name.is_empty() {
66        "anonymous".to_owned()
67    } else {
68        trimmed_name.to_owned()
69    };
70    let json_event = json!({ owned_name: details });
71    internal::dispatch_output(&json_event)
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn setup_complete_without_details() {
80        eprintln!("setup_complete");
81        let details: Value = json!({});
82        setup_complete(&details);
83    }
84
85    #[test]
86    fn setup_complete_with_details() {
87        let details: Value = json!({
88            "name": "Meow Cat",
89            "age": 11,
90            "phones": [
91                "+1 2126581356",
92                "+1 2126581384"
93            ]
94        });
95        setup_complete(&details);
96    }
97
98    #[test]
99    fn send_event_without_details() {
100        let details: Value = json!({});
101        send_event("my event", &details);
102    }
103
104    #[test]
105    fn send_event_with_details() {
106        let details: Value = json!({
107            "name": "Tweety Bird",
108            "age": 4,
109            "phones": [
110                "+1 9734970340"
111            ]
112        });
113        send_event("my event 2", &details);
114    }
115
116    #[test]
117    fn send_event_unnamed_without_details() {
118        let details: Value = json!({});
119        send_event("", &details);
120    }
121
122    #[test]
123    fn send_event_unnamed_with_details() {
124        let details: Value = json!({
125            "color": "red"
126        });
127        send_event("   ", &details);
128    }
129}