Skip to content
Open
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
6 changes: 6 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ jobs:
TEST_LOG_PATH: ${{ github.workspace }}/artifacts/log/test-logs
TestsRunningOutsideOfRepo: true
TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX: 'netaspireci.azurecr.io'
# CLI E2E Dockerfiles consume this as a build arg to avoid overloaded default Ubuntu package servers.
# azure.archive.ubuntu.com does not serve HTTPS; HTTP is intentional and matches the GitHub-hosted Ubuntu runner fallback mirror.
ASPIRE_E2E_UBUNTU_APT_MIRROR: ${{ runner.os == 'Linux' && (runner.arch == 'ARM64' && 'https://azure.ports.ubuntu.com/ubuntu-ports/' || 'http://azure.archive.ubuntu.com/ubuntu/') || '' }}
# PR metadata for CLI E2E tests that download artifacts from a PR
GITHUB_PR_NUMBER: ${{ fromJson(inputs.properties).requiresCliArchive == true && github.event.pull_request.number || '' }}
GITHUB_PR_HEAD_SHA: ${{ fromJson(inputs.properties).requiresCliArchive == true && github.event.pull_request.head.sha || '' }}
Expand Down Expand Up @@ -428,6 +431,9 @@ jobs:
NUGET_PACKAGES: ${{ github.workspace }}/.packages
PLAYWRIGHT_INSTALLED: ${{ fromJson(inputs.properties).enablePlaywrightInstall != true && 'false' || 'true' }}
TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX: 'netaspireci.azurecr.io'
# CLI E2E Dockerfiles consume this as a build arg to avoid overloaded default Ubuntu package servers.
# azure.archive.ubuntu.com does not serve HTTPS; HTTP is intentional and matches the GitHub-hosted Ubuntu runner fallback mirror.
ASPIRE_E2E_UBUNTU_APT_MIRROR: ${{ runner.os == 'Linux' && (runner.arch == 'ARM64' && 'https://azure.ports.ubuntu.com/ubuntu-ports/' || 'http://azure.archive.ubuntu.com/ubuntu/') || '' }}
# PR metadata for CLI E2E tests that download artifacts from a PR
GITHUB_PR_NUMBER: ${{ fromJson(inputs.properties).requiresCliArchive == true && github.event.pull_request.number || '' }}
GITHUB_PR_HEAD_SHA: ${{ fromJson(inputs.properties).requiresCliArchive == true && github.event.pull_request.head.sha || '' }}
Expand Down
14 changes: 14 additions & 0 deletions tests/Aspire.Cli.EndToEnd.Tests/Helpers/CliE2ETestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ private static void EnsurePolyglotBaseImage(string repoRoot, ITestOutputHelper o
startInfo.ArgumentList.Add("--quiet");
startInfo.ArgumentList.Add("--build-arg");
startInfo.ArgumentList.Add("SKIP_SOURCE_BUILD=true");
AddUbuntuAptMirrorBuildArg(startInfo);
startInfo.ArgumentList.Add("-f");
startInfo.ArgumentList.Add(dockerfilePath);
startInfo.ArgumentList.Add("-t");
Expand Down Expand Up @@ -360,6 +361,7 @@ private static void EnsurePodmanBaseImage(string repoRoot, ITestOutputHelper out

startInfo.ArgumentList.Add("build");
startInfo.ArgumentList.Add("--quiet");
AddUbuntuAptMirrorBuildArg(startInfo);
startInfo.ArgumentList.Add("-f");
startInfo.ArgumentList.Add(dockerfilePath);
startInfo.ArgumentList.Add("-t");
Expand Down Expand Up @@ -446,6 +448,18 @@ private static string GenerateDockerContainerName()
return $"hex1b-test-{Guid.NewGuid():N}".Substring(0, 32);
}

private static void AddUbuntuAptMirrorBuildArg(ProcessStartInfo startInfo)
{
var buildArgs = new Dictionary<string, string>();
CliInstallStrategy.ConfigureUbuntuAptMirrorBuildArg(buildArgs);

foreach (var (name, value) in buildArgs)
{
startInfo.ArgumentList.Add("--build-arg");
startInfo.ArgumentList.Add($"{name}={value}");
}
}

/// <summary>
/// Walks up from the test assembly directory to find the repo root (contains Aspire.slnx).
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions tests/Aspire.Cli.EndToEnd.Tests/Helpers/CliInstallStrategyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,34 @@ public void ConfigureContainer_AddsPrMetadataForPullRequest()
Assert.Equal("52669a7cac3d4f10c6269909fc38e77124ed177c", options.Environment["GITHUB_PR_HEAD_SHA"]);
}

