diff --git a/e2e_tests/tests/vsock.rs b/e2e_tests/tests/vsock.rs new file mode 100644 index 0000000000..0de0488eb4 --- /dev/null +++ b/e2e_tests/tests/vsock.rs @@ -0,0 +1,86 @@ +// 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; + +use fixture::Config; +use fixture::TestVm; + +const HOST_CID: u64 = 2; +const GUEST_CID: u64 = 5; +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"; + +#[test] +fn host_to_guest_connection() { + let config = Config::new().extra_args(vec!["--cid".to_string(), GUEST_CID.to_string()]); + 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", + &GUEST_CID.to_string(), + &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() { + let config = Config::new().extra_args(vec!["--cid".to_string(), GUEST_CID.to_string()]); + 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); +}