Skip to content

Commit 1ab3f69

Browse files
johnstcnmafredri
andauthored
chore(integration): test with a locally-hosted devcontainer feature (#438)
Co-authored-by: Mathias Fredriksson <[email protected]>
1 parent 440ac5c commit 1ab3f69

File tree

1 file changed

+55
-29
lines changed

1 file changed

+55
-29
lines changed

integration/integration_test.go

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,23 @@ COPY %s .`, testImageAlpine, inclFile)
15451545
func TestPushImage(t *testing.T) {
15461546
t.Parallel()
15471547

1548+
// Write a test feature to an in-memory registry.
1549+
testFeature := registrytest.WriteContainer(t, registrytest.New(t), "features/test-feature:latest", features.TarLayerMediaType, map[string]any{
1550+
"install.sh": `#!/bin/sh
1551+
echo "${MESSAGE}" > /root/message.txt`,
1552+
"devcontainer-feature.json": features.Spec{
1553+
ID: "test-feature",
1554+
Name: "test feature",
1555+
Version: "v0.0.1",
1556+
Options: map[string]features.Option{
1557+
"message": {
1558+
Type: "string",
1559+
Default: "hello world",
1560+
},
1561+
},
1562+
},
1563+
})
1564+
15481565
t.Run("CacheWithoutPush", func(t *testing.T) {
15491566
t.Parallel()
15501567

@@ -1557,12 +1574,15 @@ WORKDIR $WORKDIR
15571574
ENV FOO=bar
15581575
RUN echo $FOO > /root/foo.txt
15591576
RUN date --utc > /root/date.txt`, testImageAlpine),
1560-
".devcontainer/devcontainer.json": `{
1577+
".devcontainer/devcontainer.json": fmt.Sprintf(`{
15611578
"name": "Test",
15621579
"build": {
15631580
"dockerfile": "Dockerfile"
15641581
},
1565-
}`,
1582+
"features": {
1583+
%q: {}
1584+
}
1585+
}`, testFeature),
15661586
},
15671587
})
15681588

@@ -1603,7 +1623,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
16031623
envbuilderEnv("CACHE_REPO", testRepo),
16041624
envbuilderEnv("GET_CACHED_IMAGE", "1"),
16051625
}})
1606-
require.ErrorContains(t, err, "uncached COPY command is not supported in cache probe mode")
1626+
require.Regexp(t, `uncached.*command.*is not supported in cache probe mode`, err.Error())
16071627
})
16081628

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

1635+
// Given: a git repository with a devcontainer.json that references the
1636+
// feature
16151637
srv := gittest.CreateGitServer(t, gittest.Options{
16161638
Files: map[string]string{
16171639
".devcontainer/Dockerfile": fmt.Sprintf(`FROM %s
1618-
USER root
1619-
ARG WORKDIR=/
1620-
WORKDIR $WORKDIR
1621-
ENV FOO=bar
1622-
RUN echo $FOO > /root/foo.txt
1623-
RUN date --utc > /root/date.txt`, testImageAlpine),
1624-
".devcontainer/devcontainer.json": `{
1625-
"name": "Test",
1626-
"build": {
1627-
"dockerfile": "Dockerfile"
1628-
},
1629-
}`,
1640+
USER root
1641+
ARG WORKDIR=/
1642+
WORKDIR $WORKDIR
1643+
ENV FOO=bar
1644+
RUN echo $FOO > /root/foo.txt
1645+
RUN date --utc > /root/date.txt`, testImageAlpine),
1646+
".devcontainer/devcontainer.json": fmt.Sprintf(`
1647+
{
1648+
"name": "Test",
1649+
"build": {
1650+
"dockerfile": "Dockerfile"
1651+
},
1652+
"features": {
1653+
%q: {}
1654+
}
1655+
}`, testFeature),
16301656
},
16311657
})
16321658

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

16761705
t.Run("CacheAndPushDevcontainerOnly", func(t *testing.T) {
@@ -1702,7 +1731,7 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
17021731
_, err = runEnvbuilder(t, runOpts{env: append(opts,
17031732
envbuilderEnv("GET_CACHED_IMAGE", "1"),
17041733
)})
1705-
require.ErrorContains(t, err, "error probing build cache: uncached COPY command")
1734+
require.Regexp(t, "error probing build cache: uncached.*command.*is not supported in cache probe mode", err.Error())
17061735
// Then: it should fail to build the image and nothing should be pushed
17071736
_, err = remote.Image(ref)
17081737
require.ErrorContains(t, err, "NAME_UNKNOWN", "expected image to not be present before build + push")
@@ -2293,26 +2322,23 @@ RUN date --utc > /root/date.txt`, testImageAlpine),
22932322
require.NoError(t, err)
22942323
})
22952324

2296-
t.Run("CacheAndPushDevcontainerFeatures", func(t *testing.T) {
2325+
t.Run("CacheAndPushDevcontainerFeaturesOverrideOption", func(t *testing.T) {
22972326
t.Parallel()
22982327

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

23022331
srv := gittest.CreateGitServer(t, gittest.Options{
23032332
Files: map[string]string{
2304-
// NOTE(mafredri): We can't cache the feature in our local
2305-
// registry because the image media type is incompatible.
23062333
".devcontainer/devcontainer.json": fmt.Sprintf(`
2307-
{
2308-
"image": %q,
2309-
"features": {
2310-
"ghcr.io/devcontainers/feature-starter/color:1": {
2311-
"favorite": "green"
2312-
}
2313-
}
2314-
}
2315-
`, testImageUbuntu),
2334+
{
2335+
"image": %q,
2336+
"features": {
2337+
%q: {
2338+
"message": "my favorite color is green"
2339+
}
2340+
}
2341+
}`, testImageUbuntu, testFeature),
23162342
},
23172343
})
23182344

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

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

0 commit comments

Comments
 (0)