Make refNamesFromPossiblyUnqualifiedName independent from Image

... which finally makes it very easy to add comprehensive tests; so do that.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>

Closes: #1112
Approved by: rhatdan
This commit is contained in:
Miloslav Trmač
2018-07-19 00:58:26 +02:00
committed by Atomic Bot
parent 3b964a4d9a
commit 38842bd407
2 changed files with 136 additions and 11 deletions

125
libpod/image/pull_test.go Normal file
View File

@ -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 dont 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)
}
}
}