Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly set the Docker socket on Windows #1458

Merged
merged 65 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
8cb75b9
fix: set Windows' USERPROFILE env var alongside Unix's HOME
mdelapenya Aug 8, 2023
c0fbb3e
chore: skip Docker rootless tests on Windows
mdelapenya Aug 8, 2023
077cbd8
chore: initialise Docker socket path on Windows properly
mdelapenya Aug 8, 2023
25ac922
docs: document socket paths
mdelapenya Aug 8, 2023
6875dcc
chore: proper skip in tests
mdelapenya Aug 8, 2023
0ca8201
chore: log Docekr socket path in the DockerServerInfo
mdelapenya Aug 8, 2023
7a784b1
fix: the Docker client retrieves the socket path properly
mdelapenya Aug 8, 2023
c4f41b4
fix: explicitly skip subtests for rootless
mdelapenya Aug 8, 2023
f4929c2
fix: initialise socketPath
mdelapenya Aug 8, 2023
97b686e
fix: use proper eval if windows
mdelapenya Aug 8, 2023
c97d75f
revert: print docker host
mdelapenya Aug 8, 2023
7b18d0a
fix: print the resolved docker host, not the constant
mdelapenya Aug 8, 2023
903a1ab
fix: wrong assignment to variable
mdelapenya Aug 8, 2023
0e7fdb6
chore: simplify initialisation of socket path on Windows
mdelapenya Aug 8, 2023
e882279
chore: do not build unix on windows
mdelapenya Aug 8, 2023
43cce61
fix: proper compilation
mdelapenya Aug 8, 2023
881e37f
fix: define docker socket mount path
mdelapenya Aug 8, 2023
c96a6f0
fix: compile
mdelapenya Aug 8, 2023
699f649
fix: reverse logic to skip windows tests
mdelapenya Aug 8, 2023
3666417
Revert "revert: print docker host"
mdelapenya Aug 8, 2023
59f344c
revert: print Docker info
mdelapenya Aug 8, 2023
fb11a53
fix: variable value
mdelapenya Aug 8, 2023
c14750a
Revert "revert: print Docker info"
mdelapenya Aug 8, 2023
729ac05
revert: print log
mdelapenya Aug 8, 2023
200f532
chore: do not hardcode schema in test expectations
mdelapenya Aug 8, 2023
2394dae
fix: resolve error while cleaning up test resources
mdelapenya Aug 8, 2023
d8c1fde
fix: mount docker socket
mdelapenya Aug 8, 2023
1f1dd39
chore: negate build condition for windows
mdelapenya Aug 8, 2023
52120fd
Revert "chore: negate build condition for windows"
mdelapenya Aug 8, 2023
f6e1818
fix: priority in tests
mdelapenya Aug 8, 2023
31d08ca
chore: rename windows job
mdelapenya Aug 8, 2023
dbbde5b
chore: bring back initial approach
mdelapenya Aug 8, 2023
f085ffc
chore: add a docker host strategy for windows
mdelapenya Aug 8, 2023
c6f0c05
Revert "revert: print log"
mdelapenya Aug 8, 2023
c124335
fix: set the schema too
mdelapenya Aug 8, 2023
f6863fe
fix: skip on windows
mdelapenya Aug 8, 2023
777cff3
fix: include schema
mdelapenya Aug 8, 2023
0592cfc
chore: refine for windows socket path
mdelapenya Aug 9, 2023
44e6fd6
fix: skip test for Windows
mdelapenya Aug 9, 2023
fbcb850
chore: print docker host and docker socket path
mdelapenya Aug 9, 2023
0fb9b76
fix: use filepath for building test paths
mdelapenya Aug 9, 2023
fac0eee
revert: print networks after inspect
mdelapenya Aug 9, 2023
cdf2487
Merge branch 'main' into windows-tests
mdelapenya Aug 9, 2023
2de8a61
Merge branch 'main' into windows-tests
mdelapenya Aug 9, 2023
2d2bd69
fix: wrong replacement
mdelapenya Aug 9, 2023
569f89f
fix: close file before removing it
mdelapenya Aug 9, 2023
6d01b99
chore: combine function into its test
mdelapenya Aug 9, 2023
a257e8d
chore: skip test for windows
mdelapenya Aug 9, 2023
c8bb7a2
chore: adjust log
mdelapenya Aug 9, 2023
e329173
chore: increase timeout for listening to a port
mdelapenya Aug 9, 2023
72afda4
chore: move testss for BindMounts and VolumeMounts to its test file
mdelapenya Aug 9, 2023
51ac8ec
Merge branch 'main' into windows-tests
mdelapenya Aug 9, 2023
07811cb
chore: triple max timeout for the workflow run, which takes +10m
mdelapenya Aug 9, 2023
addea99
Revert "chore: triple max timeout for the workflow run, which takes +…
mdelapenya Aug 9, 2023
f174a0c
Merge branch 'main' into windows-tests
mdelapenya Aug 9, 2023
5b55d7a
Merge branch 'main' into windows-tests
mdelapenya Aug 9, 2023
9fb77de
fix: more filepaths
mdelapenya Aug 9, 2023
3b069bb
chore: skip podman provider tests on windows
mdelapenya Aug 9, 2023
37d73bb
chore: remove invalida comment
mdelapenya Aug 10, 2023
03ee221
chore: increase wait timeout forHTTP in test
mdelapenya Aug 10, 2023
2fa6dbd
chore: get Docker host from the resolution strategy
mdelapenya Aug 10, 2023
9d1b349
chore: increase wait timeout forHTTP in tests
mdelapenya Aug 10, 2023
243547a
Merge branch 'main' into windows-tests
mdelapenya Aug 10, 2023
f2415eb
chore: keep get provider for podman as it was
mdelapenya Aug 10, 2023
22deaad
chore: remove log
mdelapenya Aug 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
types: [windows-test-command]

