testcontainers-dotnet icon indicating copy to clipboard operation
testcontainers-dotnet copied to clipboard

Fix: Configuration providers provide current values

Open vlaskal opened this issue 3 years ago • 5 comments
trafficstars

Configuration providers provide current value from environment variables or setting file. This is suggestion how to fix issue #576 to make test runnable nd independent on the order.

vlaskal avatar Sep 07 '22 11:09 vlaskal

This solution will work even for this test modification for TLS:

[CollectionDefinition(nameof(DockerEndpointAuthenticationProviderTest), DisableParallelization = true)]
  [Collection(nameof(DockerEndpointAuthenticationProviderTest))]
  public sealed class DockerEndpointAuthenticationProviderTest
  {
    [Theory]
    [ClassData(typeof(AuthConfigTestData))]
    public void GetDockerClientConfiguration(IDockerEndpointAuthenticationConfiguration authConfig, Uri expectedDockerClientEndpoint)
    {
      using (var dockerClientConfiguration = authConfig.GetDockerClientConfiguration())
      {
        Assert.Equal(expectedDockerClientEndpoint, authConfig.Endpoint);
        Assert.Equal(expectedDockerClientEndpoint, dockerClientConfiguration.EndpointBaseUri);
      }
    }

    private sealed class AuthConfigTestData : List<object[]>
    {
      public AuthConfigTestData()
      {
        const string dockerHostVariableName = "DOCKER_HOST";
        const string dockerHost = "tcp://127.0.0.1:2375";
        const string dockerHostTls = "tcp://127.0.0.1:2376";

        var originalDockerHostvalue = Environment.GetEnvironmentVariable(dockerHostVariableName);

        Environment.SetEnvironmentVariable(dockerHostVariableName, dockerHostTls);
        this.Add(new object[] { new TlsEndpointAuthenticationProvider().GetAuthConfig(), new Uri(dockerHostTls) });

        Environment.SetEnvironmentVariable(dockerHostVariableName, dockerHost);
        this.Add(new object[] { new EnvironmentEndpointAuthenticationProvider().GetAuthConfig(), new Uri(dockerHost) });
        this.Add(new object[] { new NpipeEndpointAuthenticationProvider().GetAuthConfig(), new Uri("npipe://./pipe/docker_engine") });
        this.Add(new object[] { new UnixEndpointAuthenticationProvider().GetAuthConfig(), new Uri("unix:/var/run/docker.sock") });

        Environment.SetEnvironmentVariable(dockerHostVariableName, originalDockerHostvalue);
      }
    }
  }

vlaskal avatar Sep 07 '22 11:09 vlaskal

I am not sure but this bug is about environment configuration problem and not about TLS. I think mixing environment configuration with settings files does not make sense to me. Maybe I am blind., but I thin that tls should not be as argument for EnvironmentEndpointAuthenticationProvider which should provide that value. I do not see solution for current situation.

vlaskal avatar Sep 07 '22 20:09 vlaskal

My example is poorly chosen - sorry. Forget about GetDockerTls(), etc. I meant to say that all you need is DI. The singleton makes the class difficult to test, DI solves that. My example above is showing the idea with different custom configurations.

An authentication provider depend on the custom configuration. Overload the constructor with ICustomConfiguration. The default constructor will fall back to the singleton instances. Your tests will use the overloaded constructor, specific with the custom configuration you need (very common pattern).

Overload the constructor with either params ICustomConfiguration[] customConfigurations or ICustomConfiguration propertiesFileConfiguration, ICustomConfiguration environmentConfiguration. For now, I personally prefer the first one, it is easier to set up in the tests. Does that help?

HofmeisterAn avatar Sep 08 '22 04:09 HofmeisterAn

@HofmeisterAn Sorry for late answer. I will update it.

vlaskal avatar Sep 16 '22 18:09 vlaskal

Fix was updated based on suggestion and covered by one mroe test.

vlaskal avatar Sep 18 '22 19:09 vlaskal

f0f112bd53cc4c1ff8dcbb2001334a1b36a9f487, closes #576.

HofmeisterAn avatar Sep 29 '22 13:09 HofmeisterAn