Skip to content

Commit

Permalink
Merge pull request moby#5221 from profnandaa/tests-4485-part-3-docker…
Browse files Browse the repository at this point in the history
…file-lint

tests: frontend/dockerfile: add dockerfile lint tests for WCOW
  • Loading branch information
tonistiigi authored Sep 12, 2024
2 parents 1e0f685 + aa096eb commit ef2ffe9
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 57 deletions.
170 changes: 115 additions & 55 deletions frontend/dockerfile/dockerfile_lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,12 +581,16 @@ COPY Dockerfile /bar
`)
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})

dockerfile = []byte(`
FROM alpine
dockerfile = []byte(fmt.Sprintf(
`
FROM %s
RUN <<'EOT'
env
%s
EOT
`)
`,
integration.UnixOrWindows("alpine", "nanoserver"),
integration.UnixOrWindows("env", "set"),
))
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
}

Expand Down Expand Up @@ -822,12 +826,24 @@ COPY Dockerfile .
BuildErrLocation: 2,
})

dockerfile = []byte(`
ARG MY_OS=linux
osName := integration.UnixOrWindows("linux", "windows")
baseImg := integration.UnixOrWindows("busybox", "nanoserver")
dockerfile = []byte(fmt.Sprintf(
`
ARG MY_OS=%s
ARG MY_ARCH=amd64
FROM --platform=linux/${MYARCH} busybox
FROM --platform=%s/${MYARCH} %s
COPY Dockerfile .
`)
`,
osName, osName, baseImg))

osStr := integration.UnixOrWindows("linux", "windows")
streamBuildErr := fmt.Sprintf(
"failed to solve: failed to parse platform %s/${MYARCH}: \"\" is an invalid component of \"%s/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
osStr, osStr)
unmarshalBuildErr := fmt.Sprintf(
"failed to parse platform %s/${MYARCH}: \"\" is an invalid component of \"%s/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
osStr, osStr)
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
Expand All @@ -840,16 +856,18 @@ COPY Dockerfile .
Line: 4,
},
},
StreamBuildErr: "failed to solve: failed to parse platform linux/${MYARCH}: \"\" is an invalid component of \"linux/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
UnmarshalBuildErr: "failed to parse platform linux/${MYARCH}: \"\" is an invalid component of \"linux/\": platform specifier component must match \"^[A-Za-z0-9_-]+$\": invalid argument (did you mean MY_ARCH?)",
StreamBuildErr: streamBuildErr,
UnmarshalBuildErr: unmarshalBuildErr,
BuildErrLocation: 4,
})

dockerfile = []byte(`
dockerfile = []byte(fmt.Sprintf(
`
ARG tag=latest
FROM busybox:${tag}${version} AS b
FROM %s:${tag}${version} AS b
COPY Dockerfile .
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
Expand Down Expand Up @@ -902,27 +920,34 @@ COPY Dockerfile${foo} .
`)
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})

dockerfile = []byte(`
FROM alpine AS base
baseImg := integration.UnixOrWindows("alpine", "nanoserver")
dockerfile = []byte(fmt.Sprintf(
`
FROM %s AS base
ARG foo=Dockerfile
FROM base
COPY $foo .
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})

dockerfile = []byte(`
FROM alpine
dockerfile = []byte(fmt.Sprintf(
`
FROM %s
RUN echo $PATH
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})

dockerfile = []byte(`
FROM alpine
dockerfile = []byte(fmt.Sprintf(
`
FROM %s
COPY $foo .
ARG foo=bar
RUN echo $foo
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
Expand All @@ -937,13 +962,15 @@ RUN echo $foo
},
})

dockerfile = []byte(`
FROM alpine
dockerfile = []byte(fmt.Sprintf(
`
FROM %s
ARG DIR_BINARIES=binaries/
ARG DIR_ASSETS=assets/
ARG DIR_CONFIG=config/
COPY $DIR_ASSET .
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
Expand All @@ -958,10 +985,12 @@ COPY $DIR_ASSET .
},
})

dockerfile = []byte(`
FROM alpine
dockerfile = []byte(fmt.Sprintf(
`
FROM %s
ENV PATH=$PAHT:/tmp/bin
`)
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
Warnings: []expectedLintWarning{
Expand Down Expand Up @@ -1150,10 +1179,13 @@ FROM --platform=${TARGETPLATFORM} scratch
}

func testInvalidDefaultArgInFrom(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(`
baseImg := integration.UnixOrWindows("busybox", "nanoserver")
dockerfile := []byte(fmt.Sprintf(
`
ARG VERSION
FROM busybox:$VERSION
`)
FROM %s:$VERSION
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
Expand All @@ -1164,9 +1196,12 @@ FROM busybox:$VERSION
RuleName: "InvalidDefaultArgInFrom",
Description: "Default value for global ARG results in an empty or invalid base image name",
URL: "https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/",
Detail: "Default value for ARG busybox:$VERSION results in empty or invalid base image name",
Line: 3,
Level: 1,
Detail: fmt.Sprintf(
"Default value for ARG %s:$VERSION results in empty or invalid base image name",
integration.UnixOrWindows("busybox", "nanoserver"),
),
Line: 3,
Level: 1,
},
},
})
Expand All @@ -1178,7 +1213,7 @@ FROM $IMAGE
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
"build-arg:IMAGE": "busybox:latest",
"build-arg:IMAGE": integration.UnixOrWindows("busybox:latest", "nanoserver:latest"),
},
Warnings: []expectedLintWarning{
{
Expand All @@ -1192,57 +1227,80 @@ FROM $IMAGE
},
})

