diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-11-03 10:08:35 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-11-03 10:08:35 +0100 |
| commit | ab3c9645794756a1897aea7201fdd2e106c393c9 (patch) | |
| tree | 3884a37a52b305d481fb04a7af7d6e71157d6baf | |
| parent | d99ba914324849cc5c161980e1a488bc64f41163 (diff) | |
| parent | ce63939ce1a5aa1dbb2dc86c17431c9a56519742 (diff) | |
| download | mullvadvpn-ab3c9645794756a1897aea7201fdd2e106c393c9.tar.xz mullvadvpn-ab3c9645794756a1897aea7201fdd2e106c393c9.zip | |
Merge branch 'general-test-framework-touchups'
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | test/README.md | 10 | ||||
| -rw-r--r-- | test/test-manager/src/container.rs | 4 | ||||
| -rw-r--r-- | test/test-manager/src/vm/network/linux.rs | 35 | ||||
| -rw-r--r-- | test/test-manager/src/vm/provision.rs | 6 | ||||
| -rw-r--r-- | test/test-runner/src/package.rs | 18 |
6 files changed, 47 insertions, 28 deletions
@@ -174,7 +174,7 @@ See [this](Release.md) for instructions on how to make a new release. (macOS only). * `TALPID_FORCE_USERSPACE_WIREGUARD` - Forces the daemon to use the userspace implementation of - WireGuard on Linux. + WireGuard. * `TALPID_DISABLE_OFFLINE_MONITOR` - Forces the daemon to always assume the host is online. diff --git a/test/README.md b/test/README.md index 66ba136ddf..fea575425f 100644 --- a/test/README.md +++ b/test/README.md @@ -54,6 +54,7 @@ This lets us monitor traffic on network interfaces without root access. For running tests on Linux and Windows guests, you will need these tools and libraries: +#### Fedora ```bash dnf install git gcc protobuf-devel libpcap-devel qemu \ podman golang-github-rootless-containers-rootlesskit slirp4netns dnsmasq \ @@ -61,6 +62,15 @@ dnf install git gcc protobuf-devel libpcap-devel qemu \ wireguard-tools ``` + +#### Debian / Ubuntu +```bash +apt install qemu-utils qemu-system-x86 libpcap-dev slirp4netns rootlesskit dnsmasq nftables +``` + +##### Note for Debian +By default `sysctl` is only invokable by root. + ## Setting up testing environment First you need to build the images for running tests on, see [`BUILD_OS_IMAGE.md`](./docs/BUILD_OS_IMAGE.md). The `test-manager` then needs to be configured to use the image. diff --git a/test/test-manager/src/container.rs b/test/test-manager/src/container.rs index 9560f48b3e..a4ab6725d9 100644 --- a/test/test-manager/src/container.rs +++ b/test/test-manager/src/container.rs @@ -1,12 +1,14 @@ #![cfg(target_os = "linux")] +use nix::unistd::geteuid; use tokio::process::Command; /// Re-launch self with rootlesskit if we're not root. /// Allows for rootless and containerized networking. /// The VNC port is published to localhost. pub async fn relaunch_with_rootlesskit(vnc_port: Option<u16>) { - if unsafe { libc::geteuid() } == 0 { + // check if user is root (`man getuid`). + if geteuid().is_root() { return; } diff --git a/test/test-manager/src/vm/network/linux.rs b/test/test-manager/src/vm/network/linux.rs index b6df187dcc..d6f12df6b0 100644 --- a/test/test-manager/src/vm/network/linux.rs +++ b/test/test-manager/src/vm/network/linux.rs @@ -219,7 +219,8 @@ impl NetworkHandle { /// dnsmasq will serve IPv4 addresses within the range [TEST_SUBNET_IPV4_DHCP] using regular DHCP. /// It will also advertise SLAAC for IPv6 within [TEST_SUBNET_IPV6]. async fn start_dnsmasq() -> Result<DhcpProcHandle> { - let mut cmd = Command::new("dnsmasq"); + let dnsmasq = "/usr/sbin/dnsmasq"; + let mut cmd = Command::new(dnsmasq); cmd.kill_on_drop(true); cmd.stdout(Stdio::piped()); @@ -350,11 +351,9 @@ where } pub async fn run_nft(input: &str) -> Result<()> { - let mut cmd = Command::new("nft"); - cmd.args(["-f", "-"]); - - cmd.stdin(Stdio::piped()); - + let nft = "/usr/sbin/nft"; + let mut cmd = Command::new(nft); + cmd.args(["-f", "-"]).stdin(Stdio::piped()); let mut child = cmd.spawn().map_err(Error::NftStart)?; let mut stdin = child.stdin.take().unwrap(); @@ -373,19 +372,15 @@ pub async fn run_nft(input: &str) -> Result<()> { } async fn enable_forwarding() -> Result<()> { - let mut cmd = Command::new("sysctl"); - cmd.arg("net.ipv4.ip_forward=1"); - let output = cmd.output().await.map_err(Error::SysctlStart)?; - if !output.status.success() { - return Err(Error::SysctlFailed(output.status.code().unwrap())); - } - - let mut cmd = Command::new("sysctl"); - cmd.arg("net.ipv6.conf.all.forwarding=1"); - let output = cmd.output().await.map_err(Error::SysctlStart)?; - if !output.status.success() { - return Err(Error::SysctlFailed(output.status.code().unwrap())); - } - + let sysctl = "/usr/sbin/sysctl"; + let run = async |cmd: &mut Command| { + let exit_status = cmd.output().await.map_err(Error::SysctlStart)?.status; + match exit_status.success() { + true => Ok(()), + false => Err(Error::SysctlFailed(exit_status.code().unwrap())), + } + }; + run(Command::new(sysctl).arg("net.ipv4.ip_forward=1")).await?; + run(Command::new(sysctl).arg("net.ipv6.conf.all.forwarding=1")).await?; Ok(()) } diff --git a/test/test-manager/src/vm/provision.rs b/test/test-manager/src/vm/provision.rs index 818393cd33..32953230e5 100644 --- a/test/test-manager/src/vm/provision.rs +++ b/test/test-manager/src/vm/provision.rs @@ -114,7 +114,11 @@ fn blocking_ssh( OsType::Macos | OsType::Linux => r"/tmp/", }; - let stream = TcpStream::connect(SocketAddr::new(guest_ip, 22)).context("TCP connect failed")?; + let stream = { + let ssh = SocketAddr::new(guest_ip, 22); + log::debug!("Connecting to {user}@{ssh} over ssh"); + TcpStream::connect(ssh).context("TCP connect failed")? + }; let mut session = Session::new().context("Failed to connect to SSH server")?; session.set_tcp_stream(stream); diff --git a/test/test-runner/src/package.rs b/test/test-runner/src/package.rs index 5cc0b92dab..8ab3bc6d5e 100644 --- a/test/test-runner/src/package.rs +++ b/test/test-runner/src/package.rs @@ -14,6 +14,8 @@ pub async fn uninstall_app(env: HashMap<String, String>) -> Result<()> { uninstall_apt("mullvad-vpn", env, true).await } Distribution::Fedora => uninstall_rpm("mullvad-vpn", env).await, + // FIXME: Do not assume that it is Debian/Ubuntu-based. + Distribution::Unofficial { name: _ } => uninstall_apt("mullvad-vpn", env, true).await, } } @@ -105,6 +107,8 @@ pub async fn install_package(package: Package) -> Result<()> { match get_distribution()? { Distribution::Debian | Distribution::Ubuntu => install_apt(&package.path).await, Distribution::Fedora => install_rpm(&package.path).await, + // FIXME: Do not assume that it is Debian/Ubuntu-based. + Distribution::Unofficial { name: _ } => install_apt(&package.path).await, } } @@ -263,26 +267,30 @@ async fn install_nsis_exe(path: &Path) -> Result<()> { } #[cfg(target_os = "linux")] +#[allow(unused)] enum Distribution { Debian, Ubuntu, Fedora, + // Not an officially supported Linux distro. + Unofficial { name: String }, } #[cfg(target_os = "linux")] fn get_distribution() -> Result<Distribution> { let os_release = rs_release::get_os_release().map_err(|_error| Error::UnknownOs("unknown".to_string()))?; - match os_release + let id = os_release .get("id") .or(os_release.get("ID")) - .ok_or(Error::UnknownOs("unknown".to_string()))? - .as_str() - { + .ok_or(Error::UnknownOs("unknown".to_string()))?; + match id.as_str() { "debian" => Ok(Distribution::Debian), "ubuntu" => Ok(Distribution::Ubuntu), "fedora" => Ok(Distribution::Fedora), - os => Err(Error::UnknownOs(os.to_string())), + other => Ok(Distribution::Unofficial { + name: other.to_string(), + }), } } |
