I am struggling to understand service containers and have some simple scenario working. The documentation here: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/service-containers?view=azure-devops&tabs=yaml is not very clear to me, and the examples are not even valid (see https://github.com/MicrosoftDocs/vsts-docs/issues/4187
I'd like to have DevOps CI/CD work with my tests with a container running and accessible at certain Uri so that my tests can run in DevOps as they run locally.
For this example I am using Azurite docker image. If I run the container locally with the following:
version: '3'
services:
sqlserver:
image: mcr.microsoft.com/azure-storage/azurite:3.6.0
restart: always
ports:
- 10000:10000
- 10001:10001
# Run
# docker-compose -f azurite.yml up -d
I can connect from my integration tests to this container to run the tests against, by using the following Uri: http://127.0.0.1:10000/devstoreaccount1/landing
In other words, my tests work well locally when accessing 127.0.0.1:10000 because there's a container listening on that address.
I need my tests to work also in Azure DevOps CI/CD so I have the following multi-stage pipelines:
trigger:
- master
pool:
vmImage: ubuntu-18.04
variables:
- group: nuget-variables
- name: NUGET_FOLDER_NAME
value: nupkgs
- name: PIPELINE_ARTIFACT_NAME
value: $(Build.BuildNumber)
- name: PATH_PIPELINE_ARTIFACT_NAME
value: $(Pipeline.Workspace)/$(PIPELINE_ARTIFACT_NAME)
- name: NUGET_API_KEY
value: $(nuget-api-key)
- name: NUGET_FEED
value: $(nuget-feed)
- name: PRERELEASE_SUFFIX
value: $(nuget-prerelease-suffix)
resources:
containers:
- container: azurite
image: mcr.microsoft.com/azure-storage/azurite:3.6.0
ports:
- 10000:10000
- 10001:10001
stages:
- stage:
displayName: 'Build'
jobs:
- job: 'Build'
displayName: 'Build & Create nuGet Package'
services:
azurite: azurite
steps:
- task: UseDotNet@2
displayName: 'Use .NET Core sdk 3.1'
inputs:
packageType: sdk
version: 3.1.x
includePreviewVersions: false
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: NuGetAuthenticate@0
displayName: 'Authenticate in NuGet feed'
- script: dotnet restore --no-cache --force
displayName: 'Restore dependencies'
- script: dotnet build --configuration Release --no-restore
displayName: 'Build with Release Configuration'
- script: dotnet vstest test/*UnitTests/bin/Release/**/*UnitTests.dll
displayName: 'Run unit tests'
- script: dotnet vstest test/*IntegrationTests/bin/Release/**/*IntegrationTests.dll
displayName: 'Run integration tests'
- script: dotnet pack *.sln --configuration Release --output $(NUGET_FOLDER_NAME) --include-symbols -p:SymbolPackageFormat=snupkg
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
displayName: 'Create release nuGet'
- publish: $(System.DefaultWorkingDirectory)/$(NUGET_FOLDER_NAME)
artifact: $(PIPELINE_ARTIFACT_NAME)
displayName: 'Publish pipeline artifact'
- stage:
displayName: 'Release'
condition: succeeded()
jobs:
- job: 'Publish'
displayName: 'Publish nuGet Package'
steps:
- download: current
artifact: $(PIPELINE_ARTIFACT_NAME)
displayName: 'Download pipeline artifact'
- script: echo More irrelevant things here
As you can see, I specify the image for Azurite, do the mapping ports, etc. but my tests fail because they cannot connect to http://127.0.0.1:10000/devstoreaccount1/landing
I've tried naming the container and replacing the Uri in my tests to try to connect to http://azurite:10000/devstoreaccount1/landing
If I place the services section outsite a job just before stages it fails as invalid YML.
I don't really understand how to achieve the equivalent to my docker-compose with Azure DevOps to have my tests pass in CI/CD. Hopefully you spot the problem or provide an understandable explanation on how this works. Also, if anybody knows how could I "debug" this locally, I'd be more than happy to learn some tricks.
UPDATE 1: I don't know why, but now it worked with 127.0.0.1 Uri and the above yml (services defined at the job where integration tests run).
The question remains though, and any good explanation on why this works and referring with the name azurite didn't would be the valid answer.