Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test container connectivity on Linux #5651

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions test/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 0 additions & 19 deletions test/scripts/build-runner-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
;;
Expand All @@ -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}" "::"
Expand Down
10 changes: 8 additions & 2 deletions test/scripts/ssh-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions test/test-manager/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod dns;
mod helpers;
mod install;
mod settings;
mod software;
mod test_metadata;
mod tunnel;
mod tunnel_state;
Expand Down
67 changes: 67 additions & 0 deletions test/test-manager/src/tests/software.rs
Original file line number Diff line number Diff line change
@@ -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<ExecResult, Error> {
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)
}
Loading