2022-11-02 11:08:12 +00:00
|
|
|
// Copyright 2022 The ChromiumOS Authors
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
//! Testing vsock.
|
|
|
|
|
|
|
|
pub mod fixture;
|
|
|
|
|
|
|
|
use std::process::Command;
|
|
|
|
use std::process::Stdio;
|
|
|
|
use std::thread;
|
|
|
|
use std::time::Duration;
|
|
|
|
|
2022-11-08 02:22:07 +00:00
|
|
|
use rand::Rng;
|
|
|
|
|
2022-11-02 11:08:12 +00:00
|
|
|
use fixture::Config;
|
|
|
|
use fixture::TestVm;
|
|
|
|
|
|
|
|
const HOST_CID: u64 = 2;
|
|
|
|
const VSOCK_COM_PORT: u64 = 11111;
|
|
|
|
|
|
|
|
const SERVER_TIMEOUT_IN_SEC: u64 = 3;
|
|
|
|
const CLIENT_WAIT_DURATION: Duration = Duration::from_millis(1000);
|
|
|
|
|
|
|
|
const MESSAGE_TO_HOST: &str = "Connection from the host is successfully established";
|
|
|
|
const MESSAGE_TO_GUEST: &str = "Connection from the guest is successfully established";
|
|
|
|
|
2022-11-08 02:22:07 +00:00
|
|
|
// generate a random CID to avoid conflicts with other VMs run on different processes
|
|
|
|
fn generate_guest_cid() -> u32 {
|
|
|
|
// avoid special CIDs and negative values
|
|
|
|
rand::thread_rng().gen_range(3..0x8000_0000)
|
|
|
|
}
|
|
|
|
|
2022-11-02 11:08:12 +00:00
|
|
|
#[test]
|
|
|
|
fn host_to_guest_connection() {
|
2022-11-08 02:22:07 +00:00
|
|
|
let guest_cid = generate_guest_cid();
|
|
|
|
let config = Config::new().extra_args(vec!["--cid".to_string(), guest_cid.to_string()]);
|
2022-11-02 11:08:12 +00:00
|
|
|
let mut vm = TestVm::new(config).unwrap();
|
|
|
|
|
|
|
|
let handle_guest = thread::spawn(move || {
|
|
|
|
let cmd = format!(
|
|
|
|
"echo {MESSAGE_TO_HOST} | timeout {SERVER_TIMEOUT_IN_SEC}s ncat -l --vsock {VSOCK_COM_PORT}",
|
|
|
|
);
|
|
|
|
vm.exec_in_guest(&cmd).unwrap();
|
|
|
|
});
|
|
|
|
|
|
|
|
// wait until the server is ready
|
|
|
|
thread::sleep(CLIENT_WAIT_DURATION);
|
|
|
|
|
|
|
|
let output = Command::new("ncat")
|
|
|
|
.args(["--idle-timeout", "1"])
|
|
|
|
.args([
|
|
|
|
"--vsock",
|
2022-11-08 02:22:07 +00:00
|
|
|
&guest_cid.to_string(),
|
2022-11-02 11:08:12 +00:00
|
|
|
&VSOCK_COM_PORT.to_string(),
|
|
|
|
])
|
|
|
|
.output()
|
|
|
|
.expect("failed to execute process");
|
|
|
|
let host_stdout = std::str::from_utf8(&output.stdout).unwrap();
|
|
|
|
|
|
|
|
handle_guest.join().unwrap();
|
|
|
|
|
|
|
|
assert_eq!(host_stdout.trim(), MESSAGE_TO_HOST);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn guest_to_host_connection() {
|
2022-11-08 02:22:07 +00:00
|
|
|
let guest_cid = generate_guest_cid();
|
|
|
|
let config = Config::new().extra_args(vec!["--cid".to_string(), guest_cid.to_string()]);
|
2022-11-02 11:08:12 +00:00
|
|
|
let mut vm = TestVm::new(config).unwrap();
|
|
|
|
|
|
|
|
let echo = Command::new("echo")
|
|
|
|
.arg(MESSAGE_TO_GUEST)
|
|
|
|
.stdout(Stdio::piped())
|
|
|
|
.spawn()
|
|
|
|
.unwrap();
|
|
|
|
let mut handle_host = Command::new("timeout")
|
|
|
|
.arg(format!("{SERVER_TIMEOUT_IN_SEC}s"))
|
|
|
|
.arg("ncat")
|
|
|
|
.arg("-l")
|
|
|
|
.args(["--vsock", &VSOCK_COM_PORT.to_string()])
|
|
|
|
.stdin(echo.stdout.unwrap())
|
|
|
|
.spawn()
|
|
|
|
.expect("failed to execute process");
|
|
|
|
|
|
|
|
// wait until the server is ready
|
|
|
|
thread::sleep(CLIENT_WAIT_DURATION);
|
|
|
|
|
|
|
|
let cmd = format!("ncat --idle-timeout 1 --vsock {HOST_CID} {VSOCK_COM_PORT}");
|
|
|
|
let guest_stdout = vm.exec_in_guest(&cmd).unwrap();
|
|
|
|
|
|
|
|
handle_host.wait().unwrap();
|
|
|
|
|
|
|
|
assert_eq!(guest_stdout.trim(), MESSAGE_TO_GUEST);
|
|
|
|
}
|