Skip to content

Commit 1a640be

Browse files
authored
Merge pull request moby#5027 from profnandaa/integration-tests-4485
tests: enabling integration tests on windows
2 parents 7c025bf + 510428f commit 1a640be

File tree

9 files changed

+130
-44
lines changed

9 files changed

+130
-44
lines changed

.github/workflows/test-os.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
needs:
7878
- build
7979
env:
80-
TESTFLAGS: "-v --parallel=6 --timeout=30m"
80+
TESTFLAGS: "-v --timeout=60m"
8181
GOTESTSUM_FORMAT: "standard-verbose"
8282
strategy:
8383
fail-fast: false
@@ -102,7 +102,7 @@ jobs:
102102
echo "TEST_REPORT_NAME=${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.skip-integration-tests }}-${{ matrix.worker }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
103103
testFlags="${{ env.TESTFLAGS }}"
104104
if [ -n "${{ matrix.worker }}" ]; then
105-
testFlags="${testFlags} --run=//worker=${{ matrix.worker }}$"
105+
testFlags="${testFlags} --run=TestIntegration/.*/worker=${{ matrix.worker }}"
106106
fi
107107
echo "TESTFLAGS=${testFlags}" >> $GITHUB_ENV
108108
shell: bash

client/client_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6297,6 +6297,7 @@ func testExportLocalNoPlatformSplit(t *testing.T, sb integration.Sandbox) {
62976297
}
62986298

