From 0bb3c4b2bfccd19034798eb252e8cdd13471b814 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 26 Sep 2025 17:27:15 +0200 Subject: [PATCH] remove clunky old examples in place of unit tests --- smolmix/README.md | 12 +- smolmix/examples/check.rs | 65 ----------- smolmix/examples/download_file.rs | 186 ------------------------------ 3 files changed, 1 insertion(+), 262 deletions(-) delete mode 100644 smolmix/examples/check.rs delete mode 100644 smolmix/examples/download_file.rs diff --git a/smolmix/README.md b/smolmix/README.md index f02cf9d817..21e4d603bb 100644 --- a/smolmix/README.md +++ b/smolmix/README.md @@ -1,13 +1,3 @@ # smolmix poc -At the moment this is very basic but it works with smol files (large ones end up borking at the moment). - -```sh -cargo run --example download -``` - -There is a quick check for httpbin's IPs via `nslookup` and connectivity **not** using the Mixnet: - -```sh -cargo run --example check -``` +Test TLS conn + smol HTTPS req/res with `cargo test`. More to come. diff --git a/smolmix/examples/check.rs b/smolmix/examples/check.rs deleted file mode 100644 index 2979709089..0000000000 --- a/smolmix/examples/check.rs +++ /dev/null @@ -1,65 +0,0 @@ -use reqwest; -use std::{ - io::{Read, Write}, - net::TcpStream, - process::Command, -}; - -// These are just for checking: -// - Using the proper IP info in the other tests -// - That network connection is fine otherwise outside of the `NymIprDevice` -#[tokio::main] -async fn main() -> Result<(), Box> { - println!("Testing connectivity to httpbin.org...\n"); - - println!("DNS Resolution:"); - let output = Command::new("nslookup") - .arg("httpbin.org") - .output() - .expect("Failed to execute nslookup"); - println!("{}", String::from_utf8_lossy(&output.stdout)); - - println!("\nHTTP GET request:"); - match reqwest::get("http://httpbin.org/get").await { - Ok(response) => { - println!("Status: {}", response.status()); - println!("Headers: {:#?}", response.headers()); - let body = response.text().await?; - println!("Body:\n{}", body); - } - Err(e) => { - println!("Request failed: {}", e); - } - } - - println!("\nRaw TCP connection test:"); - - match TcpStream::connect("httpbin.org:80") { - Ok(mut stream) => { - println!("Connected to httpbin.org:80"); - - let request = b"GET /get HTTP/1.1\r\n\ - Host: httpbin.org\r\n\ - User-Agent: test/1.0\r\n\ - Accept: */*\r\n\ - Connection: close\r\n\ - \r\n"; - - stream.write_all(request)?; - println!("Sent request"); - - let mut response = Vec::new(); - stream.read_to_end(&mut response)?; - println!( - "Response ({} bytes):\n{}", - response.len(), - String::from_utf8_lossy(&response[..500.min(response.len())]) - ); - } - Err(e) => { - println!("Connection failed: {}", e); - } - } - - Ok(()) -} diff --git a/smolmix/examples/download_file.rs b/smolmix/examples/download_file.rs deleted file mode 100644 index 08d8f91578..0000000000 --- a/smolmix/examples/download_file.rs +++ /dev/null @@ -1,186 +0,0 @@ -use nym_sdk::stream_wrapper::IpMixStream; -use smolmix::create_device; -use smoltcp::{ - iface::{Config, Interface, SocketSet}, - socket::tcp, - time::Instant, - wire::{HardwareAddress, IpAddress, IpCidr, Ipv4Address}, -}; -use std::{ - fs::{self, File}, - io::Write, - path::PathBuf, - time::Duration, -}; -use tracing::info; - -#[tokio::main] -async fn main() -> Result<(), Box> { - nym_bin_common::logging::setup_tracing_logger(); - - let download_dir = dirs::home_dir() - .unwrap_or_else(|| PathBuf::from(".")) - .join("Downloads") - .join("nym-test"); - - fs::create_dir_all(&download_dir)?; - let file_path = download_dir.join("1Mb.dat"); - info!("Will save to: {}", file_path.display()); - - info!("Connecting to Mixnet..."); - let ipr_stream = IpMixStream::new().await?; - let (mut device, bridge, allocated_ips) = create_device(ipr_stream).await?; - - info!("Allocated IP: {}", allocated_ips.ipv4); - - // Bridge has to be run in its own task as per its docs - tokio::spawn(async move { - if let Err(e) = bridge.run().await { - eprintln!("Bridge error: {}", e); - } - }); - - // Create smoltcp interface using our allocated IP - let config = Config::new(HardwareAddress::Ip); - let mut iface = Interface::new(config, &mut device, Instant::now()); - - // Configure with our allocated IP TODO can probably smush this + fn above into one / somewhere else so doesn't have to be done manually - iface.update_ip_addrs(|ip_addrs| { - ip_addrs - .push(IpCidr::new(IpAddress::from(allocated_ips.ipv4), 32)) - .unwrap(); - }); - - // Add default route - iface - .routes_mut() - .add_default_ipv4_route(Ipv4Address::UNSPECIFIED) - .unwrap(); - - let tcp_rx_buffer = tcp::SocketBuffer::new(vec![0; 65536]); - let tcp_tx_buffer = tcp::SocketBuffer::new(vec![0; 4096]); - let tcp_socket = tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer); - - let mut sockets = SocketSet::new(vec![]); - let tcp_handle = sockets.add(tcp_socket); - - let target_ip = Ipv4Address::new(3, 213, 24, 5); // httpbin.org IP - if you're getting a mangled response run check.rs and make sure you're using the correct IP - let remote_path = "/bytes/10240"; // 10KB - let target_port = 80; - let expected_size = 10240; - - info!("Downloading {}:{}{}", target_ip, target_port, remote_path); - - let mut file = File::create(&file_path)?; - let mut connected = false; - let mut request_sent = false; - let mut total_bytes = 0; - let mut body_bytes = 0; - let mut headers_complete = false; - let mut header_buffer = Vec::new(); - let mut timestamp = Instant::from_millis(0); - let start = tokio::time::Instant::now(); - - while start.elapsed() < Duration::from_secs(300) { - iface.poll(timestamp, &mut device, &mut sockets); - - let socket = sockets.get_mut::(tcp_handle); - - if !connected && !socket.is_open() { - // iface is the hook into the NymIpDevice - socket.connect(iface.context(), (target_ip, target_port), 49152)?; - info!("Connecting..."); - connected = true; - } - - if socket.state() == tcp::State::Established && !request_sent { - let http_request = format!( - "GET {} HTTP/1.1\r\n\ - Host: httpbin.org\r\n\ - User-Agent: smolmix/0.1\r\n\ - Connection: close\r\n\ - \r\n", - remote_path - ); - - socket.send_slice(http_request.as_bytes())?; - info!("Request sent"); - request_sent = true; - } - - if socket.can_recv() { - socket.recv(|buffer| { - let len = buffer.len(); - total_bytes += len; - - if !headers_complete { - header_buffer.extend_from_slice(buffer); - - // Check for end of headers - if let Ok(headers_str) = std::str::from_utf8(&header_buffer) { - if let Some(header_end) = headers_str.find("\r\n\r\n") { - headers_complete = true; - - // Write body portion to file - let body_start = header_end + 4; - if body_start < header_buffer.len() { - let body_chunk = &header_buffer[body_start..]; - file.write_all(body_chunk).unwrap(); - body_bytes = body_chunk.len(); - info!("Headers complete, writing body to file"); - } - } - } - } else { - // Headers done, write body directly to file - file.write_all(buffer).unwrap(); - body_bytes += len; - } - - // Progress update - if body_bytes > 0 && body_bytes % 10240 < len { - let progress = (body_bytes as f64 / expected_size as f64) * 100.0; - let elapsed = start.elapsed().as_secs_f64(); - let throughput = (body_bytes as f64 / elapsed) / 1024.0; - - info!( - "Progress: {:.1}% ({} / {} bytes) - {:.1} KB/s", - progress, body_bytes, expected_size, throughput - ); - } - - (len, ()) - })?; - } - - // Check completion - if body_bytes >= expected_size || (socket.state() == tcp::State::Closed && body_bytes > 0) { - break; - } - - timestamp += smoltcp::time::Duration::from_millis(10); - tokio::time::sleep(Duration::from_millis(10)).await; - } - - // Ensure file is flushed - file.flush()?; - - // Final report - let elapsed = start.elapsed().as_secs_f64(); - let throughput = (body_bytes as f64 / elapsed) / 1024.0; - - info!("\nDownload Complete!"); - info!("Saved to: {}", file_path.display()); - info!("File size: {} bytes", body_bytes); - info!("Total time: {:.1} seconds", elapsed); - info!("Average speed: {:.1} KB/s", throughput); - - // Verify file - let metadata = fs::metadata(&file_path)?; - info!("File on disk: {} bytes", metadata.len()); - info!("Success: {}", metadata.len() as usize == expected_size); - - // TODO make a graceful shutdown fn for Device -> IprWrapper - - Ok(()) -}