roughenough_integration_test/
lib.rs1#![forbid(unsafe_code)]
2
3mod load_gen;
4
5#[cfg(test)]
6mod integration_tests {
7 use std::net::SocketAddr;
16
17 use roughenough_client::validation::ResponseValidator;
18 use roughenough_protocol::cursor::ParseCursor;
19 use roughenough_protocol::request::Request;
20 use roughenough_protocol::response::Response;
21 use roughenough_protocol::tags::{Nonce, PublicKey};
22 use roughenough_protocol::wire::{FromWire, ToWire};
23 use roughenough_server::test_utils::TestContext;
24
25 fn validate_response(
28 request_bytes: &[u8],
29 response_bytes: &[u8],
30 pub_key: PublicKey,
31 ) -> Result<(), Box<dyn std::error::Error>> {
32 assert!(response_bytes.starts_with(b"ROUGHTIM"));
33 let mut buf = response_bytes[12..].to_vec();
35 let mut cursor = ParseCursor::new(&mut buf);
36 let response = Response::from_wire(&mut cursor)?;
37
38 let validator = ResponseValidator::new_with_key(pub_key);
39 validator.validate(request_bytes, &response)?;
40 Ok(())
41 }
42
43 fn create_test_request(nonce_byte: u8) -> Request {
45 let nonce = Nonce::from([nonce_byte; 32]);
46 Request::new(&nonce)
47 }
48
49 #[test]
53 fn single_request_validation() {
54 let mut test_context = TestContext::new(64);
55 let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
56
57 let request = create_test_request(42);
58 let request_bytes = request.as_bytes().unwrap();
59 test_context
60 .response_handler
61 .add_request(&request_bytes, request, addr);
62
63 let mut responses = Vec::new();
64 test_context
65 .response_handler
66 .process_responses(|addr, bytes| {
67 responses.push((addr, bytes.to_vec()));
68 });
69
70 assert_eq!(responses.len(), 1);
71 let (response_addr, response_bytes) = &responses[0];
72 assert_eq!(*response_addr, addr);
73
74 let pub_key = test_context.key_source.public_key();
75
76 validate_response(&request_bytes, response_bytes, pub_key).unwrap();
77 }
78
79 #[test]
82 fn large_batch_validation() {
83 let num_requests = 64;
84
85 let mut test_context = TestContext::new(num_requests as u8);
86
87 let mut request_data = Vec::new();
88
89 for i in 0..num_requests {
90 let addr: SocketAddr = format!("127.0.0.1:{}", 8000 + i).parse().unwrap();
91 let request = create_test_request((i * 37) as u8);
92 let request_bytes = request.as_bytes().unwrap();
93
94 request_data.push((request_bytes.clone(), addr));
95 test_context
96 .response_handler
97 .add_request(&request_bytes, request, addr);
98 }
99
100 let mut responses = Vec::new();
101 test_context
102 .response_handler
103 .process_responses(|addr, bytes| {
104 responses.push((addr, bytes.to_vec()));
105 });
106
107 assert_eq!(responses.len(), num_requests);
108
109 for (idx, (response_addr, response_bytes)) in responses.iter().enumerate() {
110 let expected_addr = format!("127.0.0.1:{}", 8000 + idx)
111 .parse::<SocketAddr>()
112 .unwrap();
113 assert_eq!(*response_addr, expected_addr);
114
115 let (request_bytes, _) = &request_data[idx];
116 let public_key = test_context.key_source.public_key();
117
118 match validate_response(request_bytes, response_bytes, public_key) {
119 Ok(_) => {} Err(e) => {
121 println!("Response {idx} validation failed: {e}");
122
123 let mut buf = response_bytes[12..].to_vec();
124 let mut cursor = ParseCursor::new(&mut buf);
125 let response = Response::from_wire(&mut cursor).unwrap();
126
127 println!("Debug info for failed validation:");
128 println!(" Request bytes length: {}", request_bytes.len());
129 println!(" Response index: {}", response.indx());
130 println!(" Response path length: {}", response.path().as_ref().len());
131 println!(
132 " Server root: {}",
133 data_encoding::HEXLOWER.encode(response.srep().root().as_ref())
134 );
135
136 let tree = roughenough_merkle::MerkleTree::new();
138 let computed_root = tree.root_from_paths(
139 response.indx() as usize,
140 request_bytes,
141 response.path(),
142 );
143 println!(
144 " Client computed: {}",
145 data_encoding::HEXLOWER.encode(&computed_root)
146 );
147
148 panic!("Validation failed for response {idx}: {e}");
149 }
150 }
151 }
152 }
153}