jobs:
docker:
test-windows:
# At the moment, we are running a self-hosted runner on Windows 2022.
runs-on: [self-hosted, Windows, X64]
strategy:
Expand Down
1 change: 1 addition & 0 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func TestReadConfig(t *testing.T) {

t.Run("Config is read just once", func(t *testing.T) {
t.Setenv("HOME", "")
t.Setenv("USERPROFILE", "") // Windows support
t.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true")

cfg := ReadConfig()
Expand Down
110 changes: 21 additions & 89 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go/internal/testcontainersdocker"
"github.com/testcontainers/testcontainers-go/wait"
)

Expand Down Expand Up @@ -326,99 +325,32 @@ func TestShouldStartContainersInParallel(t *testing.T) {
t.Cleanup(cancel)

for i := 0; i < 3; i++ {
i := i
t.Run(fmt.Sprintf("iteration_%d", i), func(t *testing.T) {
t.Parallel()
createTestContainer(t, ctx)
})
}
}

func createTestContainer(t *testing.T, ctx context.Context) int {
req := ContainerRequest{
Image: nginxAlpineImage,
ExposedPorts: []string{nginxDefaultPort},
WaitingFor: wait.ForHTTP("/"),
}
container, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
t.Fatalf("could not start container: %v", err)
}
// mappedPort {
port, err := container.MappedPort(ctx, nginxDefaultPort)
// }
if err != nil {
t.Fatalf("could not get mapped port: %v", err)
}

terminateContainerOnEnd(t, ctx, container)

return port.Int()
}

func TestBindMount(t *testing.T) {
t.Parallel()

dockerSocket := testcontainersdocker.ExtractDockerSocket(context.Background())
req := ContainerRequest{
Image: nginxAlpineImage,
ExposedPorts: []string{nginxDefaultPort},
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
container, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
t.Fatalf("could not start container: %v", err)
}
// mappedPort {
port, err := container.MappedPort(ctx, nginxDefaultPort)
// }
if err != nil {
t.Fatalf("could not get mapped port: %v", err)
}

type args struct {
hostPath string
mountTarget ContainerMountTarget
}
tests := []struct {
name string
args args
want ContainerMount
}{
{
name: dockerSocket + ":" + dockerSocket,
args: args{hostPath: dockerSocket, mountTarget: "/var/run/docker.sock"},
want: ContainerMount{Source: GenericBindMountSource{HostPath: dockerSocket}, Target: "/var/run/docker.sock"},
},
{
name: "/var/lib/app/data:/data",
args: args{hostPath: "/var/lib/app/data", mountTarget: "/data"},
want: ContainerMount{Source: GenericBindMountSource{HostPath: "/var/lib/app/data"}, Target: "/data"},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
assert.Equalf(t, tt.want, BindMount(tt.args.hostPath, tt.args.mountTarget), "BindMount(%v, %v)", tt.args.hostPath, tt.args.mountTarget)
})
}
}
terminateContainerOnEnd(t, ctx, container)