62996299
func testExportLocalNoPlatformSplitOverwrite(t *testing.T, sb integration.Sandbox) {
6300+
integration.SkipOnPlatform(t, "windows")
63006301
workers.CheckFeatureCompat(t, sb, workers.FeatureOCIExporter, workers.FeatureMultiPlatform)
63016302
c, err := New(sb.Context(), sb.Address())
63026303
require.NoError(t, err)
@@ -8131,6 +8132,7 @@ func testPullWithLayerLimit(t *testing.T, sb integration.Sandbox) {
81318132
}
81328133

81338134
func testCallInfo(t *testing.T, sb integration.Sandbox) {
8135+
integration.SkipOnPlatform(t, "windows")
81348136
workers.CheckFeatureCompat(t, sb, workers.FeatureInfo)
81358137
c, err := New(sb.Context(), sb.Address())
81368138
require.NoError(t, err)
@@ -10568,6 +10570,7 @@ func testLayerLimitOnMounts(t *testing.T, sb integration.Sandbox) {
1056810570
}
1056910571

1057010572
func testClientCustomGRPCOpts(t *testing.T, sb integration.Sandbox) {
10573+
integration.SkipOnPlatform(t, "windows")
1057110574
var interceptedMethods []string
1057210575
intercept := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
1057310576
interceptedMethods = append(interceptedMethods, method)

frontend/dockerfile/dockerfile_test.go

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,11 @@ type frontend interface {
232232
func init() {
233233
frontends := map[string]interface{}{}
234234

235+
images := integration.UnixOrWindows(
236+
[]string{"busybox:latest", "alpine:latest"},
237+
[]string{"nanoserver:latest"})
235238
opts = []integration.TestOpt{
236-
integration.WithMirroredImages(integration.OfficialImages("busybox:latest", "alpine:latest")),
239+
integration.WithMirroredImages(integration.OfficialImages(images...)),
237240
integration.WithMatrix("frontend", frontends),
238241
}
239242

@@ -256,27 +259,32 @@ func init() {
256259
func TestIntegration(t *testing.T) {
257260
integration.Run(t, allTests, opts...)
258261

259-
integration.Run(t, securityTests, append(append(opts, securityOpts...),
260-
integration.WithMatrix("security.insecure", map[string]interface{}{
261-
"granted": securityInsecureGranted,
262-
"denied": securityInsecureDenied,
263-
}))...)
264-
integration.Run(t, networkTests, append(opts,
265-
integration.WithMatrix("network.host", map[string]interface{}{
266-
"granted": networkHostGranted,
267-
"denied": networkHostDenied,
268-
}))...)
269262
integration.Run(t, lintTests, opts...)
270263
integration.Run(t, heredocTests, opts...)
271264
integration.Run(t, outlineTests, opts...)
272265
integration.Run(t, targetsTests, opts...)
273266

267+
// the rest of the tests are meant for non-Windows, skipping on Windows.
268+
integration.SkipOnPlatform(t, "windows")
269+
274270
integration.Run(t, reproTests, append(opts,
275271
// Only use the amd64 digest, regardless to the host platform
276272
integration.WithMirroredImages(map[string]string{
277273
"amd64/bullseye-20230109-slim:latest": "docker.io/amd64/debian:bullseye-20230109-slim@sha256:1acb06a0c31fb467eb8327ad361f1091ab265e0bf26d452dea45dcb0c0ea5e75",
278274
}),
279275
)...)
276+
277+
integration.Run(t, securityTests, append(append(opts, securityOpts...),
278+
integration.WithMatrix("security.insecure", map[string]interface{}{
279+
"granted": securityInsecureGranted,
280+
"denied": securityInsecureDenied,
281+
}))...)
282+
283+
integration.Run(t, networkTests, append(opts,
284+
integration.WithMatrix("network.host", map[string]interface{}{
285+
"granted": networkHostGranted,
286+
"denied": networkHostDenied,
287+
}))...)
280288
}
281289

282290
func testEmptyStringArgInEnv(t *testing.T, sb integration.Sandbox) {
@@ -389,14 +397,20 @@ echo -n $my_arg $* > /out
389397
}
390398

391399
func testEnvEmptyFormatting(t *testing.T, sb integration.Sandbox) {
392-
integration.SkipOnPlatform(t, "windows")
393400
f := getFrontend(t, sb)
394401

395-
dockerfile := []byte(`
402+
dockerfile := []byte(integration.UnixOrWindows(
403+
`
396404
FROM busybox AS build
397405
ENV myenv foo%sbar
398406
RUN [ "$myenv" = 'foo%sbar' ]
399-
`)
407+
`,
408+
`
409+
FROM nanoserver AS build
410+
ENV myenv foo%sbar
411+
RUN if %myenv% NEQ foo%sbar (exit 1)
412+
`,
413+
))
400414

401415
dir := integration.Tmpdir(
402416
t,
@@ -425,23 +439,36 @@ RUN [ "$myenv" = 'foo%sbar' ]
425439
}
426440

427441
func testDockerignoreOverride(t *testing.T, sb integration.Sandbox) {
428-
integration.SkipOnPlatform(t, "windows")
429442
f := getFrontend(t, sb)
430-
dockerfile := []byte(`
443+
dockerfile := []byte(integration.UnixOrWindows(
444+
`
431445
FROM busybox
432446
COPY . .
433447
RUN [ -f foo ] && [ ! -f bar ]
434-
`)
448+
`,
449+
`
450+
FROM nanoserver
451+
COPY . .
452+
RUN if exist foo (if not exist bar (exit 0) else (exit 1))
453+
`,
454+
))
435455

436456
ignore := []byte(`
437457
bar
438458
`)
439459

440-
dockerfile2 := []byte(`
460+
dockerfile2 := []byte(integration.UnixOrWindows(
461+
`
441462
FROM busybox
442463
COPY . .
443464
RUN [ ! -f foo ] && [ -f bar ]
444-
`)
465+
`,
466+
`
467+
FROM nanoserver
468+
COPY . .
469+
RUN if not exist foo (if exist bar (exit 0) else (exit 1))
470+
`,
471+
))
445472

446473
ignore2 := []byte(`
447474
foo
@@ -482,15 +509,22 @@ foo
482509
}
483510

484511
func testEmptyDestDir(t *testing.T, sb integration.Sandbox) {
485-
integration.SkipOnPlatform(t, "windows")
486512
f := getFrontend(t, sb)
487513

488-
dockerfile := []byte(`
514+
dockerfile := []byte(integration.UnixOrWindows(
515+
`
489516
FROM busybox
490517
ENV empty=""
491518
COPY testfile $empty
492519
RUN [ "$(cat testfile)" == "contents0" ]
493-
`)
520+
`,
521+
`
522+
FROM nanoserver
523+
COPY testfile ''
524+
RUN cmd /V:on /C "set /p tfcontent=<testfile \
525+
& if !tfcontent! NEQ contents0 (exit 1)"
526+
`,
527+
))
494528

495529
dir := integration.Tmpdir(
496530
t,

util/testutil/integration/pins.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
//go:build !windows
2+
// +build !windows
3+
14
package integration
25

36
var pins = map[string]map[string]string{

util/testutil/integration/run.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ func Run(t *testing.T, testCases []Test, opt ...TestOpt) {
189189
t.Skip("rootless")
190190
}
191191
ctx := appcontext.Context()
192-
if !strings.HasSuffix(fn, "NoParallel") {
192+
// TODO(profnandaa): to revisit this to allow tests run
193+
// in parallel on Windows in a stable way. Is flaky currently.
194+
if !strings.HasSuffix(fn, "NoParallel") && runtime.GOOS != "windows" {
193195
t.Parallel()
194196
}
195197
require.NoError(t, sandboxLimiter.Acquire(context.TODO(), 1))
@@ -273,23 +275,7 @@ func copyImagesLocal(t *testing.T, host string, images map[string]string) error
273275
}
274276

275277
func OfficialImages(names ...string) map[string]string {
276-
ns := runtime.GOARCH
277-
if ns == "arm64" {
278-
ns = "arm64v8"
279-
} else if ns != "amd64" {
280-
ns = "library"
281-
}
282-
m := map[string]string{}
283-
for _, name := range names {
284-
ref := "docker.io/" + ns + "/" + name
285-
if pns, ok := pins[name]; ok {
286-
if dgst, ok := pns[ns]; ok {
287-
ref += "@" + dgst
288-
}
289-
}
290-
m["library/"+name] = ref
291-
}
292-
return m
278+
return officialImages(names...)
293279
}
294280

295281
func withMirrorConfig(mirror string) ConfigUpdater {
@@ -439,9 +425,19 @@ func prepareValueMatrix(tc testConf) []matrixValue {
439425
return m
440426
}
441427

442-
// Skips tests on Windows
428+
// Skips tests on platform
443429
func SkipOnPlatform(t *testing.T, goos string) {
444430
if runtime.GOOS == goos {
445431
t.Skipf("Skipped on %s", goos)
446432
}
447433
}
434+
435+
// Selects between two types, returns second
436+
// argument if on Windows or else first argument.
437+
// Typically used for selecting test cases.
438+
func UnixOrWindows[T any](unix, windows T) T {
439+
if runtime.GOOS == "windows" {
440+
return windows
441+
}
442+
return unix
443+
}

util/testutil/integration/run_unix.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package integration
5+
6+
import "runtime"
7+
8+
func officialImages(names ...string) map[string]string {
9+
ns := runtime.GOARCH
10+
if ns == "arm64" {
11+
ns = "arm64v8"
12+
} else if ns != "amd64" {
13+
ns = "library"
14+
}
15+
m := map[string]string{}
16+
for _, name := range names {
17+
ref := "docker.io/" + ns + "/" + name
18+
if pns, ok := pins[name]; ok {
19+
if dgst, ok := pns[ns]; ok {
20+
ref += "@" + dgst
21+
}
22+
}
23+
m["library/"+name] = ref
24+
}
25+
return m
26+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package integration
2+
3+
func officialImages(names ...string) map[string]string {
4+
m := map[string]string{}
5+
for _, name := range names {
6+
// select available refs from the mirror map
7+
// so that we mirror only those needed for the tests
8+
if ref, ok := windowsImagesMirrorMap[name]; ok {
9+
m["library/"+name] = ref
10+
}
11+
}
12+
return m
13+
}

util/testutil/integration/util.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,12 @@ func StartCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) (func() error, error
9494
case <-ctx.Done():
9595
case <-stopped:
9696
case <-stop:
97+
// windows processes not responding to SIGTERM
98+
signal := UnixOrWindows(syscall.SIGTERM, syscall.SIGKILL)
99+
signalStr := UnixOrWindows("SIGTERM", "SIGKILL")
97100
fmt.Fprintf(cmd.Stderr, "> sending sigterm %v\n", time.Now())
98-
cmd.Process.Signal(syscall.SIGTERM)
101+
fmt.Fprintf(cmd.Stderr, "> sending %s %v\n", signalStr, time.Now())
102+
cmd.Process.Signal(signal)
99103
go func() {
100104
select {
101105
case <-stopped:

util/testutil/integration/util_windows.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ import (
1111

1212
var socketScheme = "npipe://"
1313

14+
var windowsImagesMirrorMap = map[string]string{
15+
// TODO(profnandaa): currently, amd64 only, to revisit for other archs.
16+
"nanoserver:latest": "mcr.microsoft.com/windows/nanoserver:ltsc2022",
17+
"servercore:latest": "mcr.microsoft.com/windows/servercore:ltsc2022",
18+
"busybox:latest": "registry.k8s.io/e2e-test-images/busybox@sha256:6d854ffad9666d2041b879a1c128c9922d77faced7745ad676639b07111ab650",
19+
}
20+
1421
// abstracted function to handle pipe dialing on windows.
1522
// some simplification has been made to discard timeout param.
1623
func dialPipe(address string) (net.Conn, error) {

0 commit comments

Comments
 (0)