github.com/containerd/Containerd@v1.4.13/reference/reference_test.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package reference
    18  
    19  import (
    20  	"testing"
    21  
    22  	digest "github.com/opencontainers/go-digest"
    23  )
    24  
    25  func TestReferenceParser(t *testing.T) {
    26  	for _, testcase := range []struct {
    27  		Skip       bool
    28  		Name       string
    29  		Input      string
    30  		Normalized string
    31  		Digest     digest.Digest
    32  		Hostname   string
    33  		Expected   Spec
    34  		Err        error
    35  	}{
    36  		{
    37  			Name:       "Basic",
    38  			Input:      "docker.io/library/redis:foo?fooo=asdf",
    39  			Normalized: "docker.io/library/redis:foo",
    40  			Hostname:   "docker.io",
    41  			Expected: Spec{
    42  				Locator: "docker.io/library/redis",
    43  				Object:  "foo",
    44  			},
    45  		},
    46  		{
    47  			Name:       "BasicWithDigest",
    48  			Input:      "docker.io/library/redis:foo@sha256:abcdef?fooo=asdf",
    49  			Normalized: "docker.io/library/redis:foo@sha256:abcdef",
    50  			Hostname:   "docker.io",
    51  			Digest:     "sha256:abcdef",
    52  			Expected: Spec{
    53  				Locator: "docker.io/library/redis",
    54  				Object:  "foo@sha256:abcdef",
    55  			},
    56  		},
    57  
    58  		{
    59  			Name:  "DigestOnly",
    60  			Input: "docker.io/library/redis@sha256:abcdef?fooo=asdf",
    61  			Expected: Spec{
    62  				Locator: "docker.io/library/redis",
    63  				Object:  "@sha256:abcdef",
    64  			},
    65  			Hostname:   "docker.io",
    66  			Normalized: "docker.io/library/redis@sha256:abcdef",
    67  			Digest:     "sha256:abcdef",
    68  		},
    69  		{
    70  			Name:       "AtShortDigest",
    71  			Input:      "docker.io/library/redis:obj@abcdef?fooo=asdf",
    72  			Normalized: "docker.io/library/redis:obj@abcdef",
    73  			Hostname:   "docker.io",
    74  			Digest:     "abcdef",
    75  			Expected: Spec{
    76  				Locator: "docker.io/library/redis",
    77  				Object:  "obj@abcdef",
    78  			},
    79  		},
    80  		{
    81  			Name:       "HostWithPort",
    82  			Input:      "localhost:5000/library/redis:obj@abcdef?fooo=asdf",
    83  			Normalized: "localhost:5000/library/redis:obj@abcdef",
    84  			Hostname:   "localhost:5000",
    85  			Digest:     "abcdef",
    86  			Expected: Spec{
    87  				Locator: "localhost:5000/library/redis",
    88  				Object:  "obj@abcdef",
    89  			},
    90  		},
    91  		{
    92  			Name:  "HostnameRequired",
    93  			Input: "/docker.io/library/redis:obj@abcdef?fooo=asdf",
    94  			Err:   ErrHostnameRequired,
    95  		},
    96  		{
    97  			Name:       "ErrObjectRequired",
    98  			Input:      "docker.io/library/redis?fooo=asdf",
    99  			Hostname:   "docker.io",
   100  			Normalized: "docker.io/library/redis",
   101  			Expected: Spec{
   102  				Locator: "docker.io/library/redis",
   103  				Object:  "",
   104  			},
   105  		},
   106  		{
   107  			Name:     "Subdomain",
   108  			Input:    "sub-dom1.foo.com/bar/baz/quux:latest",
   109  			Hostname: "sub-dom1.foo.com",
   110  			Expected: Spec{
   111  				Locator: "sub-dom1.foo.com/bar/baz/quux",
   112  				Object:  "latest",
   113  			},
   114  		},
   115  		{
   116  			Name:     "SubdomainWithLongTag",
   117  			Input:    "sub-dom1.foo.com/bar/baz/quux:some-long-tag",
   118  			Hostname: "sub-dom1.foo.com",
   119  			Expected: Spec{
   120  				Locator: "sub-dom1.foo.com/bar/baz/quux",
   121  				Object:  "some-long-tag",
   122  			},
   123  		},
   124  		{
   125  			Name:     "AGCRAppears",
   126  			Input:    "b.gcr.io/test.example.com/my-app:test.example.com",
   127  			Hostname: "b.gcr.io",
   128  			Expected: Spec{
   129  				Locator: "b.gcr.io/test.example.com/my-app",
   130  				Object:  "test.example.com",
   131  			},
   132  		},
   133  		{
   134  			Name:     "Punycode",
   135  			Input:    "xn--n3h.com/myimage:xn--n3h.com", // ☃.com in punycode
   136  			Hostname: "xn--n3h.com",
   137  			Expected: Spec{
   138  				Locator: "xn--n3h.com/myimage",
   139  				Object:  "xn--n3h.com",
   140  			},
   141  		},
   142  		{
   143  
   144  			Name:     "PunycodeWithDigest",
   145  			Input:    "xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff",
   146  			Hostname: "xn--7o8h.com",
   147  			Digest:   "sha512:fffffff",
   148  			Expected: Spec{
   149  				Locator: "xn--7o8h.com/myimage",
   150  				Object:  "xn--7o8h.com@sha512:fffffff",
   151  			},
   152  		},
   153  		{
   154  			Skip:     true, // TODO(stevvooe): Implement this case.
   155  			Name:     "SchemeDefined",
   156  			Input:    "http://xn--7o8h.com/myimage:xn--7o8h.com@sha512:fffffff",
   157  			Hostname: "xn--7o8h.com",
   158  			Digest:   "sha512:fffffff",
   159  			Err:      ErrInvalid,
   160  		},
   161  	} {
   162  		t.Run(testcase.Name, func(t *testing.T) {
   163  			if testcase.Skip {
   164  				t.Skip("testcase disabled")
   165  				return
   166  			}
   167  
   168  			ref, err := Parse(testcase.Input)
   169  			if err != testcase.Err {
   170  				if testcase.Err != nil {
   171  					t.Fatalf("expected error %v for %q, got %v, %#v", testcase.Err, testcase.Input, err, ref)
   172  				} else {
   173  					t.Fatalf("unexpected error %v", err)
   174  				}
   175  			} else if testcase.Err != nil {
   176  				return
   177  			}
   178  
   179  			if ref != testcase.Expected {
   180  				t.Fatalf("%#v != %#v", ref, testcase.Expected)
   181  			}
   182  
   183  			if testcase.Normalized == "" {
   184  				testcase.Normalized = testcase.Input
   185  			}
   186  
   187  			if ref.String() != testcase.Normalized {
   188  				t.Fatalf("normalization failed: %v != %v", ref.String(), testcase.Normalized)
   189  			}
   190  
   191  			if ref.Digest() != testcase.Digest {
   192  				t.Fatalf("digest extraction failed: %v != %v", ref.Digest(), testcase.Digest)
   193  			}
   194  
   195  			if ref.Hostname() != testcase.Hostname {
   196  				t.Fatalf("unexpected hostname: %v != %v", ref.Hostname(), testcase.Hostname)
   197  			}
   198  		})
   199  	}
   200  }