func TestVolumeMount(t *testing.T) {
t.Parallel()
type args struct {
volumeName string
mountTarget ContainerMountTarget
}
tests := []struct {
name string
args args
want ContainerMount
}{
{
name: "sample-data:/data",
args: args{volumeName: "sample-data", mountTarget: "/data"},
want: ContainerMount{Source: GenericVolumeMountSource{Name: "sample-data"}, Target: "/data"},
},
{
name: "web:/var/nginx/html",
args: args{volumeName: "web", mountTarget: "/var/nginx/html"},
want: ContainerMount{Source: GenericVolumeMountSource{Name: "web"}, Target: "/var/nginx/html"},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
assert.Equalf(t, tt.want, VolumeMount(tt.args.volumeName, tt.args.mountTarget), "VolumeMount(%v, %v)", tt.args.volumeName, tt.args.mountTarget)
t.Logf("Parallel container [iteration_%d] listening on %d\n", i, port.Int())
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion docker_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func removeImageFromLocalCache(t *testing.T, image string) {
PruneChildren: true,
})
if err != nil {
t.Logf("could not remove image %s: %v", image, err)
t.Logf("could not remove image %s: %v\n", image, err)
}
}

Expand Down
51 changes: 26 additions & 25 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestContainerWithNetworkModeAndNetworkTogether(t *testing.T) {
nginx, err := GenericContainer(ctx, gcr)
if err != nil {
// Error when NetworkMode = host and Network = []string{"bridge"}
t.Logf("Can't use Network and NetworkMode together, %s", err)
t.Logf("Can't use Network and NetworkMode together, %s\n", err)
}
terminateContainerOnEnd(t, ctx, nginx)
}
Expand Down Expand Up @@ -658,7 +658,7 @@ func TestContainerTerminationRemovesDockerImage(t *testing.T) {

req := ContainerRequest{
FromDockerfile: FromDockerfile{
Context: "./testdata",
Context: filepath.Join(".", "testdata"),
},
ExposedPorts: []string{"6379/tcp"},
WaitingFor: wait.ForLog("Ready to accept connections"),
Expand Down Expand Up @@ -970,15 +970,14 @@ func TestContainerCreationTimesOut(t *testing.T) {
func TestContainerRespondsWithHttp200ForIndex(t *testing.T) {
ctx := context.Background()

// delayed-nginx will wait 2s before opening port
nginxC, err := GenericContainer(ctx, GenericContainerRequest{
ProviderType: providerType,
ContainerRequest: ContainerRequest{
Image: nginxAlpineImage,
ExposedPorts: []string{
nginxDefaultPort,
},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
},
Started: true,
})
Expand Down Expand Up @@ -1075,7 +1074,7 @@ func Test_BuildContainerFromDockerfileWithBuildArgs(t *testing.T) {
t.Log("got ctx, creating container request")
req := ContainerRequest{
FromDockerfile: FromDockerfile{
Context: "./testdata",
Context: filepath.Join(".", "testdata"),
Dockerfile: "args.Dockerfile",
BuildArgs: map[string]*string{
"FOO": &ba,
Expand Down Expand Up @@ -1128,7 +1127,7 @@ func Test_BuildContainerFromDockerfileWithBuildLog(t *testing.T) {
// fromDockerfile {
req := ContainerRequest{
FromDockerfile: FromDockerfile{
Context: "./testdata",
Context: filepath.Join(".", "testdata"),
Dockerfile: "buildlog.Dockerfile",
PrintBuildLog: true,
},
Expand Down Expand Up @@ -1277,7 +1276,7 @@ func ExampleDockerProvider_CreateContainer() {
req := ContainerRequest{
Image: "docker.io/nginx:alpine",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
nginxC, _ := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -1295,7 +1294,7 @@ func ExampleContainer_Host() {
req := ContainerRequest{
Image: "docker.io/nginx:alpine",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
nginxC, _ := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -1317,7 +1316,7 @@ func ExampleContainer_Start() {
req := ContainerRequest{
Image: "docker.io/nginx:alpine",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
nginxC, _ := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -1335,7 +1334,7 @@ func ExampleContainer_Stop() {
req := ContainerRequest{
Image: "docker.io/nginx:alpine",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
nginxC, _ := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -1354,7 +1353,7 @@ func ExampleContainer_MappedPort() {
req := ContainerRequest{
Image: "docker.io/nginx:alpine",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
nginxC, _ := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -1373,7 +1372,7 @@ func ExampleContainer_MappedPort() {
}

func TestContainerCreationWithBindAndVolume(t *testing.T) {
absPath, err := filepath.Abs("./testdata/hello.sh")
absPath, err := filepath.Abs(filepath.Join(".", "testdata", "hello.sh"))
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1605,7 +1604,7 @@ func TestDockerContainerCopyFileToContainer(t *testing.T) {
terminateContainerOnEnd(t, ctx, nginxC)

copiedFileName := "hello_copy.sh"
_ = nginxC.CopyFileToContainer(ctx, "./testdata/hello.sh", "/"+copiedFileName, 700)
_ = nginxC.CopyFileToContainer(ctx, filepath.Join(".", "testdata", "hello.sh"), "/"+copiedFileName, 700)
c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -1646,7 +1645,7 @@ func TestDockerContainerCopyDirToContainer(t *testing.T) {

func TestDockerCreateContainerWithFiles(t *testing.T) {
ctx := context.Background()
hostFileName := "./testdata/hello.sh"
hostFileName := filepath.Join(".", "testdata", "hello.sh")
copiedFileName := "/hello_copy.sh"
tests := []struct {
name string
Expand All @@ -1673,9 +1672,7 @@ func TestDockerCreateContainerWithFiles(t *testing.T) {
},
},
errMsg: "can't copy " +
"./testdata/hello.sh123 to container: open " +
"./testdata/hello.sh123: no such file or directory: " +
"failed to create container",
hostFileName + "123 to container: open " + hostFileName + "123",
},
}

Expand Down Expand Up @@ -1738,7 +1735,7 @@ func TestDockerCreateContainerWithDirs(t *testing.T) {
{
name: "success copy directory",
dir: ContainerFile{
HostFilePath: filepath.Join("./", hostDirName),
HostFilePath: filepath.Join(".", hostDirName),
ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist
FileMode: 700,
},
Expand All @@ -1747,16 +1744,16 @@ func TestDockerCreateContainerWithDirs(t *testing.T) {
{
name: "host dir not found",
dir: ContainerFile{
HostFilePath: "./testdata123", // does not exist
ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist
HostFilePath: filepath.Join(".", "testdata123"), // does not exist
ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist
FileMode: 700,
},
hasError: true,
},
{
name: "container dir not found",
dir: ContainerFile{
HostFilePath: "./" + hostDirName,
HostFilePath: filepath.Join(".", hostDirName),
ContainerFilePath: "/parent-does-not-exist/testdata123", // does not exist
FileMode: 700,
},
Expand Down Expand Up @@ -1805,7 +1802,7 @@ func TestDockerContainerCopyToContainer(t *testing.T) {

copiedFileName := "hello_copy.sh"

fileContent, err := os.ReadFile("./testdata/hello.sh")
fileContent, err := os.ReadFile(filepath.Join(".", "testdata", "hello.sh"))
if err != nil {
t.Fatal(err)
}
Expand All @@ -1820,7 +1817,7 @@ func TestDockerContainerCopyToContainer(t *testing.T) {
}

func TestDockerContainerCopyFileFromContainer(t *testing.T) {
fileContent, err := os.ReadFile("./testdata/hello.sh")
fileContent, err := os.ReadFile(filepath.Join(".", "testdata", "hello.sh"))
if err != nil {
t.Fatal(err)
}
Expand All @@ -1840,7 +1837,7 @@ func TestDockerContainerCopyFileFromContainer(t *testing.T) {
terminateContainerOnEnd(t, ctx, nginxC)

copiedFileName := "hello_copy.sh"
_ = nginxC.CopyFileToContainer(ctx, "./testdata/hello.sh", "/"+copiedFileName, 700)
_ = nginxC.CopyFileToContainer(ctx, filepath.Join(".", "testdata", "hello.sh"), "/"+copiedFileName, 700)
c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -1879,7 +1876,7 @@ func TestDockerContainerCopyEmptyFileFromContainer(t *testing.T) {
terminateContainerOnEnd(t, ctx, nginxC)

copiedFileName := "hello_copy.sh"
_ = nginxC.CopyFileToContainer(ctx, "./testdata/empty.sh", "/"+copiedFileName, 700)
_ = nginxC.CopyFileToContainer(ctx, filepath.Join(".", "testdata", "empty.sh"), "/"+copiedFileName, 700)
c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -1955,6 +1952,10 @@ func TestDockerContainerResources(t *testing.T) {
}

func TestContainerWithReaperNetwork(t *testing.T) {
if testcontainersdocker.IsWindows() {
t.Skip("Skip for Windows. See https://stackoverflow.com/questions/43784916/docker-for-windows-networking-container-with-multiple-network-interfaces")
}

ctx := context.Background()
networks := []string{
"test_network_" + randomString(),
Expand Down
2 changes: 1 addition & 1 deletion docs/features/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Path to Docker's socket. Used by Ryuk, Docker Compose, and a few other container

Example: `/var/run/docker-alt.sock`

3. If the Operative System retrieved by the Docker client is "Docker Desktop", return the default docker socket path for rootless docker.
3. If the Operative System retrieved by the Docker client is "Docker Desktop", and the host is running on Windows, it will return the `//var/run/docker.sock` UNC Path. Else return the default docker socket path for rootless docker.

4. Get the current Docker Host from the existing strategies: see [Docker host detection](#docker-host-detection).

Expand Down
3 changes: 2 additions & 1 deletion examples/nginx/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nginx
import (
"context"
"fmt"
"time"

"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
Expand All @@ -17,7 +18,7 @@ func startContainer(ctx context.Context) (*nginxContainer, error) {
req := testcontainers.ContainerRequest{
Image: "nginx",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForHTTP("/"),
WaitingFor: wait.ForHTTP("/").WithStartupTimeout(10 * time.Second),
}
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Expand Down