https://github.com/thediveo/morbyd is a thin layer on top of the standard 
Docker Go client to easily build and run throw-away test Docker images and 
containers, and running commands inside them. It features a function option 
API to keep the slightly excessive Docker API option parameters at bay. 
(And large test coverage FWIW).

You might ask: why, when there's ory/dockertest/v3?

Because their Ory's proprietary Docker client (predating the canonical one) 
is incompatible with the Docker daemon's 100 CONTINUE header when streaming 
container and command stdout/stderr. I've reported this, but did not got 
any response at all, so I finally cut my losses and wrote "morbyd" to be 
able to move on. The proper Docker client allows me to easily dump and 
analyse build and container output when tests go south.

Below is how morbyd feels, compared to ory/dockertest/v3, to give you an 
idea which API design might be better suited for you (or not):

dockertest (using Gomega for assertions):

Expect(pool.Client.BuildImage(docker.BuildImageOptions{
Name:       img.Name,
ContextDir: "./test/_kindisch", // sorry, couldn't resist the pun.
Dockerfile: "Dockerfile",
BuildArgs: []docker.BuildArg{
{Name: "KINDEST_BASE_TAG", Value: test.KindestBaseImageTag},
},
OutputStream: io.Discard,
})).To(Succeed())
providerCntr := Successful(pool.RunWithOptions(
&dockertest.RunOptions{
Name:       kindischName,
Repository: img.Name,
Privileged: true,
Mounts: []string{
"/var", // well, this actually is an unnamed volume
"/dev/mapper:/dev/mapper",
"/lib/modules:/lib/modules:ro",
},
Tty: true,
}, func(hc *docker.HostConfig) {
hc.Init = false
hc.Tmpfs = map[string]string{
"/tmp": "",
"/run": "",
}
hc.Devices = []docker.Device{
{PathOnHost: "/dev/fuse"},
}
}))

morbyd (also using Gomega for assertions):

Expect(sess.BuildImage(ctx, "./test/_kindisch",
build.WithTag(img.Name),
build.WithBuildArg("KINDEST_BASE_TAG="+test.KindestBaseImageTag),
build.WithOutput(timestamper.New(GinkgoWriter)))).
Error().NotTo(HaveOccurred())
providerCntr := Successful(sess.Run(ctx, img.Name,
run.WithName(kindischName),
run.WithAutoRemove(),
run.WithPrivileged(),
run.WithSecurityOpt("label=disable"),
run.WithCgroupnsMode("private"),
run.WithVolume("/var"),
run.WithVolume("/dev/mapper:/dev/mapper"),
run.WithVolume("/lib/modules:/lib/modules:ro"),
run.WithTmpfs("/tmp"),
run.WithTmpfs("/run"),
run.WithDevice("/dev/fuse"),
run.WithCombinedOutput(timestamper.New(GinkgoWriter))))

Some of these options are not simply writing their arg in the same-name 
struct field, but instead are parsing things, preferably in the same way as 
the Docker CLI does. So the transition from CLI args to unit test args 
should be much smoother without having to dig deep into the Docker API 
parameter details.

While I tried to strive for more option completeness than just my own 
minimal viable proof, there surely a bits and pieces missing. In case 
morbyd might be interesting for you, I would be glad to hear from you and 
also missing pieces; and preferably a PR if you would be so kind.



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/34643167-7222-4e7a-a1a8-79d757c2c8fen%40googlegroups.com.

Reply via email to