Hi,
I have a docker-compose stack, containing the following services within the same network (please see listing below):
- Kafka + Zookeeper
- netclient-run: ASP.NET Core WebApp that spawns a Background/Hosted Service that requests topic creation from the Kafka service. This is done using the confluent-kafka-dotnet client.
-
netclient-test: ASP.NET Core xUnit test that uses
WebApplicationFactory
to start aTestServer
instance and create a Http Client. The Test Server bootstraps the WebApp.
Upon startup of the live WebApp the background/hosted service runs and successfully makes a request to the kafka service. This is successful locally and on the GitLab CI Server.
However the test blocks indefinelty on the Gitlab CI Server when the background service makes a request to kafka to create the topic. The same test runs successfully on local development environment. I am using WebApplicationFactory
to spin-up a TestServer
and create a HttpClient
.
Does anyone have any ideas as to why the test is blocking on GitLab CI server?
I have created a small GitLab project to illustrate the issue that I am encountering.
Output from GitLab CI Server
netclient-run | .NET Run Web App Ready. Starting WebApp that contains KafkaAdmin background service.
netclient-test | Giving netclient-run a bit of time to start up…
netclient-run | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
netclient-run | Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
netclient-run | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
netclient-run | No XML encryptor configured. Key {395ba0f4-cde9-49af-8fb4-fd16b9f05bae} may be persisted to storage in unencrypted form.
netclient-run | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-run | Admin service trying to create Kafka Topic...
netclient-run | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-run | Topic::eventbus, ReplicationCount::1, PartitionCount::3
netclient-run | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-run | Bootstrap Servers::kafka:9092
netclient-run | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-run | Admin service successfully created topic eventbus
netclient-run | info: Microsoft.Hosting.Lifetime[0]
netclient-run | Now listening on: http://[::]:80
netclient-run | info: Microsoft.Hosting.Lifetime[0]
netclient-run | Application started. Press Ctrl+C to shut down.
netclient-run | info: Microsoft.Hosting.Lifetime[0]
netclient-run | Hosting environment: Docker
netclient-run | info: Microsoft.Hosting.Lifetime[0]
netclient-run | Content root path: /KafkaAdmin/src/KafkaAdmin.WebApp
netclient-test | .NET Client test container ready. Running test that uses WebApplicationFactory TestServer to start WebApp with KafkaAdmin background service
netclient-test | This runs successfully in a local development environment on MacOS and Ubuntu Linux 16.04.
netclient-test | This fails when running on a GitLab CI Server. It can be seen that the test server bootstraps the WebApp.....
netclient-test | The KafkaAdmin background service blocks when requesting topic creation from the kafka service
netclient-test | Test run for /KafkaAdmin/tests/KafkaAdmin.Kafka.IntegrationTests/bin/Release/netcoreapp3.1/linux-musl-x64/KafkaAdmin.Kafka.IntegrationTests.dll(.NETCoreApp,Version=v3.1)
netclient-test | Starting test execution, please wait...
netclient-test |
netclient-test | A total of 1 test files matched the specified pattern.
netclient-test | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
netclient-test | Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
netclient-test | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
netclient-test | No XML encryptor configured. Key {2b234f03-01b4-472d-9621-db8e056db173} may be persisted to storage in unencrypted form.
netclient-test | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-test | Admin service trying to create Kafka Topic...
netclient-test | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-test | Topic::eventbus, ReplicationCount::1, PartitionCount::3
netclient-test | info: KafkaAdmin.Kafka.KafkaAdminService[0]
netclient-test | Bootstrap Servers::kafka:9092
GitLab Pipeline
stages:
- test
variables:
DOCKER_DRIVER: overlay2
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
services:
- docker:dind
stages:
- test
test:
stage: test
image: docker/compose:alpine-1.27.4
before_script:
- docker version
- docker-compose version
- docker info
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
script:
- cd docker
- docker-compose -f docker-compose.yml build
- docker-compose -f docker-compose.yml up --exit-code-from netclient-test --abort-on-container-exit
Docker Compose Environment
---
version: "3.8"
services:
zookeeper:
image: confluentinc/cp-zookeeper:6.0.0
hostname: zookeeper
container_name: zookeeper
ports:
- "2181:2181"
networks:
- camnet
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ZOOKEEPER_LOG4J_ROOT_LOGLEVEL: WARN
kafka:
image: confluentinc/cp-kafka:6.0.0
hostname: kafka
container_name: kafka
depends_on:
- zookeeper
networks:
- camnet
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_NUM_PARTITIONS: 3
KAFKA_HEAP_OPTS: -Xmx512M -Xms512M
KAFKA_LOG4J_ROOT_LOGLEVEL: WARN
KAFKA_LOG4J_LOGGERS: "org.apache.zookeeper=WARN,org.apache.kafka=WARN,kafka=WARN,kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN"
netclient-test:
build:
context: ../
dockerfile: docker/Dockerfile
container_name: netclient-test
image: dcs3spp/netclient
networks:
- camnet
depends_on:
- kafka
- netclient-run
entrypoint: []
command:
- bash
- -c
- |-
echo 'Giving Kafka a bit of time to start up…'
while ! nc -z kafka 9092;
do
sleep 1;
done;
echo 'Giving netclient-run a bit of time to start up…'
while ! nc -z netclient-run 80;
do
sleep 1;
done;
echo .NET Client test container ready. Running test that uses WebApplicationFactory TestServer to start WebApp with KafkaAdmin background service
echo This runs successfully in a local development environment on MacOS and Ubuntu Linux 16.04.
echo This fails when running on a GitLab CI Server. It can be seen that the test server bootstraps the WebApp.....
echo The KafkaAdmin background service blocks when requesting topic creation from the kafka service
dotnet test --runtime linux-musl-x64 -c Release --no-restore --nologo tests/KafkaAdmin.Kafka.IntegrationTests/
netclient-run:
build:
context: ../
dockerfile: docker/Dockerfile
container_name: netclient-run
image: dcs3spp/netclient
networks:
- camnet
depends_on:
- kafka
entrypoint: []
command:
- bash
- -c
- |-
echo 'Giving Kafka a bit of time to start up…'
while ! nc -z kafka 9092;
do
sleep 1;
done;
echo .NET Run Web App Ready. Starting WebApp that contains KafkaAdmin background service.
dotnet run --runtime linux-musl-x64 -c Release --no-restore --project src/KafkaAdmin.WebApp/
networks:
camnet:
xUnit Test Stub
namespace KafkaAdmin.Kafka.IntegrationTests
{
public class ApiControllerTest
{
[Fact]
public void ApiControllerTest_Ping_Returns_Pong()
{
var appFactory = new WebApplicationFactory<WebApp.Startup>();
/** THIS CODE HANGS ON GITLAB.COM CI BUT RUNS LOCALLY **/
using (var client = appFactory.CreateClient())
{
Console.WriteLine("WE ARE IN THE TEST HERE");
}
}
}
}