diff --git a/test/README.md b/test/README.md index d9381e2e62ed..c29cb51c9412 100644 --- a/test/README.md +++ b/test/README.md @@ -53,7 +53,7 @@ For running tests on Linux and Windows guests, you will need these tools and lib ```bash dnf install git gcc protobuf-devel libpcap-devel qemu \ - podman e2tools mingw64-gcc mingw64-winpthreads-static mtools \ + podman mingw64-gcc mingw64-winpthreads-static mtools \ golang-github-rootless-containers-rootlesskit slirp4netns dnsmasq \ dbus-devel pkgconf-pkg-config swtpm edk2-ovmf \ wireguard-tools @@ -110,8 +110,7 @@ Here is an example of how to create a new OS configuration and then run all test # The image is assumed to contain a test runner service set up as described in ./docs/BUILD_OS_IMAGE.md cargo run --bin test-manager set debian11 qemu ./os-images/debian11.qcow2 linux \ --package-type deb --architecture x64 \ - --artifacts-dir /opt/testing \ - --disks ./testrunner-images/linux-test-runner.img + --provisioner ssh --ssh-user test --ssh-password test # Try it out to see if it works cargo run --bin test-manager run-vm debian11 diff --git a/test/build.sh b/test/build.sh index 133120e6f7af..2a8f7c7063fa 100755 --- a/test/build.sh +++ b/test/build.sh @@ -22,7 +22,7 @@ else cargo build --bin test-runner --release --target "${TARGET}" fi -# Don't build a runner image for macOS. -if [[ $TARGET != aarch64-apple-darwin ]]; then +# Only build runner image for Windows +if [[ $TARGET == x86_64-pc-windows-gnu ]]; then ./scripts/build-runner-image.sh fi diff --git a/test/scripts/build-runner-image.sh b/test/scripts/build-runner-image.sh index 6881e0c7f924..fe8077b33777 100755 --- a/test/scripts/build-runner-image.sh +++ b/test/scripts/build-runner-image.sh @@ -7,9 +7,6 @@ set -eu TEST_RUNNER_IMAGE_SIZE_MB=1000 case $TARGET in - "x86_64-unknown-linux-gnu") - TEST_RUNNER_IMAGE_FILENAME=linux-test-runner.img - ;; "x86_64-pc-windows-gnu") TEST_RUNNER_IMAGE_FILENAME=windows-test-runner.img ;; @@ -30,22 +27,6 @@ TEST_RUNNER_IMAGE_PATH="${SCRIPT_DIR}/../testrunner-images/${TEST_RUNNER_IMAGE_F case $TARGET in - "x86_64-unknown-linux-gnu") - truncate -s "${TEST_RUNNER_IMAGE_SIZE_MB}M" "${TEST_RUNNER_IMAGE_PATH}" - mkfs.ext4 -F "${TEST_RUNNER_IMAGE_PATH}" - e2cp \ - -P 500 \ - "${SCRIPT_DIR}/../target/$TARGET/release/test-runner" \ - "${PACKAGES_DIR}/"app-e2e-* \ - "${TEST_RUNNER_IMAGE_PATH}:/" - e2cp "${PACKAGES_DIR}/"*.deb \ - "${TEST_RUNNER_IMAGE_PATH}:/" || true - e2cp "${PACKAGES_DIR}/"*.rpm \ - "${TEST_RUNNER_IMAGE_PATH}:/" || true - e2cp "${SCRIPT_DIR}/../openvpn.ca.crt" \ - "${TEST_RUNNER_IMAGE_PATH}:/" - ;; - "x86_64-pc-windows-gnu") truncate -s "${TEST_RUNNER_IMAGE_SIZE_MB}M" "${TEST_RUNNER_IMAGE_PATH}" mformat -F -i "${TEST_RUNNER_IMAGE_PATH}" "::" diff --git a/test/scripts/ssh-setup.sh b/test/scripts/ssh-setup.sh index bfe0b66f12c7..9ab1d895f566 100644 --- a/test/scripts/ssh-setup.sh +++ b/test/scripts/ssh-setup.sh @@ -105,9 +105,15 @@ fi setup_systemd +function install_packages_apt { + apt update + apt install -yf xvfb wireguard-tools curl + curl -fsSL https://get.docker.com | sh +} + # Install required packages if which apt &>/dev/null; then - apt install -f xvfb wireguard-tools + install_packages_apt elif which dnf &>/dev/null; then - dnf install -y xorg-x11-server-Xvfb wireguard-tools + dnf install -y xorg-x11-server-Xvfb wireguard-tools podman fi diff --git a/test/test-manager/src/tests/mod.rs b/test/test-manager/src/tests/mod.rs index ee8b7038fe32..08251eb27b08 100644 --- a/test/test-manager/src/tests/mod.rs +++ b/test/test-manager/src/tests/mod.rs @@ -4,6 +4,7 @@ mod dns; mod helpers; mod install; mod settings; +mod software; mod test_metadata; mod tunnel; mod tunnel_state; diff --git a/test/test-manager/src/tests/software.rs b/test/test-manager/src/tests/software.rs new file mode 100644 index 000000000000..1c52f5032f6a --- /dev/null +++ b/test/test-manager/src/tests/software.rs @@ -0,0 +1,67 @@ +//! Tests of interoperability with other software + +use super::{helpers, Error, TestContext}; +use mullvad_management_interface::ManagementServiceClient; +use test_macro::test_function; +use test_rpc::{ExecResult, ServiceClient}; + +/// This test fails if there is no connectivity, or name resolution fails, when connected to a VPN. +#[test_function(target_os = "linux")] +pub async fn test_containers( + _: TestContext, + rpc: ServiceClient, + mut mullvad_client: ManagementServiceClient, +) -> Result<(), Error> { + let result = probe_container_connectivity(&rpc).await?; + assert!( + result.success(), + "containers should have connectivity when disconnected from the VPN" + ); + + helpers::connect_and_wait(&mut mullvad_client).await?; + + let result = probe_container_connectivity(&rpc).await?; + assert!( + result.success(), + "containers should have connectivity when connected to the VPN" + ); + + Ok(()) +} + +/// This function executes curl inside podman or docker in the guest/test runner. +async fn probe_container_connectivity(rpc: &ServiceClient) -> Result { + let has_podman = rpc.exec("bash", ["-c", "which podman"]).await?.success(); + + let result = if has_podman { + // podman run docker.io/curlimages/curl:latest https://am.i.mullvad.net/connected + rpc.exec( + "podman", + [ + "run", + "docker.io/curlimages/curl:latest", + "https://am.i.mullvad.net/connected", + ], + ) + .await? + } else { + // sudo docker run docker.io/curlimages/curl:latest https://am.i.mullvad.net/connected + rpc.exec( + "sudo", + [ + "docker", + "run", + "docker.io/curlimages/curl:latest", + "https://am.i.mullvad.net/connected", + ], + ) + .await? + }; + + if !result.success() { + let stdout = std::str::from_utf8(&result.stdout).unwrap_or("invalid utf8"); + let stderr = std::str::from_utf8(&result.stderr).unwrap_or("invalid utf8"); + log::error!("probe_container_connectivity failed:\n\nstdout:\n\n{stdout}\n\n{stderr}\n"); + } + Ok(result) +}