testcontainers / testcontainers-dotnet

A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions.
https://dotnet.testcontainers.org
MIT License
3.82k stars 279 forks source link

[Bug]: Error SSL connecting to CosmosDb container by Untrusted root #931

Closed felipe-rodrigues closed 1 year ago

felipe-rodrigues commented 1 year ago

Testcontainers version

3.2.0

Using the latest Testcontainers version?

Yes

Host OS

Windows

Host arch

x64

.NET version

6.0.2

Docker version

Client:
 Cloud integration: v1.0.33
 Version:           24.0.2
 API version:       1.43
 Go version:        go1.20.4
 Git commit:        cb74dfc
 Built:             Thu May 25 21:53:15 2023
 OS/Arch:           windows/amd64
 Context:           default

Server: Docker Desktop 4.20.1 (110738)
 Engine:
  Version:          24.0.2
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.4
  Git commit:       659604f
  Built:            Thu May 25 21:52:17 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker info

Client:
 Version:    24.0.2
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.10.5
    Path:     C:\Program Files\Docker\cli-plugins\docker-buildx.exe
  compose: Docker Compose (Docker Inc.)
    Version:  v2.18.1
    Path:     C:\Program Files\Docker\cli-plugins\docker-compose.exe
  dev: Docker Dev Environments (Docker Inc.)
    Version:  v0.1.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-dev.exe
  extension: Manages Docker extensions (Docker Inc.)
    Version:  v0.2.19
    Path:     C:\Program Files\Docker\cli-plugins\docker-extension.exe
  init: Creates Docker-related starter files for your project (Docker Inc.)
    Version:  v0.1.0-beta.4
    Path:     C:\Program Files\Docker\cli-plugins\docker-init.exe
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
    Version:  0.6.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-sbom.exe
  scan: Docker Scan (Docker Inc.)
    Version:  v0.26.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-scan.exe
  scout: Command line tool for Docker Scout (Docker Inc.)
    Version:  v0.12.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-scout.exe

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 53
 Server Version: 24.0.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 3dce8eb055cbb6872793272b4f20ed16117344f8
 runc version: v1.1.7-0-g860f061
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 4.19.128-microsoft-standard
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 7.774GiB
 Name: docker-desktop
 ID: 49464339-ef2a-48b1-879d-45c0680c3cc7
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  127.0.0.0/8
 Live Restore Enabled: false

What happened?

I'm trying to create tests for an application that uses CosmosDb with EntityFramework Core.

I'm getting:

System.Net.Http.HttpRequestException : The SSL connection could not be established, see inner exception. ---- System.Security.Authentication.AuthenticationException : The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot

Relevant log output

No response

Additional information

EfCore Context

public class MyContext : DbContext
    {
        public MyContext()
        {
        }

        public MyContext(DbContextOptions<MyContext> options) : base(options)
        {

        }

        public DbSet<MyEntity> MyEntities { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasDefaultContainer("test");

            modelBuilder.Entity<MyEntity>();
        }
    }

    public class MyEntity
    {
        public Guid Id { get; set; }
    }

TestClass:

public class UnitTest1
    {

        private IServiceProvider _serviceProvider;
        private CosmosDbContainer _container;

        public UnitTest1()
        {
            _container = new CosmosDbBuilder()
                .Build();

        }

        [Fact]
        public async Task ConnectionShouldWork()
        {

            await _container.StartAsync();

             var connectionString = _container.GetConnectionString();

            var services = new ServiceCollection();
            services.AddDbContext<MyContext>(options => options.UseCosmos(connectionString,"test"));
            _serviceProvider = services.BuildServiceProvider();

            using (var dbContext = _serviceProvider.GetRequiredService<MyContext>())
            {
                Assert.True(dbContext.Database.EnsureCreated());
            }

        }
    }
HofmeisterAn commented 1 year ago

Use the container's provided HTTP client (it is pre-configured to trust the CosmosDb Emulator's certificate):

https://github.com/testcontainers/testcontainers-dotnet/blob/0ecda30d424730ce45205adb9ac567306f35d3b3/tests/Testcontainers.CosmosDb.Tests/CosmosDbContainerTest.cs#L22-L28

felipe-rodrigues commented 1 year ago

Thank you @HofmeisterAn.

I'm using efcore to connect with the database. There is one configuration on the setup I needed to do. but it was very close wit your solution.

 ///  _container = new CosmosDbBuilder().Build();

 var options = new DbContextOptionsBuilder<MyContext>()
                                       .UseCosmos(connection, databaseName: "test", (options) =>
                                       {
                                           options.HttpClientFactory(() => _container..HttpClient);
                                           options.RequestTimeout(TimeSpan.FromSeconds(5));
                                           options.ConnectionMode(Microsoft.Azure.Cosmos.ConnectionMode.Gateway);
                                       })
                                       .Options;

                    services.AddSingleton(sp => options);
                    services.AddScoped<MyContext>();