dockerfile = []byte(`
dockerfile = []byte(integration.UnixOrWindows(
`
ARG SFX="box:"
FROM busy${SFX}
`)
`,
`
ARG SFX="server:"
FROM nano${SFX}
`,
))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
"build-arg:SFX": "box:latest",
"build-arg:SFX": integration.UnixOrWindows("box:latest", "server:latest"),
},
Warnings: []expectedLintWarning{
{
RuleName: "InvalidDefaultArgInFrom",
Description: "Default value for global ARG results in an empty or invalid base image name",
URL: "https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/",
Detail: "Default value for ARG busy${SFX} results in empty or invalid base image name",
Line: 3,
Level: 1,
Detail: fmt.Sprintf(
"Default value for ARG %s${SFX} results in empty or invalid base image name",
integration.UnixOrWindows("busy", "nano"),
),
Line: 3,
Level: 1,
},
},
})

dockerfile = []byte(`
dockerfile = []byte(fmt.Sprintf(
`
ARG VERSION="latest"
FROM busybox:${VERSION}
`)
FROM %s:${VERSION}
`,
baseImg))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
"build-arg:VERSION": "latest",
},
})

dockerfile = []byte(`
dockerfile = []byte(integration.UnixOrWindows(
`
ARG BUSYBOX_VARIANT=""
FROM busybox:stable${BUSYBOX_VARIANT}
`)
`,
`
ARG BUSYBOX_VARIANT=""
FROM nanoserver:plus${BUSYBOX_VARIANT}
`,
))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
"build-arg:BUSYBOX_VARIANT": "-musl",
"build-arg:BUSYBOX_VARIANT": integration.UnixOrWindows("-musl", "-busybox"),
},
})

dockerfile = []byte(`
ARG BUSYBOX_VARIANT
FROM busybox:stable${BUSYBOX_VARIANT}
`)
dockerfile = []byte(integration.UnixOrWindows(
`
ARG BUSYBOX_VARIANT
FROM busybox:stable${BUSYBOX_VARIANT}
`,
`
ARG BUSYBOX_VARIANT
FROM nanoserver:plus${BUSYBOX_VARIANT}
`,
))
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
FrontendAttrs: map[string]string{
"build-arg:BUSYBOX_VARIANT": "-musl",
"build-arg:BUSYBOX_VARIANT": integration.UnixOrWindows("-musl", "-busybox"),
},
})
}
Expand Down Expand Up @@ -1376,10 +1434,14 @@ func checkProgressStream(t *testing.T, sb integration.Sandbox, lintTest *lintTes

f := getFrontend(t, sb)

platformStr := integration.UnixOrWindows(
"linux/amd64,linux/arm64",
"windows/amd64",
)
attrs := lintTest.FrontendAttrs
if attrs == nil {
attrs = map[string]string{
"platform": "linux/amd64,linux/arm64",
"platform": platformStr,
}
}

Expand Down Expand Up @@ -1428,8 +1490,6 @@ func checkLinterWarnings(t *testing.T, sb integration.Sandbox, lintTest *lintTes
return lintTest.Warnings[i].Line < lintTest.Warnings[j].Line
})

integration.SkipOnPlatform(t, "windows")

if lintTest.TmpDir == nil {
testfiles := []fstest.Applier{
fstest.CreateFile("Dockerfile", lintTest.Dockerfile, 0600),
Expand Down
2 changes: 1 addition & 1 deletion frontend/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func init() {

images := integration.UnixOrWindows(
[]string{"busybox:latest", "alpine:latest"},
[]string{"nanoserver:latest", "nanoserver:plus"})
[]string{"nanoserver:latest", "nanoserver:plus", "nanoserver:plus-busybox"})
opts = []integration.TestOpt{
integration.WithMirroredImages(integration.OfficialImages(images...)),
integration.WithMatrix("frontend", frontends),
Expand Down
3 changes: 2 additions & 1 deletion util/testutil/integration/util_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ var windowsImagesMirrorMap = map[string]string{
// nanoserver with extra binaries, like fc.exe
// TODO(profnandaa): get an approved/compliant repo, placeholder for now
// see dockerfile here - https://github.com/microsoft/windows-container-tools/pull/178
"nanoserver:plus": "docker.io/wintools/nanoserver:ltsc2022",
"nanoserver:plus": "docker.io/wintools/nanoserver:ltsc2022",
"nanoserver:plus-busybox": "docker.io/wintools/nanoserver:ltsc2022",
}

// abstracted function to handle pipe dialing on windows.
Expand Down

0 comments on commit ef2ffe9

Please sign in to comment.