Skip to content

Commit 661f18e

Browse files
mtjhrcslp
authored andcommitted
tests: Add test where guest process connects to host using TCP (vsock)
Signed-off-by: Matej Hrica <[email protected]>
1 parent 1075947 commit 661f18e

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

tests/test_cases/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use test_vm_config::TestVmConfig;
44
mod test_vsock_guest_connect;
55
use test_vsock_guest_connect::TestVsockGuestConnect;
66

7+
mod test_tsi_tcp_guest_connect;
8+
use test_tsi_tcp_guest_connect::TestTsiTcpGuestConnect;
9+
710
pub fn test_cases() -> Vec<TestCase> {
811
// Register your test here:
912
vec![
@@ -22,6 +25,7 @@ pub fn test_cases() -> Vec<TestCase> {
2225
}),
2326
),
2427
TestCase::new("vsock-guest-connect", Box::new(TestVsockGuestConnect)),
28+
TestCase::new("tsi-tcp-guest-connect", Box::new(TestTsiTcpGuestConnect::new())),
2529
]
2630
}
2731

@@ -42,6 +46,7 @@ mod common;
4246

4347
#[cfg(feature = "host")]
4448
mod krun;
49+
mod tcp_tester;
4550

4651
#[host]
4752
#[derive(Clone, Debug)]

tests/test_cases/src/tcp_tester.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use std::io::{ErrorKind, Read, Write};
2+
use std::mem;
3+
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, TcpStream};
4+
use std::time::Duration;
5+
6+
fn expect_msg(stream: &mut TcpStream, expected: &[u8]) {
7+
let mut buf = vec![0; expected.len()];
8+
stream.read_exact(&mut buf[..]).unwrap();
9+
assert_eq!(&buf[..], expected);
10+
}
11+
12+
fn expect_wouldblock(stream: &mut TcpStream) {
13+
stream.set_nonblocking(true).unwrap();
14+
let err = stream.read(&mut [0u8; 1]).unwrap_err();
15+
stream.set_nonblocking(false).unwrap();
16+
assert_eq!(err.kind(), ErrorKind::WouldBlock);
17+
}
18+
19+
fn set_timeouts(stream: &mut TcpStream) {
20+
stream
21+
.set_read_timeout(Some(Duration::from_millis(500)))
22+
.unwrap();
23+
stream
24+
.set_write_timeout(Some(Duration::from_millis(500)))
25+
.unwrap();
26+
}
27+
28+
#[derive(Debug, Copy, Clone)]
29+
pub struct TcpTester {
30+
port: u16,
31+
}
32+
33+
impl TcpTester {
34+
pub const fn new(port: u16) -> Self {
35+
Self { port }
36+
}
37+
38+
pub fn create_server_socket(&self) -> TcpListener {
39+
TcpListener::bind(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), self.port)).unwrap()
40+
}
41+
42+
pub fn run_server(&self, listener: TcpListener) {
43+
let (mut stream, _addr) = listener.accept().unwrap();
44+
set_timeouts(&mut stream);
45+
stream.write_all(b"ping!").unwrap();
46+
expect_msg(&mut stream, b"pong!");
47+
expect_wouldblock(&mut stream);
48+
stream.write_all(b"bye!").unwrap();
49+
// We leak the file descriptor for now, since there is no easy way to close it on libkrun exit
50+
mem::forget(listener);
51+
}
52+
53+
pub fn run_client(&self) {
54+
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), self.port);
55+
let mut stream = TcpStream::connect(&addr).unwrap();
56+
set_timeouts(&mut stream);
57+
expect_msg(&mut stream, b"ping!");
58+
expect_wouldblock(&mut stream);
59+
stream.write_all(b"pong!").unwrap();
60+
expect_msg(&mut stream, b"bye!");
61+
}
62+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::tcp_tester::TcpTester;
2+
use macros::{guest, host};
3+
4+
const PORT: u16 = 8000;
5+
6+
pub struct TestTsiTcpGuestConnect {
7+
tcp_tester: TcpTester,
8+
}
9+
10+
impl TestTsiTcpGuestConnect {
11+
pub fn new() -> TestTsiTcpGuestConnect {
12+
Self {
13+
tcp_tester: TcpTester::new(PORT),
14+
}
15+
}
16+
}
17+
18+
#[host]
19+
mod host {
20+
use super::*;
21+
22+
use crate::common::setup_fs_and_enter;
23+
use crate::{krun_call, krun_call_u32};
24+
use crate::{Test, TestSetup};
25+
use krun_sys::*;
26+
use std::thread;
27+
28+
impl Test for TestTsiTcpGuestConnect {
29+
fn start_vm(self: Box<Self>, test_setup: TestSetup) -> anyhow::Result<()> {
30+
let listener = self.tcp_tester.create_server_socket();
31+
thread::spawn(move || self.tcp_tester.run_server(listener));
32+
unsafe {
33+
let ctx = krun_call_u32!(krun_create_ctx())?;
34+
krun_call!(krun_set_vm_config(ctx, 1, 512))?;
35+
setup_fs_and_enter(ctx, test_setup)?;
36+
}
37+
Ok(())
38+
}
39+
}
40+
}
41+
42+
#[guest]
43+
mod guest {
44+
use super::*;
45+
use crate::Test;
46+
47+
impl Test for TestTsiTcpGuestConnect {
48+
fn in_guest(self: Box<Self>) {
49+
self.tcp_tester.run_client();
50+
println!("OK");
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)