Fix the dependency issue (#231)

This commit is contained in:
Robbie Zhang
2018-06-21 12:09:42 -07:00
committed by GitHub
parent 027b76651d
commit 6ec1098bb8
16629 changed files with 74837 additions and 4975021 deletions

View File

@@ -1,275 +0,0 @@
package reference
import (
"testing"
"github.com/docker/distribution/digest"
)
func TestValidateReferenceName(t *testing.T) {
validRepoNames := []string{
"docker/docker",
"library/debian",
"debian",
"docker.io/docker/docker",
"docker.io/library/debian",
"docker.io/debian",
"index.docker.io/docker/docker",
"index.docker.io/library/debian",
"index.docker.io/debian",
"127.0.0.1:5000/docker/docker",
"127.0.0.1:5000/library/debian",
"127.0.0.1:5000/debian",
"thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev",
}
invalidRepoNames := []string{
"https://github.com/hyperhq/hypercli",
"docker/Docker",
"-docker",
"-docker/docker",
"-docker.io/docker/docker",
"docker///docker",
"docker.io/docker/Docker",
"docker.io/docker///docker",
"1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
"docker.io/1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
}
for _, name := range invalidRepoNames {
_, err := ParseNamed(name)
if err == nil {
t.Fatalf("Expected invalid repo name for %q", name)
}
}
for _, name := range validRepoNames {
_, err := ParseNamed(name)
if err != nil {
t.Fatalf("Error parsing repo name %s, got: %q", name, err)
}
}
}
func TestValidateRemoteName(t *testing.T) {
validRepositoryNames := []string{
// Sanity check.
"docker/docker",
// Allow 64-character non-hexadecimal names (hexadecimal names are forbidden).
"thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev",
// Allow embedded hyphens.
"docker-rules/docker",
// Allow multiple hyphens as well.
"docker---rules/docker",
//Username doc and image name docker being tested.
"doc/docker",
// single character names are now allowed.
"d/docker",
"jess/t",
// Consecutive underscores.
"dock__er/docker",
}
for _, repositoryName := range validRepositoryNames {
_, err := ParseNamed(repositoryName)
if err != nil {
t.Errorf("Repository name should be valid: %v. Error: %v", repositoryName, err)
}
}
invalidRepositoryNames := []string{
// Disallow capital letters.
"docker/Docker",
// Only allow one slash.
"docker///docker",
// Disallow 64-character hexadecimal.
"1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
// Disallow leading and trailing hyphens in namespace.
"-docker/docker",
"docker-/docker",
"-docker-/docker",
// Don't allow underscores everywhere (as opposed to hyphens).
"____/____",
"_docker/_docker",
// Disallow consecutive periods.
"dock..er/docker",
"dock_.er/docker",
"dock-.er/docker",
// No repository.
"docker/",
//namespace too long
"this_is_not_a_valid_namespace_because_its_lenth_is_greater_than_255_this_is_not_a_valid_namespace_because_its_lenth_is_greater_than_255_this_is_not_a_valid_namespace_because_its_lenth_is_greater_than_255_this_is_not_a_valid_namespace_because_its_lenth_is_greater_than_255/docker",
}
for _, repositoryName := range invalidRepositoryNames {
if _, err := ParseNamed(repositoryName); err == nil {
t.Errorf("Repository name should be invalid: %v", repositoryName)
}
}
}
func TestParseRepositoryInfo(t *testing.T) {
type tcase struct {
RemoteName, NormalizedName, FullName, AmbiguousName, Hostname string
}
tcases := []tcase{
{
RemoteName: "fooo/bar",
NormalizedName: "fooo/bar",
FullName: "docker.io/fooo/bar",
AmbiguousName: "index.docker.io/fooo/bar",
Hostname: "docker.io",
},
{
RemoteName: "library/ubuntu",
NormalizedName: "ubuntu",
FullName: "docker.io/library/ubuntu",
AmbiguousName: "library/ubuntu",
Hostname: "docker.io",
},
{
RemoteName: "nonlibrary/ubuntu",
NormalizedName: "nonlibrary/ubuntu",
FullName: "docker.io/nonlibrary/ubuntu",
AmbiguousName: "",
Hostname: "docker.io",
},
{
RemoteName: "other/library",
NormalizedName: "other/library",
FullName: "docker.io/other/library",
AmbiguousName: "",
Hostname: "docker.io",
},
{
RemoteName: "private/moonbase",
NormalizedName: "127.0.0.1:8000/private/moonbase",
FullName: "127.0.0.1:8000/private/moonbase",
AmbiguousName: "",
Hostname: "127.0.0.1:8000",
},
{
RemoteName: "privatebase",
NormalizedName: "127.0.0.1:8000/privatebase",
FullName: "127.0.0.1:8000/privatebase",
AmbiguousName: "",
Hostname: "127.0.0.1:8000",
},
{
RemoteName: "private/moonbase",
NormalizedName: "example.com/private/moonbase",
FullName: "example.com/private/moonbase",
AmbiguousName: "",
Hostname: "example.com",
},
{
RemoteName: "privatebase",
NormalizedName: "example.com/privatebase",
FullName: "example.com/privatebase",
AmbiguousName: "",
Hostname: "example.com",
},
{
RemoteName: "private/moonbase",
NormalizedName: "example.com:8000/private/moonbase",
FullName: "example.com:8000/private/moonbase",
AmbiguousName: "",
Hostname: "example.com:8000",
},
{
RemoteName: "privatebasee",
NormalizedName: "example.com:8000/privatebasee",
FullName: "example.com:8000/privatebasee",
AmbiguousName: "",
Hostname: "example.com:8000",
},
{
RemoteName: "library/ubuntu-12.04-base",
NormalizedName: "ubuntu-12.04-base",
FullName: "docker.io/library/ubuntu-12.04-base",
AmbiguousName: "index.docker.io/library/ubuntu-12.04-base",
Hostname: "docker.io",
},
}
for _, tcase := range tcases {
refStrings := []string{tcase.NormalizedName, tcase.FullName}
if tcase.AmbiguousName != "" {
refStrings = append(refStrings, tcase.AmbiguousName)
}
var refs []Named
for _, r := range refStrings {
named, err := ParseNamed(r)
if err != nil {
t.Fatal(err)
}
refs = append(refs, named)
named, err = WithName(r)
if err != nil {
t.Fatal(err)
}
refs = append(refs, named)
}
for _, r := range refs {
if expected, actual := tcase.NormalizedName, r.Name(); expected != actual {
t.Fatalf("Invalid normalized reference for %q. Expected %q, got %q", r, expected, actual)
}
if expected, actual := tcase.FullName, r.FullName(); expected != actual {
t.Fatalf("Invalid normalized reference for %q. Expected %q, got %q", r, expected, actual)
}
if expected, actual := tcase.Hostname, r.Hostname(); expected != actual {
t.Fatalf("Invalid hostname for %q. Expected %q, got %q", r, expected, actual)
}
if expected, actual := tcase.RemoteName, r.RemoteName(); expected != actual {
t.Fatalf("Invalid remoteName for %q. Expected %q, got %q", r, expected, actual)
}
}
}
}
func TestParseReferenceWithTagAndDigest(t *testing.T) {
ref, err := ParseNamed("busybox:latest@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")
if err != nil {
t.Fatal(err)
}
if _, isTagged := ref.(NamedTagged); isTagged {
t.Fatalf("Reference from %q should not support tag", ref)
}
if _, isCanonical := ref.(Canonical); !isCanonical {
t.Fatalf("Reference from %q should not support digest", ref)
}
if expected, actual := "busybox@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa", ref.String(); actual != expected {
t.Fatalf("Invalid parsed reference for %q: expected %q, got %q", ref, expected, actual)
}
}
func TestInvalidReferenceComponents(t *testing.T) {
if _, err := WithName("-foo"); err == nil {
t.Fatal("Expected WithName to detect invalid name")
}
ref, err := WithName("busybox")
if err != nil {
t.Fatal(err)
}
if _, err := WithTag(ref, "-foo"); err == nil {
t.Fatal("Expected WithName to detect invalid tag")
}
if _, err := WithDigest(ref, digest.Digest("foo")); err == nil {
t.Fatal("Expected WithName to detect invalid digest")
}
}

View File

@@ -1,356 +0,0 @@
package reference
import (
"bytes"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/hyperhq/hypercli/image"
)
var (
saveLoadTestCases = map[string]image.ID{
"registry:5000/foobar:HEAD": "sha256:470022b8af682154f57a2163d030eb369549549cba00edc69e1b99b46bb924d6",
"registry:5000/foobar:alternate": "sha256:ae300ebc4a4f00693702cfb0a5e0b7bc527b353828dc86ad09fb95c8a681b793",
"registry:5000/foobar:latest": "sha256:6153498b9ac00968d71b66cca4eac37e990b5f9eb50c26877eb8799c8847451b",
"registry:5000/foobar:master": "sha256:6c9917af4c4e05001b346421959d7ea81b6dc9d25718466a37a6add865dfd7fc",
"jess/hollywood:latest": "sha256:ae7a5519a0a55a2d4ef20ddcbd5d0ca0888a1f7ab806acc8e2a27baf46f529fe",
"registry@sha256:367eb40fd0330a7e464777121e39d2f5b3e8e23a1e159342e53ab05c9e4d94e6": "sha256:24126a56805beb9711be5f4590cc2eb55ab8d4a85ebd618eed72bb19fc50631c",
"busybox:latest": "sha256:91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c",
}
marshalledSaveLoadTestCases = []byte(`{"Repositories":{"busybox":{"busybox:latest":"sha256:91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c"},"jess/hollywood":{"jess/hollywood:latest":"sha256:ae7a5519a0a55a2d4ef20ddcbd5d0ca0888a1f7ab806acc8e2a27baf46f529fe"},"registry":{"registry@sha256:367eb40fd0330a7e464777121e39d2f5b3e8e23a1e159342e53ab05c9e4d94e6":"sha256:24126a56805beb9711be5f4590cc2eb55ab8d4a85ebd618eed72bb19fc50631c"},"registry:5000/foobar":{"registry:5000/foobar:HEAD":"sha256:470022b8af682154f57a2163d030eb369549549cba00edc69e1b99b46bb924d6","registry:5000/foobar:alternate":"sha256:ae300ebc4a4f00693702cfb0a5e0b7bc527b353828dc86ad09fb95c8a681b793","registry:5000/foobar:latest":"sha256:6153498b9ac00968d71b66cca4eac37e990b5f9eb50c26877eb8799c8847451b","registry:5000/foobar:master":"sha256:6c9917af4c4e05001b346421959d7ea81b6dc9d25718466a37a6add865dfd7fc"}}}`)
)
func TestLoad(t *testing.T) {
jsonFile, err := ioutil.TempFile("", "tag-store-test")
if err != nil {
t.Fatalf("error creating temp file: %v", err)
}
defer os.RemoveAll(jsonFile.Name())
// Write canned json to the temp file
_, err = jsonFile.Write(marshalledSaveLoadTestCases)
if err != nil {
t.Fatalf("error writing to temp file: %v", err)
}
jsonFile.Close()
store, err := NewReferenceStore(jsonFile.Name())
if err != nil {
t.Fatalf("error creating tag store: %v", err)
}
for refStr, expectedID := range saveLoadTestCases {
ref, err := ParseNamed(refStr)
if err != nil {
t.Fatalf("failed to parse reference: %v", err)
}
id, err := store.Get(ref)
if err != nil {
t.Fatalf("could not find reference %s: %v", refStr, err)
}
if id != expectedID {
t.Fatalf("expected %s - got %s", expectedID, id)
}
}
}
func TestSave(t *testing.T) {
jsonFile, err := ioutil.TempFile("", "tag-store-test")
if err != nil {
t.Fatalf("error creating temp file: %v", err)
}
_, err = jsonFile.Write([]byte(`{}`))
jsonFile.Close()
defer os.RemoveAll(jsonFile.Name())
store, err := NewReferenceStore(jsonFile.Name())
if err != nil {
t.Fatalf("error creating tag store: %v", err)
}
for refStr, id := range saveLoadTestCases {
ref, err := ParseNamed(refStr)
if err != nil {
t.Fatalf("failed to parse reference: %v", err)
}
if canonical, ok := ref.(Canonical); ok {
err = store.AddDigest(canonical, id, false)
if err != nil {
t.Fatalf("could not add digest reference %s: %v", refStr, err)
}
} else {
err = store.AddTag(ref, id, false)
if err != nil {
t.Fatalf("could not add reference %s: %v", refStr, err)
}
}
}
jsonBytes, err := ioutil.ReadFile(jsonFile.Name())
if err != nil {
t.Fatalf("could not read json file: %v", err)
}
if !bytes.Equal(jsonBytes, marshalledSaveLoadTestCases) {
t.Fatalf("save output did not match expectations\nexpected:\n%s\ngot:\n%s", marshalledSaveLoadTestCases, jsonBytes)
}
}
func TestAddDeleteGet(t *testing.T) {
jsonFile, err := ioutil.TempFile("", "tag-store-test")
if err != nil {
t.Fatalf("error creating temp file: %v", err)
}
_, err = jsonFile.Write([]byte(`{}`))
jsonFile.Close()
defer os.RemoveAll(jsonFile.Name())
store, err := NewReferenceStore(jsonFile.Name())
if err != nil {
t.Fatalf("error creating tag store: %v", err)
}
testImageID1 := image.ID("sha256:9655aef5fd742a1b4e1b7b163aa9f1c76c186304bf39102283d80927c916ca9c")
testImageID2 := image.ID("sha256:9655aef5fd742a1b4e1b7b163aa9f1c76c186304bf39102283d80927c916ca9d")
testImageID3 := image.ID("sha256:9655aef5fd742a1b4e1b7b163aa9f1c76c186304bf39102283d80927c916ca9e")
// Try adding a reference with no tag or digest
nameOnly, err := WithName("username/repo")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddTag(nameOnly, testImageID1, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
// Add a few references
ref1, err := ParseNamed("username/repo1:latest")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddTag(ref1, testImageID1, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
ref2, err := ParseNamed("username/repo1:old")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddTag(ref2, testImageID2, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
ref3, err := ParseNamed("username/repo1:alias")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddTag(ref3, testImageID1, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
ref4, err := ParseNamed("username/repo2:latest")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddTag(ref4, testImageID2, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
ref5, err := ParseNamed("username/repo3@sha256:58153dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if err = store.AddDigest(ref5.(Canonical), testImageID2, false); err != nil {
t.Fatalf("error adding to store: %v", err)
}
// Attempt to overwrite with force == false
if err = store.AddTag(ref4, testImageID3, false); err == nil || !strings.HasPrefix(err.Error(), "Conflict:") {
t.Fatalf("did not get expected error on overwrite attempt - got %v", err)
}
// Repeat to overwrite with force == true
if err = store.AddTag(ref4, testImageID3, true); err != nil {
t.Fatalf("failed to force tag overwrite: %v", err)
}
// Check references so far
id, err := store.Get(nameOnly)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID1 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID1.String())
}
id, err = store.Get(ref1)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID1 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID1.String())
}
id, err = store.Get(ref2)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID2 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID2.String())
}
id, err = store.Get(ref3)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID1 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID1.String())
}
id, err = store.Get(ref4)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID3 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID3.String())
}
id, err = store.Get(ref5)
if err != nil {
t.Fatalf("Get returned error: %v", err)
}
if id != testImageID2 {
t.Fatalf("id mismatch: got %s instead of %s", id.String(), testImageID3.String())
}
// Get should return ErrDoesNotExist for a nonexistent repo
nonExistRepo, err := ParseNamed("username/nonexistrepo:latest")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if _, err = store.Get(nonExistRepo); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Get")
}
// Get should return ErrDoesNotExist for a nonexistent tag
nonExistTag, err := ParseNamed("username/repo1:nonexist")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
if _, err = store.Get(nonExistTag); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Get")
}
// Check References
refs := store.References(testImageID1)
if len(refs) != 3 {
t.Fatal("unexpected number of references")
}
// Looking for the references in this order verifies that they are
// returned lexically sorted.
if refs[0].String() != ref3.String() {
t.Fatalf("unexpected reference: %v", refs[0].String())
}
if refs[1].String() != ref1.String() {
t.Fatalf("unexpected reference: %v", refs[1].String())
}
if refs[2].String() != nameOnly.String()+":latest" {
t.Fatalf("unexpected reference: %v", refs[2].String())
}
// Check ReferencesByName
repoName, err := WithName("username/repo1")
if err != nil {
t.Fatalf("could not parse reference: %v", err)
}
associations := store.ReferencesByName(repoName)
if len(associations) != 3 {
t.Fatal("unexpected number of associations")
}
// Looking for the associations in this order verifies that they are
// returned lexically sorted.
if associations[0].Ref.String() != ref3.String() {
t.Fatalf("unexpected reference: %v", associations[0].Ref.String())
}
if associations[0].ImageID != testImageID1 {
t.Fatalf("unexpected reference: %v", associations[0].Ref.String())
}
if associations[1].Ref.String() != ref1.String() {
t.Fatalf("unexpected reference: %v", associations[1].Ref.String())
}
if associations[1].ImageID != testImageID1 {
t.Fatalf("unexpected reference: %v", associations[1].Ref.String())
}
if associations[2].Ref.String() != ref2.String() {
t.Fatalf("unexpected reference: %v", associations[2].Ref.String())
}
if associations[2].ImageID != testImageID2 {
t.Fatalf("unexpected reference: %v", associations[2].Ref.String())
}
// Delete should return ErrDoesNotExist for a nonexistent repo
if _, err = store.Delete(nonExistRepo); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Delete")
}
// Delete should return ErrDoesNotExist for a nonexistent tag
if _, err = store.Delete(nonExistTag); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Delete")
}
// Delete a few references
if deleted, err := store.Delete(ref1); err != nil || deleted != true {
t.Fatal("Delete failed")
}
if _, err := store.Get(ref1); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Get")
}
if deleted, err := store.Delete(ref5); err != nil || deleted != true {
t.Fatal("Delete failed")
}
if _, err := store.Get(ref5); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Get")
}
if deleted, err := store.Delete(nameOnly); err != nil || deleted != true {
t.Fatal("Delete failed")
}
if _, err := store.Get(nameOnly); err != ErrDoesNotExist {
t.Fatal("Expected ErrDoesNotExist from Get")
}
}
func TestInvalidTags(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "tag-store-test")
defer os.RemoveAll(tmpDir)
store, err := NewReferenceStore(filepath.Join(tmpDir, "repositories.json"))
if err != nil {
t.Fatalf("error creating tag store: %v", err)
}
id := image.ID("sha256:470022b8af682154f57a2163d030eb369549549cba00edc69e1b99b46bb924d6")
// sha256 as repo name
ref, err := ParseNamed("sha256:abc")
if err != nil {
t.Fatal(err)
}
err = store.AddTag(ref, id, true)
if err == nil {
t.Fatalf("expected setting tag %q to fail", ref)
}
// setting digest as a tag
ref, err = ParseNamed("registry@sha256:367eb40fd0330a7e464777121e39d2f5b3e8e23a1e159342e53ab05c9e4d94e6")
if err != nil {
t.Fatal(err)
}
err = store.AddTag(ref, id, true)
if err == nil {
t.Fatalf("expected setting digest %q to fail", ref)
}
}