testenvironment-docker icon indicating copy to clipboard operation
testenvironment-docker copied to clipboard

Review/Improve library API

Open Deffiss opened this issue 4 years ago • 8 comments

Deffiss avatar Apr 24 '20 07:04 Deffiss

Below you can find my thoughts of configuration options messed up with possible new functionality... What we can configure now:

  • container name
  • image name
  • image tag
  • environment variables
  • port forwardings
  • way of container waiting (probably we need to introduce pre-built waiters for file or port(current HttpContainerWaiter) in container?)
  • way of container cleaning
  • indicate that container is reusable
  • logger

Which configuration we can introduce:

  • container label
  • working directory
  • command
  • entry point
  • dockerfile (probably we need to get rid of container_from_dockerfile as separate entity and move it to common configuration and somehow respect .dockerignore)
  • std output consumer (? via using Docker.Containers.AttachContainerAsync ?)
  • dependent container

There are several ways of providing such configuration Builder pattern:

var container = new ContainerBuilder()
    .SetName("postgres")
    .SetPorts(5000, 5001)
    .SetEnvironment(...)
    .Build()

Options way:

var options = new ContainerCreationOptions
{
    Name = "postgres",
    Ports = new Dictionary<int, int> { { 5000, 5001 } },
    Environment = ...
};
var container = new Container(options);

Hellevar avatar May 14 '20 17:05 Hellevar

Also it might worth to try integrate dockerignore feature based on this library

Hellevar avatar May 15 '20 05:05 Hellevar

Both configuration options looks good but building nicely looking Fluent API might be difficult. That's why second option looks a bit more realistic. Also would be interesting to see how this might look for specific containers like Mssql or Mongo. In terms of new features, all of them deserve to be introduced but let's prioritize them first and implement as a separate issues.

Deffiss avatar May 15 '20 07:05 Deffiss

There are several ways of providing such configuration Builder pattern:

var container = new ContainerBuilder()
    .SetName("postgres")
    .SetPorts(5000, 5001)
    .SetEnvironment(...)
    .Build()

How about FluentMigrator-like syntax:

public static class ContainerNames
{
  public static readonly string Postgres = "postgres";
}
public static class EnvironmentNames
{
  public static readonly string Production = "Production";
}
public static class LabelNames
{
  public static readonly string IntegrationTest = "IntegrationTest";
}
var iContainerSyntax = Create.Container(ContainerNames.Postgres)
  .Ports(5000, 5001)
  .Environment(EnvironmentNames.Production)
  .Labels(LabelNames.IntegrationTest)
  .Build(); // builds object

I removed the Set prefix as it interferes with intellisense and minimizing keystrokes to get to an autocompletion result.

May also want to consider @kzu library for hiding certain things from IntelliSense. https://github.com/kzu/IFluentInterface

jzabroski avatar May 15 '20 15:05 jzabroski

@Deffiss @Hellevar Thoughts on my proposal above?

Another slight tweak would be, instead of .Build(); simply .Do(); I've also used .BuildIt(); in the past.

jzabroski avatar May 29 '20 16:05 jzabroski

Another thought is that you can have the fluent syntax do something like:

var iContainerSyntax = Create.Container(ContainerNames.Postgres)
  .Ports(5000, 5001)
  .Environment(EnvironmentNames.Production)
  .Labels(LabelNames.IntegrationTest)
  .Entrypoint("RUN.CMD")
  // generates a file named "dockerfile" from the above instructions
  .SaveAsDockerfile(System.IO.Directory.GetCurrentDirectory())
  //.Build() // optional debug step to build the image from the dockerfile
  .Run(); // runs the dockerfile

This would allow you to share dockerfiles with other teams. And since you have a way to specify labels, and also C# compiler metadata functions like CallerMemberName, you can comment the generated dockerfile so people know how you achieved it.

jzabroski avatar Jun 02 '20 17:06 jzabroski

@jzabroski Right now we are trying to understand what will be more convenient for usage - fluent notation or just options with properties. Soon we will see some PRs and be able to compare. Your opinion would be appreciated. The idea to expose a dockerfile deserves separate feature thread.

Deffiss avatar Jun 03 '20 07:06 Deffiss

@Deffiss I think my core observation is whether .Build() should build an image, or build an object. The more I think about it, it should be Build an image. That's why the dockerfile idea is material. (Although, I think you might be able to dump from the docker image the effective dockerfile, I'm not sure how it works when you construct an image and run it from the API.)

jzabroski avatar Jun 03 '20 13:06 jzabroski