blob: ec2cc767005401e9353f812a2cd015fcf5af0500 [file] [edit]
//@ignore-target: windows # No libc socket on Windows
//@compile-flags: -Zmiri-disable-isolation
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
const TEST_BYTES: &[u8] = b"these are some test bytes!";
fn main() {
test_create_ipv4_listener();
test_create_ipv6_listener();
test_accept_and_connect();
test_read_write();
test_peek();
test_peer_addr();
}
fn test_create_ipv4_listener() {
let _listener_ipv4 = TcpListener::bind("127.0.0.1:0").unwrap();
}
fn test_create_ipv6_listener() {
let _listener_ipv6 = TcpListener::bind("[::1]:0").unwrap();
}
/// Try to connect to a TCP listener running in a separate thread and
/// accepting connections.
fn test_accept_and_connect() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
// Get local address with randomized port to know where
// we need to connect to.
let address = listener.local_addr().unwrap();
let handle = thread::spawn(move || {
let (_stream, _addr) = listener.accept().unwrap();
});
let _stream = TcpStream::connect(address).unwrap();
handle.join().unwrap();
}
/// Test reading and writing into two connected sockets and ensuring
/// that the other side receives the correct bytes.
fn test_read_write() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
// Get local address with randomized port to know where
// we need to connect to.
let address = listener.local_addr().unwrap();
let handle = thread::spawn(move || {
let (mut stream, _addr) = listener.accept().unwrap();
stream.write_all(TEST_BYTES).unwrap();
});
let mut stream = TcpStream::connect(address).unwrap();
let mut buffer = [0; TEST_BYTES.len()];
stream.read_exact(&mut buffer).unwrap();
assert_eq!(&buffer, TEST_BYTES);
handle.join().unwrap();
}
/// Test that peeking on a receiving socket doesn't remove the bytes
/// from the queue.
fn test_peek() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
// Get local address with randomized port to know where
// we need to connect to.
let address = listener.local_addr().unwrap();
let handle = thread::spawn(move || {
let (mut stream, _addr) = listener.accept().unwrap();
stream.write_all(TEST_BYTES).unwrap();
});
let mut stream = TcpStream::connect(address).unwrap();
let mut buffer = [0; TEST_BYTES.len()];
let bytes_peeked = stream.peek(&mut buffer).unwrap();
// Since we have short accesses, and there is nothing like an "peek exact",
// we can only ensure that we peeked at most as many bytes as we wrote into
// the buffer and that the peeked bytes match the ones we wrote.
assert!(bytes_peeked <= TEST_BYTES.len());
assert_eq!(&buffer[0..bytes_peeked], &TEST_BYTES[0..bytes_peeked]);
// Since the peek shouldn't remove the bytes from the queue,
// we should be able to read them again.
let mut buffer = [0; TEST_BYTES.len()];
stream.read_exact(&mut buffer).unwrap();
assert_eq!(&buffer, TEST_BYTES);
handle.join().unwrap();
}
/// Test whether the [`TcpStream::peer_addr`] of a connected socket
/// is the same address as the one the stream was connected to.
fn test_peer_addr() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
// Get local address with randomized port to know where
// we need to connect to.
let address = listener.local_addr().unwrap();
let handle = thread::spawn(move || {
let (_stream, _addr) = listener.accept().unwrap();
});
let stream = TcpStream::connect(address).unwrap();
let peer_addr = stream.peer_addr().unwrap();
assert_eq!(address, peer_addr);
handle.join().unwrap();
}