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

chore(integration): test with a locally-hosted devcontainer feature #438

Merged
merged 2 commits into from
Dec 19, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 55 additions & 29 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,23 @@ COPY %s .`, testImageAlpine, inclFile)
func TestPushImage(t *testing.T) {
t.Parallel()

// Write a test feature to an in-memory registry.
testFeature := registrytest.WriteContainer(t, registrytest.New(t), "features/test-feature:latest", features.TarLayerMediaType, map[string]any{
"install.sh": `#!/bin/sh
echo "${MESSAGE}" > /root/message.txt`,
"devcontainer-feature.json": features.Spec{
ID: "test-feature",
Name: "test feature",
Version: "v0.0.1",
Options: map[string]features.Option{
"message": {
Type: "string",
Default: "hello world",
},
},
},
})

t.Run("CacheWithoutPush", func(t *testing.T) {
t.Parallel()

Expand All @@ -1557,12 +1574,15 @@ WORKDIR $WORKDIR
ENV FOO=bar
RUN echo $FOO > /root/foo.txt
RUN date --utc > /root/date.txt`, testImageAlpine),
".devcontainer/devcontainer.json": `{
".devcontainer/devcontainer.json": fmt.Sprintf(`{
"name": "Test",
"build": {
"dockerfile": "Dockerfile"
},
}`,
"features": {
%q: {}
}
}`, testFeature),
},
})

Expand Down Expand Up @@ -1603,7 +1623,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
envbuilderEnv("CACHE_REPO", testRepo),
envbuilderEnv("GET_CACHED_IMAGE", "1"),
}})
require.ErrorContains(t, err, "uncached COPY command is not supported in cache probe mode")
require.Regexp(t, `uncached.*?command.*?is not supported in cache probe mode`, err.Error())
johnstcn marked this conversation as resolved.
Show resolved Hide resolved
})

t.Run("CacheAndPush", func(t *testing.T) {
Expand All @@ -1612,21 +1632,27 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

// Given: a git repository with a devcontainer.json that references the
// feature
srv := gittest.CreateGitServer(t, gittest.Options{
Files: map[string]string{
".devcontainer/Dockerfile": fmt.Sprintf(`FROM %s
USER root
ARG WORKDIR=/
WORKDIR $WORKDIR
ENV FOO=bar
RUN echo $FOO > /root/foo.txt
RUN date --utc > /root/date.txt`, testImageAlpine),
".devcontainer/devcontainer.json": `{
"name": "Test",
"build": {
"dockerfile": "Dockerfile"
},
}`,
USER root
ARG WORKDIR=/
WORKDIR $WORKDIR
ENV FOO=bar
RUN echo $FOO > /root/foo.txt
RUN date --utc > /root/date.txt`, testImageAlpine),
".devcontainer/devcontainer.json": fmt.Sprintf(`
{
"name": "Test",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
%q: {}
}
}`, testFeature),
},
})

Expand Down Expand Up @@ -1671,6 +1697,9 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
require.Regexp(t, `(?s)^USAGE:\s+envbuilder`, strings.TrimSpace(out))
out = execContainer(t, ctr.ID, "cat /root/date.txt")
require.NotEmpty(t, strings.TrimSpace(out))
// Then: the feature install script was run
out = execContainer(t, ctr.ID, "cat /root/message.txt")
require.Equal(t, "hello world", strings.TrimSpace(out))
})

t.Run("CacheAndPushDevcontainerOnly", func(t *testing.T) {
Expand Down Expand Up @@ -1702,7 +1731,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
_, err = runEnvbuilder(t, runOpts{env: append(opts,
envbuilderEnv("GET_CACHED_IMAGE", "1"),
)})
require.ErrorContains(t, err, "error probing build cache: uncached COPY command")
require.Regexp(t, "error probing build cache: uncached.*?command.*?is not supported in cache probe mode", err.Error())
johnstcn marked this conversation as resolved.
Show resolved Hide resolved
// Then: it should fail to build the image and nothing should be pushed
_, err = remote.Image(ref)
require.ErrorContains(t, err, "NAME_UNKNOWN", "expected image to not be present before build + push")
Expand Down Expand Up @@ -2293,26 +2322,23 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
require.NoError(t, err)
})

t.Run("CacheAndPushDevcontainerFeatures", func(t *testing.T) {
t.Run("CacheAndPushDevcontainerFeaturesOverrideOption", func(t *testing.T) {
t.Parallel()

ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

srv := gittest.CreateGitServer(t, gittest.Options{
Files: map[string]string{
// NOTE(mafredri): We can't cache the feature in our local
// registry because the image media type is incompatible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for figuring this out! ❤️

".devcontainer/devcontainer.json": fmt.Sprintf(`
{
"image": %q,
"features": {
"ghcr.io/devcontainers/feature-starter/color:1": {
"favorite": "green"
}
}
}
`, testImageUbuntu),
{
"image": %q,
"features": {
%q: {
"message": "my favorite color is green"
}
}
}`, testImageUbuntu, testFeature),
},
})

Expand Down Expand Up @@ -2343,7 +2369,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
ctr := startContainerFromRef(ctx, t, cli, cachedRef)

// Check that the feature is present in the image.
out := execContainer(t, ctr.ID, "/usr/local/bin/color")
out := execContainer(t, ctr.ID, "cat /root/message.txt")
require.Contains(t, strings.TrimSpace(out), "my favorite color is green")
})

Expand Down
Loading