Skip to content

Commit 7221cd8

Browse files
test: Container test refactor (#2123)
Co-authored-by: Alex Hemsath <[email protected]>
1 parent e5c8176 commit 7221cd8

19 files changed

+446
-418
lines changed

.github/workflows/all_solutions.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ jobs:
135135
path: ${{ github.workspace }}\src\AwsLambda\AwsLambdaOpenTracer\bin\Release\netstandard2.0-ILRepacked
136136
if-no-files-found: error
137137

138-
run-linux-smoke-tests:
138+
run-linux-container-tests:
139139
needs: build-fullagent-msi
140-
name: Run Linux Smoke Tests
141-
uses: ./.github/workflows/run_linux_smoke_tests.yml
140+
name: Run Linux Container Tests
141+
uses: ./.github/workflows/run_linux_container_tests.yml
142142
secrets: inherit
143143

144144
build-integration-tests:

.github/workflows/run_linux_smoke_tests.yml renamed to .github/workflows/run_linux_container_tests.yml

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: .NET Agent Linux Smoke Tests
1+
name: .NET Agent Linux Container Integration Tests
22

33
on:
44
workflow_call:
@@ -20,16 +20,16 @@ env:
2020

2121
# only allow one instance of this workflow to be running per PR or branch, cancels any that are already running
2222
concurrency:
23-
group: linux-smoke-tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
23+
group: linux-container-tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
2424
cancel-in-progress: true
2525

2626
permissions:
2727
contents: read
2828

2929
jobs:
3030

31-
run-linux-smoke-tests:
32-
name: Run Linux Smoke Tests
31+
run-linux-container-tests:
32+
name: Run Linux Container Integration Tests
3333
runs-on: ubuntu-latest
3434

3535
env:
@@ -71,13 +71,12 @@ jobs:
7171
name: homefolders
7272
path: ${{ github.workspace }}/src/Agent
7373
repo: ${{ github.repository }}
74-
7574

7675
- name: Set up secrets
7776
env:
7877
INTEGRATION_TEST_SECRETS: ${{ secrets.TEST_SECRETS }}
7978
run: |
8079
echo $INTEGRATION_TEST_SECRETS | dotnet user-secrets set --project ${{ env.integration_tests_shared_project }}
81-
82-
- name: Build & Run Linux Smoke Tests
80+
81+
- name: Build & Run Linux Container Integration Tests
8382
run: dotnet test ./tests/Agent/IntegrationTests/ContainerIntegrationTests/ContainerIntegrationTests.csproj --framework net7.0

tests/Agent/IntegrationTests/ContainerApplications/KafkaTestApp/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public static void SetupKafka(ILogger logger)
5454
{
5555
Thread.Sleep(15 * 1000); // Waiting for Kafka to get ready
5656

57-
var broker = Environment.GetEnvironmentVariable("NEW_RELIC_KAFKA_CONTAINER_NAME");
57+
var broker = Environment.GetEnvironmentVariable("NEW_RELIC_KAFKA_BROKER_NAME");
5858
var kafkaConfig = new ConfigurationBuilder().AddInMemoryCollection().Build();
5959
kafkaConfig["bootstrap.servers"] = $"{broker}:9092";
6060
kafkaConfig["group.id"] = "kafka-dotnet-getting-started";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
ARG DOTNET_VERSION
2+
ARG TARGET_ARCH
3+
# Uses a custom-built Fedora image with ASP.NET Core pre-installed, served from a private
4+
# container repository under the .NET Team Sandbox Azure subscription
5+
FROM --platform=${TARGET_ARCH} dotnetreg.azurecr.io/fedora-aspnet:${DOTNET_VERSION} AS base
6+
WORKDIR /app
7+
EXPOSE 80
8+
9+
# build image is always amd64 (to match the runner architecture), even though the target architecture may be arm64
10+
FROM --platform=amd64 mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION} AS build
11+
ARG TARGET_ARCH
12+
WORKDIR /src
13+
COPY ["SmokeTestApp/SmokeTestApp.csproj", "SmokeTestApp/"]
14+
RUN dotnet restore "SmokeTestApp/SmokeTestApp.csproj" -a ${TARGET_ARCH}
15+
16+
COPY . .
17+
WORKDIR "/src/SmokeTestApp"
18+
RUN dotnet build "SmokeTestApp.csproj" -c Release -o /app/build --os linux -a ${TARGET_ARCH}
19+
20+
FROM build AS publish
21+
RUN dotnet publish "SmokeTestApp.csproj" -c Release -o /app/publish /p:UseAppHost=false --os linux -a ${TARGET_ARCH}
22+
23+
FROM base AS final
24+
25+
# Enable the agent
26+
ARG NEW_RELIC_HOST
27+
ARG NEW_RELIC_LICENSE_KEY
28+
ARG NEW_RELIC_APP_NAME
29+
30+
ENV CORECLR_ENABLE_PROFILING=1 \
31+
CORECLR_PROFILER={36032161-FFC0-4B61-B559-F6C5D41BAE5A} \
32+
CORECLR_NEWRELIC_HOME=/usr/local/newrelic-dotnet-agent \
33+
CORECLR_PROFILER_PATH=/usr/local/newrelic-dotnet-agent/libNewRelicProfiler.so \
34+
NEW_RELIC_HOST=${NEW_RELIC_HOST} \
35+
NEW_RELIC_LICENSE_KEY=${NEW_RELIC_LICENSE_KEY} \
36+
NEW_RELIC_APP_NAME=${NEW_RELIC_APP_NAME} \
37+
NEWRELIC_LOG_DIRECTORY=/app/logs
38+
39+
WORKDIR /app
40+
COPY --from=publish /app/publish .
41+
42+
ENTRYPOINT ["dotnet", "SmokeTestApp.dll"]

tests/Agent/IntegrationTests/ContainerApplications/docker-compose-kafka.yml

+26-18
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ version: "3"
1111
# PLATFORM The platform that the service runs on -- linux/amd64 or linux/arm64/v8
1212
# DOTNET_VERSION The dotnet version number to use (7.0, 8.0, etc)
1313
# TEST_DOCKERFILE The path and dockerfile to use for the service.
14+
#
15+
# NEW_RELIC_KAFKA_TOPIC
1416
#
1517
# and the usual suspects:
1618
# NEW_RELIC_LICENSE_KEY
@@ -22,40 +24,46 @@ version: "3"
2224
# Alternatively, set COMPOSE_FILE environment variable to the path and omit the -f parameter
2325

2426
services:
25-
UbuntuX64Kafka1TestApp:
26-
extends:
27-
file: docker-compose-smoketestapp.yml
28-
service: smoketestapp
29-
depends_on:
30-
- kafka-broker
31-
environment:
32-
- NEW_RELIC_KAFKA_TOPIC=${NEW_RELIC_KAFKA_TOPIC}
33-
- NEW_RELIC_KAFKA_CONTAINER_NAME=${NEW_RELIC_KAFKA_CONTAINER_NAME}
34-
35-
UbuntuX64Kafka2TestApp:
36-
extends:
37-
file: docker-compose-smoketestapp.yml
38-
service: smoketestapp
27+
LinuxSmokeTestApp:
28+
container_name: ${CONTAINER_NAME}
29+
image: ${CONTAINER_NAME}
30+
platform: ${PLATFORM}
31+
build:
32+
context: .
33+
dockerfile: ${TEST_DOCKERFILE}
34+
args:
35+
DISTRO_TAG: ${DISTRO_TAG}
36+
TARGET_ARCH: ${TARGET_ARCH}
37+
NEW_RELIC_LICENSE_KEY: ${NEW_RELIC_LICENSE_KEY}
38+
NEW_RELIC_APP_NAME: ${NEW_RELIC_APP_NAME}
39+
NEW_RELIC_HOST: ${NEW_RELIC_HOST}
40+
DOTNET_VERSION: ${DOTNET_VERSION}
41+
APP_DOTNET_VERSION: ${APP_DOTNET_VERSION}
42+
ports:
43+
- "${PORT}:80"
44+
volumes:
45+
- ${AGENT_PATH}:/usr/local/newrelic-dotnet-agent # AGENT_PATH from .env, points to newrelichome_linux_x64
46+
- ${LOG_PATH}:/app/logs # LOG_PATH from .env, should be a folder unique to this run of the smoketest app
3947
depends_on:
4048
- kafka-broker
4149
environment:
4250
- NEW_RELIC_KAFKA_TOPIC=${NEW_RELIC_KAFKA_TOPIC}
43-
- NEW_RELIC_KAFKA_CONTAINER_NAME=${NEW_RELIC_KAFKA_CONTAINER_NAME}
51+
- NEW_RELIC_KAFKA_BROKER_NAME=kafka-broker
4452

4553
kafka-broker:
4654
image: confluentinc/cp-kafka:7.5.0
4755
environment:
4856
KAFKA_BROKER_ID: 1
4957
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
50-
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://${NEW_RELIC_KAFKA_CONTAINER_NAME}:29092,PLAINTEXT_HOST://${NEW_RELIC_KAFKA_CONTAINER_NAME}:9092
58+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-broker:29092,PLAINTEXT_HOST://kafka-broker:9092
5159
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
5260
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
5361
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
5462
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
5563
KAFKA_PROCESS_ROLES: broker,controller
5664
KAFKA_NODE_ID: 1
57-
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@${NEW_RELIC_KAFKA_CONTAINER_NAME}:29093
58-
KAFKA_LISTENERS: PLAINTEXT://${NEW_RELIC_KAFKA_CONTAINER_NAME}:29092,CONTROLLER://${NEW_RELIC_KAFKA_CONTAINER_NAME}:29093,PLAINTEXT_HOST://:9092
65+
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka-broker:29093
66+
KAFKA_LISTENERS: PLAINTEXT://kafka-broker:29092,CONTROLLER://kafka-broker:29093,PLAINTEXT_HOST://:9092
5967
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
6068
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
6169
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs

tests/Agent/IntegrationTests/ContainerApplications/docker-compose.yml

+19-49
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ version: "3"
1010
# CONTAINER_NAME The name for the container
1111
# PLATFORM The platform that the service runs on -- linux/amd64 or linux/arm64/v8
1212
# DOTNET_VERSION The dotnet version number to use (7.0, 8.0, etc)
13-
# NETWORK_NAME The network name to use for containers in this app. Should be unique among all running instances.
1413
# TEST_DOCKERFILE The path and dockerfile to use for the service.
1514
#
1615
# and the usual suspects:
@@ -23,55 +22,26 @@ version: "3"
2322
# Alternatively, set COMPOSE_FILE environment variable to the path and omit the -f parameter
2423

2524
services:
26-
DebianX64SmokeTestApp:
27-
extends:
28-
file: docker-compose-smoketestapp.yml
29-
service: smoketestapp
30-
UbuntuX64SmokeTestApp:
31-
extends:
32-
file: docker-compose-smoketestapp.yml
33-
service: smoketestapp
34-
AlpineX64SmokeTestApp:
35-
extends:
36-
file: docker-compose-smoketestapp.yml
37-
service: smoketestapp
38-
DebianArm64SmokeTestApp:
39-
extends:
40-
file: docker-compose-smoketestapp.yml
41-
service: smoketestapp
42-
UbuntuArm64SmokeTestApp:
43-
extends:
44-
file: docker-compose-smoketestapp.yml
45-
service: smoketestapp
46-
CentosX64SmokeTestApp:
47-
extends:
48-
file: docker-compose-smoketestapp.yml
49-
service: smoketestapp
25+
LinuxSmokeTestApp:
26+
container_name: ${CONTAINER_NAME}
27+
image: ${CONTAINER_NAME}
28+
platform: ${PLATFORM}
5029
build:
51-
dockerfile: SmokeTestApp/Dockerfile.centos
52-
CentosArm64SmokeTestApp:
53-
extends:
54-
file: docker-compose-smoketestapp.yml
55-
service: smoketestapp
56-
build:
57-
dockerfile: SmokeTestApp/Dockerfile.centos
58-
AmazonX64SmokeTestApp:
59-
extends:
60-
file: docker-compose-smoketestapp.yml
61-
service: smoketestapp
62-
build:
63-
dockerfile: SmokeTestApp/Dockerfile.amazon
64-
AmazonArm64SmokeTestApp:
65-
extends:
66-
file: docker-compose-smoketestapp.yml
67-
service: smoketestapp
68-
build:
69-
dockerfile: SmokeTestApp/Dockerfile.amazon
70-
LinuxUnicodeLogfileTestApp:
71-
extends:
72-
file: docker-compose-smoketestapp.yml
73-
service: smoketestapp
74-
30+
context: .
31+
dockerfile: ${TEST_DOCKERFILE}
32+
args:
33+
DISTRO_TAG: ${DISTRO_TAG}
34+
TARGET_ARCH: ${TARGET_ARCH}
35+
NEW_RELIC_LICENSE_KEY: ${NEW_RELIC_LICENSE_KEY}
36+
NEW_RELIC_APP_NAME: ${NEW_RELIC_APP_NAME}
37+
NEW_RELIC_HOST: ${NEW_RELIC_HOST}
38+
DOTNET_VERSION: ${DOTNET_VERSION}
39+
APP_DOTNET_VERSION: ${APP_DOTNET_VERSION}
40+
ports:
41+
- "${PORT}:80"
42+
volumes:
43+
- ${AGENT_PATH}:/usr/local/newrelic-dotnet-agent # AGENT_PATH from .env, points to newrelichome_linux_x64
44+
- ${LOG_PATH}:/app/logs # LOG_PATH from .env, should be a folder unique to this run of the smoketest app
7545
networks:
7646
default:
7747
driver: bridge

tests/Agent/IntegrationTests/ContainerIntegrationTests.sln

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ EndProject
1818
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_docker", "_docker", "{FB10922F-3CC6-4497-AF53-DF6808380258}"
1919
ProjectSection(SolutionItems) = preProject
2020
ContainerApplications\docker-compose-kafka.yml = ContainerApplications\docker-compose-kafka.yml
21-
ContainerApplications\docker-compose-smoketestapp.yml = ContainerApplications\docker-compose-smoketestapp.yml
2221
ContainerApplications\docker-compose.yml = ContainerApplications\docker-compose.yml
2322
EndProjectSection
2423
EndProject
+14-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
using NewRelic.Agent.IntegrationTests.Shared;
1212
using Xunit;
1313

14-
namespace NewRelic.Agent.ContainerIntegrationTests.ContainerFixtures;
14+
namespace NewRelic.Agent.ContainerIntegrationTests.Applications;
1515

1616
public class ContainerApplication : RemoteApplication
1717
{
@@ -22,12 +22,14 @@ public class ContainerApplication : RemoteApplication
2222
private readonly string _targetArch;
2323
private readonly string _agentArch;
2424
private readonly string _containerPlatform;
25-
private readonly string _dockerComposeServiceName;
25+
26+
private static Random random = new Random();
27+
private readonly long _randomId;
2628

2729
// Used for handling dependent containers started automatically for services
2830
public readonly List<string> DockerDependencies;
2931

30-
protected override string ApplicationDirectoryName { get; }
32+
protected override string ApplicationDirectoryName { get; } = "ContainerApplication";
3133

3234
protected override string SourceApplicationDirectoryPath
3335
{
@@ -37,16 +39,16 @@ protected override string SourceApplicationDirectoryPath
3739
}
3840
}
3941

40-
public ContainerApplication(string applicationDirectoryName, string distroTag, Architecture containerArchitecture,
42+
public ContainerApplication(string distroTag, Architecture containerArchitecture,
4143
string dotnetVersion, string dockerfile, string dockerComposeFile = "docker-compose.yml") : base(applicationType: ApplicationType.Container, isCoreApp: true)
4244
{
43-
ApplicationDirectoryName = applicationDirectoryName;
44-
_dockerComposeServiceName = applicationDirectoryName;
4545
_distroTag = distroTag;
4646
_dotnetVersion = dotnetVersion;
4747
_dockerfile = dockerfile;
4848
_dockerComposeFile = dockerComposeFile;
4949

50+
_randomId = random.NextInt64(); // a random id to help ensure container name uniqueness
51+
5052
DockerDependencies = new List<string>();
5153

5254
switch (containerArchitecture)
@@ -64,9 +66,9 @@ public ContainerApplication(string applicationDirectoryName, string distroTag, A
6466
}
6567
}
6668

67-
public override string AppName => $"{_dockerComposeServiceName}_{_dotnetVersion}-{_distroTag}_{_targetArch}";
69+
public override string AppName => $"ContainerTestApp_{_dotnetVersion}-{_distroTag}_{_targetArch}_{_randomId}";
6870

69-
private string ContainerName => $"{_dockerComposeServiceName}_{_dotnetVersion}-{_distroTag}_{_targetArch}".ToLower(); // must be lowercase
71+
private string ContainerName => AppName.ToLower().Replace(".", "_"); // must be lowercase, can't have any periods in it
7072

7173
public override void CopyToRemote()
7274
{
@@ -79,7 +81,7 @@ public override void Start(string commandLineArguments, Dictionary<string, strin
7981
{
8082
CleanupContainer();
8183

82-
var arguments = $"compose -f {_dockerComposeFile} -p {_dockerComposeServiceName.ToLower()} up --abort-on-container-exit --remove-orphans --force-recreate {_dockerComposeServiceName}";
84+
var arguments = $"compose -f {_dockerComposeFile} -p {ContainerName} up --abort-on-container-exit --remove-orphans --force-recreate LinuxSmokeTestApp";
8385

8486
var newRelicHomeDirectoryPath = DestinationNewRelicHomeDirectoryPath;
8587
var profilerLogDirectoryPath = DefaultLogFileDirectoryPath;
@@ -107,6 +109,7 @@ public override void Start(string commandLineArguments, Dictionary<string, strin
107109
startInfo.EnvironmentVariables.Remove("NEWRELIC_LOG_DIRECTORY");
108110
startInfo.EnvironmentVariables.Remove("NEWRELIC_LOG_LEVEL");
109111
startInfo.EnvironmentVariables.Remove("NEWRELIC_LICENSEKEY");
112+
startInfo.EnvironmentVariables.Remove("NEW_RELIC_APP_NAME");
110113
startInfo.EnvironmentVariables.Remove("NEW_RELIC_LICENSE_KEY");
111114
startInfo.EnvironmentVariables.Remove("NEW_RELIC_HOST");
112115
startInfo.EnvironmentVariables.Remove("NEWRELIC_INSTALL_PATH");
@@ -132,9 +135,6 @@ public override void Start(string commandLineArguments, Dictionary<string, strin
132135
startInfo.EnvironmentVariables.Add("AGENT_PATH", newRelicHomeDirectoryPath);
133136
startInfo.EnvironmentVariables.Add("LOG_PATH", profilerLogDirectoryPath);
134137
startInfo.EnvironmentVariables.Add("CONTAINER_NAME", ContainerName);
135-
// generate a random network name to keep parallel test execution from failing
136-
// network name length needs to be less than 15 characters to be compatible with linux containers
137-
startInfo.EnvironmentVariables.Add("NETWORK_NAME", $"net-{System.Security.Cryptography.RandomNumberGenerator.GetInt32(1000000, 10000000)}");
138138

139139
if (AdditionalEnvironmentVariables != null)
140140
{
@@ -183,7 +183,7 @@ public override void Shutdown()
183183

184184
// stop and remove the container, no need to kill RemoteProcess, as it will die when this command runs
185185
// wait up to 5 seconds for the app to terminate gracefully before forcefully closing it
186-
Process.Start("docker", $"compose -p {_dockerComposeServiceName.ToLower()} down --rmi local --remove-orphans");
186+
Process.Start("docker", $"compose -p {ContainerName.ToLower()} down --rmi local --remove-orphans");
187187

188188
Thread.Sleep(TimeSpan.FromSeconds(5)); // give things a chance to settle before destroying the container
189189
}
@@ -193,7 +193,7 @@ private void CleanupContainer()
193193
Console.WriteLine($"[{AppName} {DateTime.Now}] Cleaning up container and images related to {ContainerName} container.");
194194
TestLogger?.WriteLine($"[{AppName}] Cleaning up container and images related to {ContainerName} container.");
195195

196-
Process.Start("docker", $"compose -p {_dockerComposeServiceName.ToLower()} down --rmi local --remove-orphans");
196+
Process.Start("docker", $"compose -p {ContainerName.ToLower()} down --rmi local --remove-orphans");
197197

198198

199199
#if DEBUG

tests/Agent/IntegrationTests/ContainerIntegrationTests/ContainerFixtures/ContainerFixture.cs

-15
This file was deleted.

0 commit comments

Comments
 (0)