[Fact]
public void ConfigureContainer_AddsUbuntuAptMirrorBuildArgWhenEnvironmentVariableIsSet()
{
using var environment = new EnvironmentVariableScope(
(CliInstallStrategy.UbuntuAptMirrorEnvironmentVariableName, "http://azure.archive.ubuntu.com/ubuntu/"));

var strategy = CliInstallStrategy.LatestGa();
var options = new DockerContainerOptions();

strategy.ConfigureContainer(options);

Assert.Equal("http://azure.archive.ubuntu.com/ubuntu/", options.BuildArgs[CliInstallStrategy.UbuntuAptMirrorBuildArgName]);
}

[Fact]
public void ConfigureContainer_DoesNotAddUbuntuAptMirrorBuildArgWhenEnvironmentVariableIsEmpty()
{
using var environment = new EnvironmentVariableScope(
(CliInstallStrategy.UbuntuAptMirrorEnvironmentVariableName, null));

var strategy = CliInstallStrategy.LatestGa();
var options = new DockerContainerOptions();

strategy.ConfigureContainer(options);

Assert.DoesNotContain(CliInstallStrategy.UbuntuAptMirrorBuildArgName, options.BuildArgs.Keys);
}

[Fact]
public void Detect_DotnetTool_WhenEnvironmentVariableIsSet()
{
Expand Down
12 changes: 12 additions & 0 deletions tests/Shared/CliInstallStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ internal enum CliInstallQuality
internal sealed class CliInstallStrategy
{
internal const string CliArchiveDirEnvironmentVariableName = "ASPIRE_E2E_CLI_ARCHIVE_DIR";
internal const string UbuntuAptMirrorBuildArgName = "UBUNTU_APT_MIRROR";
internal const string UbuntuAptMirrorEnvironmentVariableName = "ASPIRE_E2E_UBUNTU_APT_MIRROR";

private const string PreinstalledEnvironmentVariableName = "ASPIRE_E2E_PREINSTALLED";
/// <summary>
Expand Down Expand Up @@ -513,6 +515,7 @@ public static CliInstallStrategy Detect(Action<string>? log = null)
public void ConfigureContainer(DockerContainerOptions config)
{
config.BuildArgs["SKIP_SOURCE_BUILD"] = "true";
ConfigureUbuntuAptMirrorBuildArg(config.BuildArgs);

switch (Mode)
{
Expand Down Expand Up @@ -559,6 +562,15 @@ public void ConfigureContainer(DockerContainerOptions config)
}
}

internal static void ConfigureUbuntuAptMirrorBuildArg(IDictionary<string, string> buildArgs)
{
var ubuntuAptMirror = Environment.GetEnvironmentVariable(UbuntuAptMirrorEnvironmentVariableName);
if (!string.IsNullOrWhiteSpace(ubuntuAptMirror))
{
buildArgs[UbuntuAptMirrorBuildArgName] = ubuntuAptMirror;
}
}

/// <summary>
/// Returns a description of this strategy for test output logging.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions tests/Shared/Docker/Dockerfile.e2e
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build

ARG SKIP_SOURCE_BUILD=false
ARG UBUNTU_APT_MIRROR=

# Install native AOT build toolchain.
COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN if [ "$SKIP_SOURCE_BUILD" != "true" ]; then \
apt-get update -qq && \
apt-get install -y --no-install-recommends clang zlib1g-dev && \
Expand All @@ -47,10 +50,14 @@ RUN if [ "$SKIP_SOURCE_BUILD" != "true" ]; then \
# ============================================================
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS runtime

ARG UBUNTU_APT_MIRROR=

# --- Common tooling (shared between dotnet and polyglot variants) ---

# Install gh CLI (needed by get-aspire-cli-pr.sh to download PR artifacts).
# Install Docker CLI plus the buildx/compose plugins used by publish and deploy flows.
COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends gpg docker.io docker-buildx docker-compose-v2 unzip && \
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
Expand Down
4 changes: 4 additions & 0 deletions tests/Shared/Docker/Dockerfile.e2e-podman
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
# deploy flows can be tested without depending on host Podman state.
FROM mcr.microsoft.com/dotnet/sdk:10.0

ARG UBUNTU_APT_MIRROR=

COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends \
curl \
Expand Down
7 changes: 7 additions & 0 deletions tests/Shared/Docker/Dockerfile.e2e-polyglot-base
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build

ARG SKIP_SOURCE_BUILD=false
ARG UBUNTU_APT_MIRROR=

# Install native AOT build toolchain.
COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN if [ "$SKIP_SOURCE_BUILD" != "true" ]; then \
apt-get update -qq && \
apt-get install -y --no-install-recommends clang zlib1g-dev && \
Expand All @@ -48,7 +51,11 @@ RUN if [ "$SKIP_SOURCE_BUILD" != "true" ]; then \
# ============================================================
FROM ubuntu:24.04 AS runtime

ARG UBUNTU_APT_MIRROR=

# Install base tools and Docker CLI.
COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends \
ca-certificates curl gpg docker.io git libicu-dev unzip && \
Expand Down
4 changes: 4 additions & 0 deletions tests/Shared/Docker/Dockerfile.e2e-polyglot-java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

FROM aspire-e2e-polyglot-base

ARG UBUNTU_APT_MIRROR=

COPY tests/Shared/Docker/configure-ubuntu-apt-mirror.sh /usr/local/bin/
RUN sh /usr/local/bin/configure-ubuntu-apt-mirror.sh "$UBUNTU_APT_MIRROR"
RUN apt-get update -qq && \
apt-get install -y --no-install-recommends openjdk-25-jdk && \
rm -rf /var/lib/apt/lists/*
51 changes: 51 additions & 0 deletions tests/Shared/Docker/configure-ubuntu-apt-mirror.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/sh
set -eu

ubuntu_apt_mirror="${1:-}"

if [ -z "$ubuntu_apt_mirror" ]; then
exit 0
fi

if [ ! -f /etc/os-release ]; then
echo "Skipping UBUNTU_APT_MIRROR because /etc/os-release was not found." >&2
exit 0
fi

. /etc/os-release

if [ "${ID:-}" != "ubuntu" ]; then
echo "Skipping UBUNTU_APT_MIRROR because current image ID is '${ID:-unknown}', not 'ubuntu'." >&2
exit 0
fi

case "$ubuntu_apt_mirror" in
*://*) ;;
*)
echo "UBUNTU_APT_MIRROR must be an absolute URI, got '$ubuntu_apt_mirror'." >&2
exit 1
;;
esac

if [ -z "${VERSION_CODENAME:-}" ]; then
echo "Could not determine the Ubuntu version codename from /etc/os-release." >&2
exit 1
fi

ubuntu_apt_mirror="${ubuntu_apt_mirror%/}"
ubuntu_apt_components="${UBUNTU_APT_COMPONENTS:-main restricted universe multiverse}"
ubuntu_sources_file="/etc/apt/sources.list.d/ubuntu.sources"

mkdir -p "$(dirname "$ubuntu_sources_file")"

cat > "$ubuntu_sources_file" <<EOF
Types: deb
URIs: $ubuntu_apt_mirror
Suites: $VERSION_CODENAME $VERSION_CODENAME-updates $VERSION_CODENAME-backports $VERSION_CODENAME-security
Components: $ubuntu_apt_components
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
EOF

if [ -f /etc/apt/sources.list ]; then
printf '# Ubuntu sources configured in %s\n' "$ubuntu_sources_file" > /etc/apt/sources.list
fi
Loading