0

I have developed in Visual Studio 2017 (version 15.9.16) a simple .Net Core 2.2 unit test project that connects to a MongoDb instance enabling Container Orchrestation Support. My purpose is running a container with a MongoDb instance where the unit tests will connect to whenever they are launched from Test Explorer window. The problem I am facing is that from the unit test code I cannot connect to the MongoDb container, the service name defined in docker-compose.yml cannot be resolved.

Here are the contents of the docker-compose.yml file:

version: '3.4'

services:
  myapp:
    image: ${DOCKER_REGISTRY-}myapp
    build:
      context: .
      dockerfile: myapp/Dockerfile
    depends_on:
      - mongo
  mongo:
    image: mongo:latest

The contents of the Dockerfile of the app are the following:

FROM microsoft/dotnet:2.2-runtime AS base
WORKDIR /app

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY myapp/myapp.csproj myapp/
RUN dotnet restore myapp/myapp.csproj
COPY . .
WORKDIR /src/myapp
RUN dotnet build myapp.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish myapp.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "myapp.dll"]

Inside the unit test code, if I try to connect to the MongoDb instance using var client = new MongoClient("mongodb://mongo:27017"); when trying to write to the database I get the following exception:

A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/mongo:27017" }", EndPoint: "Unspecified/mongo:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Sockets.SocketException: Unknown host at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult) at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult) at System.Net.Dns.<>c.b__25_1(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at MongoDB.Driver.Core.Connections.TcpStreamFactory.ResolveEndPointsAsync(EndPoint initial) at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken) at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken) --- End of inner exception stack trace --- at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.ServerMonitor.HeartbeatAsync(CancellationToken cancellationToken)", LastUpdateTimestamp: "2019-10-03T10:00:40.7989018Z" }] }.'

If I try to resolve MongoDb container service name using System.Net.Dns.GetHostEntry("mongo") I get this exception:

System.Net.SocketException: 'Unknown host'

It seems clear to me that the .Net Core code inside the unit test container cannot resolve docker-compose.yml service names. On the other hand, if I start a session in the unit test container I can do a ping mongo or telnet mongo 27017 with success. I have also tried ensuring that MongoDb container has started as proposed in this question, but with no luck. Something must be missing in my code or the docker configuration files to enable service name resolution. Any help would be much appreciated.

2 Answers 2

0

You can declare a network and associate an IP adress for each service, then use the ip address of mongo service instead of resolving its hostname:

version: '3.4'

services:
  myapp:
    image: ${DOCKER_REGISTRY-}myapp
    build:
      context: .
      dockerfile: myapp/Dockerfile
    depends_on:
      - mongo
    networks:
      mynetwork:
        ipv4_address: 178.25.0.3
  mongo:
    image: mongo:latest
    networks:
      mynetwork:
        ipv4_address: 178.25.0.2

networks:
  mynetwork:
    driver: bridge
    ipam:
      config:
      - subnet: 178.25.0.0/24

MongoClient("mongodb://178.25.0.2:27017");
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your help! I am a newbie with Docker and did not know that it is possible to set fixed ip addresses to containers. But, as I mention in my answer, this could not fix the problem I reported because the reason was simply that containers where not being run from the Test Explorer window.
0

Finally I found the reason for this behavior after running System.Net.Dns.GetHostName() inside my unit test code and seeing that the returning name was the host name and not the container name. I forgot to mention that I was running my unit test from the Test Explorer window and this way container support is completely ignored. Opposite from what I expected, Docker Compose is not being invoked so neither MongoDb container nor unit test project container are launched, unit test project is just running inside the host. The feature of running unit tests in container when container support is enabled in Visual Studio is already asked at https://developercommunity.visualstudio.com/idea/554907/allow-running-unit-tests-in-docker.html. Please vote up for this feature!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.