github.com/opsramp/moby@v1.13.1/reference/reference_test.go (about)

     1  package reference
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/docker/distribution/digest"
     7  )
     8  
     9  func TestValidateReferenceName(t *testing.T) {
    10  	validRepoNames := []string{
    11  		"docker/docker",
    12  		"library/debian",
    13  		"debian",
    14  		"docker.io/docker/docker",
    15  		"docker.io/library/debian",
    16  		"docker.io/debian",
    17  		"index.docker.io/docker/docker",
    18  		"index.docker.io/library/debian",
    19  		"index.docker.io/debian",
    20  		"127.0.0.1:5000/docker/docker",
    21  		"127.0.0.1:5000/library/debian",
    22  		"127.0.0.1:5000/debian",
    23  		"thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev",
    24  	}
    25  	invalidRepoNames := []string{
    26  		"https://github.com/docker/docker",
    27  		"docker/Docker",
    28  		"-docker",
    29  		"-docker/docker",
    30  		"-docker.io/docker/docker",
    31  		"docker///docker",
    32  		"docker.io/docker/Docker",
    33  		"docker.io/docker///docker",
    34  		"1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
    35  		"docker.io/1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
    36  	}
    37  
    38  	for _, name := range invalidRepoNames {
    39  		_, err := ParseNamed(name)
    40  		if err == nil {
    41  			t.Fatalf("Expected invalid repo name for %q", name)
    42  		}
    43  	}
    44  
    45  	for _, name := range validRepoNames {
    46  		_, err := ParseNamed(name)
    47  		if err != nil {
    48  			t.Fatalf("Error parsing repo name %s, got: %q", name, err)
    49  		}
    50  	}
    51  }
    52  
    53  func TestValidateRemoteName(t *testing.T) {
    54  	validRepositoryNames := []string{
    55  		// Sanity check.
    56  		"docker/docker",
    57  
    58  		// Allow 64-character non-hexadecimal names (hexadecimal names are forbidden).
    59  		"thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev",
    60  
    61  		// Allow embedded hyphens.
    62  		"docker-rules/docker",
    63  
    64  		// Allow multiple hyphens as well.
    65  		"docker---rules/docker",
    66  
    67  		//Username doc and image name docker being tested.
    68  		"doc/docker",
    69  
    70  		// single character names are now allowed.
    71  		"d/docker",
    72  		"jess/t",
    73  
    74  		// Consecutive underscores.
    75  		"dock__er/docker",
    76  	}
    77  	for _, repositoryName := range validRepositoryNames {
    78  		_, err := ParseNamed(repositoryName)
    79  		if err != nil {
    80  			t.Errorf("Repository name should be valid: %v. Error: %v", repositoryName, err)
    81  		}
    82  	}
    83  
    84  	invalidRepositoryNames := []string{
    85  		// Disallow capital letters.
    86  		"docker/Docker",
    87  
    88  		// Only allow one slash.
    89  		"docker///docker",
    90  
    91  		// Disallow 64-character hexadecimal.
    92  		"1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
    93  
    94  		// Disallow leading and trailing hyphens in namespace.
    95  		"-docker/docker",
    96  		"docker-/docker",
    97  		"-docker-/docker",
    98  
    99  		// Don't allow underscores everywhere (as opposed to hyphens).
   100  		"____/____",
   101  
   102  		"_docker/_docker",
   103  
   104  		// Disallow consecutive periods.
   105  		"dock..er/docker",
   106  		"dock_.er/docker",
   107  		"dock-.er/docker",
   108  
   109  		// No repository.
   110  		"docker/",
   111  
   112  		//namespace too long
   113  		"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",
   114  	}
   115  	for _, repositoryName := range invalidRepositoryNames {
   116  		if _, err := ParseNamed(repositoryName); err == nil {
   117  			t.Errorf("Repository name should be invalid: %v", repositoryName)
   118  		}
   119  	}
   120  }
   121  
   122  func TestParseRepositoryInfo(t *testing.T) {
   123  	type tcase struct {
   124  		RemoteName, NormalizedName, FullName, AmbiguousName, Hostname string
   125  	}
   126  
   127  	tcases := []tcase{
   128  		{
   129  			RemoteName:     "fooo/bar",
   130  			NormalizedName: "fooo/bar",
   131  			FullName:       "docker.io/fooo/bar",
   132  			AmbiguousName:  "index.docker.io/fooo/bar",
   133  			Hostname:       "docker.io",
   134  		},
   135  		{
   136  			RemoteName:     "library/ubuntu",
   137  			NormalizedName: "ubuntu",
   138  			FullName:       "docker.io/library/ubuntu",
   139  			AmbiguousName:  "library/ubuntu",
   140  			Hostname:       "docker.io",
   141  		},
   142  		{
   143  			RemoteName:     "nonlibrary/ubuntu",
   144  			NormalizedName: "nonlibrary/ubuntu",
   145  			FullName:       "docker.io/nonlibrary/ubuntu",
   146  			AmbiguousName:  "",
   147  			Hostname:       "docker.io",
   148  		},
   149  		{
   150  			RemoteName:     "other/library",
   151  			NormalizedName: "other/library",
   152  			FullName:       "docker.io/other/library",
   153  			AmbiguousName:  "",
   154  			Hostname:       "docker.io",
   155  		},
   156  		{
   157  			RemoteName:     "private/moonbase",
   158  			NormalizedName: "127.0.0.1:8000/private/moonbase",
   159  			FullName:       "127.0.0.1:8000/private/moonbase",
   160  			AmbiguousName:  "",
   161  			Hostname:       "127.0.0.1:8000",
   162  		},
   163  		{
   164  			RemoteName:     "privatebase",
   165  			NormalizedName: "127.0.0.1:8000/privatebase",
   166  			FullName:       "127.0.0.1:8000/privatebase",
   167  			AmbiguousName:  "",
   168  			Hostname:       "127.0.0.1:8000",
   169  		},
   170  		{
   171  			RemoteName:     "private/moonbase",
   172  			NormalizedName: "example.com/private/moonbase",
   173  			FullName:       "example.com/private/moonbase",
   174  			AmbiguousName:  "",
   175  			Hostname:       "example.com",
   176  		},
   177  		{
   178  			RemoteName:     "privatebase",
   179  			NormalizedName: "example.com/privatebase",
   180  			FullName:       "example.com/privatebase",
   181  			AmbiguousName:  "",
   182  			Hostname:       "example.com",
   183  		},
   184  		{
   185  			RemoteName:     "private/moonbase",
   186  			NormalizedName: "example.com:8000/private/moonbase",
   187  			FullName:       "example.com:8000/private/moonbase",
   188  			AmbiguousName:  "",
   189  			Hostname:       "example.com:8000",
   190  		},
   191  		{
   192  			RemoteName:     "privatebasee",
   193  			NormalizedName: "example.com:8000/privatebasee",
   194  			FullName:       "example.com:8000/privatebasee",
   195  			AmbiguousName:  "",
   196  			Hostname:       "example.com:8000",
   197  		},
   198  		{
   199  			RemoteName:     "library/ubuntu-12.04-base",
   200  			NormalizedName: "ubuntu-12.04-base",
   201  			FullName:       "docker.io/library/ubuntu-12.04-base",
   202  			AmbiguousName:  "index.docker.io/library/ubuntu-12.04-base",
   203  			Hostname:       "docker.io",
   204  		},
   205  	}
   206  
   207  	for _, tcase := range tcases {
   208  		refStrings := []string{tcase.NormalizedName, tcase.FullName}
   209  		if tcase.AmbiguousName != "" {
   210  			refStrings = append(refStrings, tcase.AmbiguousName)
   211  		}
   212  
   213  		var refs []Named
   214  		for _, r := range refStrings {
   215  			named, err := ParseNamed(r)
   216  			if err != nil {
   217  				t.Fatal(err)
   218  			}
   219  			refs = append(refs, named)
   220  			named, err = WithName(r)
   221  			if err != nil {
   222  				t.Fatal(err)
   223  			}
   224  			refs = append(refs, named)
   225  		}
   226  
   227  		for _, r := range refs {
   228  			if expected, actual := tcase.NormalizedName, r.Name(); expected != actual {
   229  				t.Fatalf("Invalid normalized reference for %q. Expected %q, got %q", r, expected, actual)
   230  			}
   231  			if expected, actual := tcase.FullName, r.FullName(); expected != actual {
   232  				t.Fatalf("Invalid normalized reference for %q. Expected %q, got %q", r, expected, actual)
   233  			}
   234  			if expected, actual := tcase.Hostname, r.Hostname(); expected != actual {
   235  				t.Fatalf("Invalid hostname for %q. Expected %q, got %q", r, expected, actual)
   236  			}
   237  			if expected, actual := tcase.RemoteName, r.RemoteName(); expected != actual {
   238  				t.Fatalf("Invalid remoteName for %q. Expected %q, got %q", r, expected, actual)
   239  			}
   240  
   241  		}
   242  	}
   243  }
   244  
   245  func TestParseReferenceWithTagAndDigest(t *testing.T) {
   246  	ref, err := ParseNamed("busybox:latest@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  	if _, isTagged := ref.(NamedTagged); isTagged {
   251  		t.Fatalf("Reference from %q should not support tag", ref)
   252  	}
   253  	if _, isCanonical := ref.(Canonical); !isCanonical {
   254  		t.Fatalf("Reference from %q should not support digest", ref)
   255  	}
   256  	if expected, actual := "busybox@sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa", ref.String(); actual != expected {
   257  		t.Fatalf("Invalid parsed reference for %q: expected %q, got %q", ref, expected, actual)
   258  	}
   259  }
   260  
   261  func TestInvalidReferenceComponents(t *testing.T) {
   262  	if _, err := WithName("-foo"); err == nil {
   263  		t.Fatal("Expected WithName to detect invalid name")
   264  	}
   265  	ref, err := WithName("busybox")
   266  	if err != nil {
   267  		t.Fatal(err)
   268  	}
   269  	if _, err := WithTag(ref, "-foo"); err == nil {
   270  		t.Fatal("Expected WithName to detect invalid tag")
   271  	}
   272  	if _, err := WithDigest(ref, digest.Digest("foo")); err == nil {
   273  		t.Fatal("Expected WithName to detect invalid digest")
   274  	}
   275  }