summaryrefslogtreecommitdiff
path: root/libpod/image/pull_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/image/pull_test.go')
-rw-r--r--libpod/image/pull_test.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/libpod/image/pull_test.go b/libpod/image/pull_test.go
new file mode 100644
index 000000000..535dd4e9d
--- /dev/null
+++ b/libpod/image/pull_test.go
@@ -0,0 +1,125 @@
+package image
+
+import (
+ "io/ioutil"
+ "os"
+ "testing"
+
+ "github.com/containers/image/transports"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+const registriesConfWithSearch = `[registries.search]
+registries = ['example.com', 'docker.io']
+`
+
+func TestRefNamesFromPossiblyUnqualifiedName(t *testing.T) {
+ const digestSuffix = "@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+ type pullRefStrings struct{ image, srcRef, dstName string } // pullRefName with string data only
+
+ registriesConf, err := ioutil.TempFile("", "TestRefNamesFromPossiblyUnqualifiedName")
+ require.NoError(t, err)
+ defer registriesConf.Close()
+ defer os.Remove(registriesConf.Name())
+
+ err = ioutil.WriteFile(registriesConf.Name(), []byte(registriesConfWithSearch), 0600)
+ require.NoError(t, err)
+
+ // Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not
+ // run in parallel unless they opt in by calling t.Parallel(). So don’t do that.
+ oldRCP, hasRCP := os.LookupEnv("REGISTRIES_CONFIG_PATH")
+ defer func() {
+ if hasRCP {
+ os.Setenv("REGISTRIES_CONFIG_PATH", oldRCP)
+ } else {
+ os.Unsetenv("REGISTRIES_CONFIG_PATH")
+ }
+ }()
+ os.Setenv("REGISTRIES_CONFIG_PATH", registriesConf.Name())
+
+ for _, c := range []struct {
+ input string
+ expected []pullRefStrings
+ }{
+ {"#", nil}, // Clearly invalid.
+ { // Fully-explicit docker.io, name-only.
+ "docker.io/library/busybox",
+ // (The docker:// representation is shortened by c/image/docker.Reference but it refers to "docker.io/library".)
+ []pullRefStrings{{"docker.io/library/busybox", "docker://busybox:latest", "docker.io/library/busybox"}},
+ },
+ { // docker.io with implied /library/, name-only.
+ "docker.io/busybox",
+ // (The docker:// representation is shortened by c/image/docker.Reference but it refers to "docker.io/library".)
+ // The .dstName fields differ for the explicit/implicit /library/ cases, but StorageTransport.ParseStoreReference normalizes that.
+ []pullRefStrings{{"docker.io/busybox", "docker://busybox:latest", "docker.io/busybox"}},
+ },
+ { // Qualified example.com, name-only.
+ "example.com/ns/busybox",
+ []pullRefStrings{{"example.com/ns/busybox", "docker://example.com/ns/busybox:latest", "example.com/ns/busybox"}},
+ },
+ { // Qualified example.com, name:tag.
+ "example.com/ns/busybox:notlatest",
+ []pullRefStrings{{"example.com/ns/busybox:notlatest", "docker://example.com/ns/busybox:notlatest", "example.com/ns/busybox:notlatest"}},
+ },
+ { // Qualified example.com, name@digest.
+ "example.com/ns/busybox" + digestSuffix,
+ []pullRefStrings{{"example.com/ns/busybox" + digestSuffix, "docker://example.com/ns/busybox" + digestSuffix,
+ // FIXME?! Why is .dstName dropping the digest, and adding :none?!
+ "example.com/ns/busybox:none"}},
+ },
+ // Qualified example.com, name:tag@digest. This code is happy to try, but .srcRef parsing currently rejects such input.
+ {"example.com/ns/busybox:notlatest" + digestSuffix, nil},
+ { // Unqualified, single-name, name-only
+ "busybox",
+ []pullRefStrings{
+ {"example.com/busybox:latest", "docker://example.com/busybox:latest", "example.com/busybox:latest"},
+ // (The docker:// representation is shortened by c/image/docker.Reference but it refers to "docker.io/library".)
+ {"docker.io/busybox:latest", "docker://busybox:latest", "docker.io/busybox:latest"},
+ },
+ },
+ { // Unqualified, namespaced, name-only
+ "ns/busybox",
+ // FIXME: This is interpreted as "registry == ns", and actual pull happens from docker.io/ns/busybox:latest;
+ // example.com should be first in the list but isn't used at all.
+ []pullRefStrings{
+ {"ns/busybox", "docker://ns/busybox:latest", "ns/busybox"},
+ },
+ },
+ { // Unqualified, name:tag
+ "busybox:notlatest",
+ []pullRefStrings{
+ {"example.com/busybox:notlatest", "docker://example.com/busybox:notlatest", "example.com/busybox:notlatest"},
+ // (The docker:// representation is shortened by c/image/docker.Reference but it refers to "docker.io/library".)
+ {"docker.io/busybox:notlatest", "docker://busybox:notlatest", "docker.io/busybox:notlatest"},
+ },
+ },
+ { // Unqualified, name@digest
+ "busybox" + digestSuffix,
+ []pullRefStrings{
+ // FIXME?! Why is .input and .dstName dropping the digest, and adding :none?!
+ {"example.com/busybox:none", "docker://example.com/busybox" + digestSuffix, "example.com/busybox:none"},
+ // (The docker:// representation is shortened by c/image/docker.Reference but it refers to "docker.io/library".)
+ {"docker.io/busybox:none", "docker://busybox" + digestSuffix, "docker.io/busybox:none"},
+ },
+ },
+ // Unqualified, name:tag@digest. This code is happy to try, but .srcRef parsing currently rejects such input.
+ {"busybox:notlatest" + digestSuffix, nil},
+ } {
+ res, err := refNamesFromPossiblyUnqualifiedName(c.input)
+ if len(c.expected) == 0 {
+ assert.Error(t, err, c.input)
+ } else {
+ assert.NoError(t, err, c.input)
+ strings := make([]pullRefStrings, len(res))
+ for i, rn := range res {
+ strings[i] = pullRefStrings{
+ image: rn.image,
+ srcRef: transports.ImageName(rn.srcRef),
+ dstName: rn.dstName,
+ }
+ }
+ assert.Equal(t, c.expected, strings, c.input)
+ }
+ }
+}