shadow_integration_tests/
e2e_flow.rs1use shadow_core::PeerId;
4
5pub fn test_full_e2e_flow() -> Result<(), String> {
7 let alice_sk = crypto::SigningKey::generate();
8 let alice_id = PeerId::random();
9 let bob_sk = crypto::SigningKey::generate();
10 let bob_id = PeerId::random();
11 let alice_vk = alice_sk.verify_key();
12 let bob_vk = bob_sk.verify_key();
13
14 let (a_state, a_pub) = messaging::SecureChannel::initiate(alice_sk, alice_id);
16 let (b_state, b_pub) = messaging::SecureChannel::initiate(bob_sk, bob_id);
17 let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, bob_vk)
18 .map_err(|e| format!("Channel setup failed: {}", e))?;
19 let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, alice_vk)
20 .map_err(|e| format!("Channel setup failed: {}", e))?;
21
22 let msg = messaging::Message::text(
24 alice_id,
25 messaging::MessageTarget::Direct(bob_id),
26 "E2E integration test: full pipeline",
27 );
28
29 let envelope = a_chan
31 .encrypt_message(&msg)
32 .map_err(|e| format!("Encrypt: {}", e))?;
33 let env_bytes = envelope
34 .to_bytes()
35 .map_err(|e| format!("Env serialize: {}", e))?;
36
37 let stego_config = stego_transport::StegoChannelConfig::default();
39 let stego_chan = stego_transport::StegoChannel::new(stego_config);
40 let stego_image = stego_chan
41 .encode(&env_bytes)
42 .map_err(|e| format!("Stego encode: {}", e))?;
43
44 let extracted = stego_chan
46 .decode(&stego_image)
47 .map_err(|e| format!("Stego decode: {}", e))?;
48 let extracted_env_bytes = &extracted[..env_bytes.len()];
49
50 let received_env = messaging::EncryptedEnvelope::from_bytes(extracted_env_bytes)
52 .map_err(|e| format!("Env deserialize: {}", e))?;
53 let received_msg = b_chan
54 .decrypt_message(&received_env)
55 .map_err(|e| format!("Decrypt: {}", e))?;
56
57 if received_msg.sender != alice_id {
59 return Err("Sender mismatch".into());
60 }
61
62 Ok(())
63}
64
65pub fn test_group_messaging_e2e() -> Result<(), String> {
67 let mut group_mgr = messaging::GroupManager::new();
68 let owner = PeerId::random();
69 let member1 = PeerId::random();
70 let member2 = PeerId::random();
71
72 let gid = group_mgr.create_group("test-e2e-group", owner);
74 group_mgr.join_group(&gid, member1);
75 group_mgr.join_group(&gid, member2);
76
77 let group = group_mgr.get_group(&gid).ok_or("Group not found")?;
79 if group.member_count() != 3 {
80 return Err(format!("Expected 3 members, got {}", group.member_count()));
81 }
82
83 let msg = messaging::Message::text(
85 owner,
86 messaging::MessageTarget::Group(gid),
87 "Hello group!",
88 );
89
90 let serialized = msg.to_bytes().map_err(|e| format!("Serialize: {}", e))?;
91 if serialized.is_empty() {
92 return Err("Empty serialized message".into());
93 }
94
95 Ok(())
96}
97
98pub fn test_offline_queue_delivery() -> Result<(), String> {
100 let alice_sk = crypto::SigningKey::generate();
101 let alice_id = PeerId::random();
102 let bob_sk = crypto::SigningKey::generate();
103 let bob_id = PeerId::random();
104 let alice_vk = alice_sk.verify_key();
105 let bob_vk = bob_sk.verify_key();
106
107 let (a_state, a_pub) = messaging::SecureChannel::initiate(alice_sk, alice_id);
108 let (b_state, b_pub) = messaging::SecureChannel::initiate(bob_sk, bob_id);
109 let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, bob_vk)
110 .map_err(|e| format!("Channel: {}", e))?;
111 let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, alice_vk)
112 .map_err(|e| format!("Channel: {}", e))?;
113
114 let mut queue = messaging::OfflineQueue::new();
116
117 for i in 0..10 {
118 let msg = messaging::Message::text(
119 alice_id,
120 messaging::MessageTarget::Direct(bob_id),
121 format!("Queued message #{}", i),
122 );
123 let env = a_chan
124 .encrypt_message(&msg)
125 .map_err(|e| format!("Encrypt: {}", e))?;
126 queue.enqueue(bob_id, env, messaging::QueuePriority::Normal);
127 }
128
129 if queue.count_for(&bob_id) != 10 {
130 return Err(format!(
131 "Expected 10 queued, got {}",
132 queue.count_for(&bob_id)
133 ));
134 }
135
136 let messages = queue.dequeue_for(&bob_id);
138 if messages.len() != 10 {
139 return Err(format!("Expected 10 dequeued, got {}", messages.len()));
140 }
141
142 for (i, qm) in messages.iter().enumerate() {
144 let decrypted = b_chan
145 .decrypt_message(&qm.envelope)
146 .map_err(|e| format!("Decrypt msg {}: {}", i, e))?;
147 if decrypted.sender != alice_id {
149 return Err(format!("Message {} sender mismatch", i));
150 }
151 }
152
153 Ok(())
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn test_e2e() {
162 test_full_e2e_flow().unwrap();
163 }
164
165 #[test]
166 fn test_group_e2e() {
167 test_group_messaging_e2e().unwrap();
168 }
169
170 #[test]
171 fn test_offline() {
172 test_offline_queue_delivery().unwrap();
173 }
174
175 #[test]
176 fn test_bidirectional_e2e() {
177 let a_sk = crypto::SigningKey::generate();
178 let a_id = PeerId::random();
179 let b_sk = crypto::SigningKey::generate();
180 let b_id = PeerId::random();
181 let a_vk = a_sk.verify_key();
182 let b_vk = b_sk.verify_key();
183
184 let (a_state, a_pub) = messaging::SecureChannel::initiate(a_sk, a_id);
185 let (b_state, b_pub) = messaging::SecureChannel::initiate(b_sk, b_id);
186 let a_chan = messaging::SecureChannel::complete(a_state, &b_pub, b_vk).unwrap();
187 let b_chan = messaging::SecureChannel::complete(b_state, &a_pub, a_vk).unwrap();
188
189 let msg1 = messaging::Message::text(a_id, messaging::MessageTarget::Direct(b_id), "Hello Bob");
191 let env1 = a_chan.encrypt_message(&msg1).unwrap();
192 let dec1 = b_chan.decrypt_message(&env1).unwrap();
193 assert_eq!(dec1.sender, a_id);
194
195 let msg2 = messaging::Message::text(b_id, messaging::MessageTarget::Direct(a_id), "Hello Alice");
197 let env2 = b_chan.encrypt_message(&msg2).unwrap();
198 let dec2 = a_chan.decrypt_message(&env2).unwrap();
199 assert_eq!(dec2.sender, b_id);
200 }
201}