...

Source file src/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/request_test.go

Documentation: cuelabs.dev/go/oci/ociregistry/internal/ocirequest

     1  // Copyright 2023 CUE Labs AG
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ocirequest
    16  
    17  import (
    18  	"net/url"
    19  	"testing"
    20  
    21  	"github.com/go-quicktest/qt"
    22  )
    23  
    24  var parseRequestTests = []struct {
    25  	testName string
    26  	method   string
    27  	url      string
    28  
    29  	wantRequest   *Request
    30  	wantError     string
    31  	wantConstruct string
    32  }{{
    33  	testName: "ping",
    34  	method:   "GET",
    35  	url:      "/v2",
    36  	wantRequest: &Request{
    37  		Kind: ReqPing,
    38  	},
    39  	wantConstruct: "/v2/",
    40  }, {
    41  	testName: "ping",
    42  	method:   "GET",
    43  	url:      "/v2/",
    44  	wantRequest: &Request{
    45  		Kind: ReqPing,
    46  	},
    47  }, {
    48  	testName: "getBlob",
    49  	method:   "GET",
    50  	url:      "/v2/foo/bar/blobs/sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
    51  	wantRequest: &Request{
    52  		Kind:   ReqBlobGet,
    53  		Repo:   "foo/bar",
    54  		Digest: "sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
    55  	},
    56  }, {
    57  	testName:  "getBlobInvalidDigest",
    58  	method:    "GET",
    59  	url:       "/v2/foo/bar/blobs/sha256:wrong",
    60  	wantError: `badly formed digest`,
    61  }, {
    62  	testName:  "getBlobInvalidRepo",
    63  	method:    "GET",
    64  	url:       "/v2/foo/bAr/blobs/sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824",
    65  	wantError: `invalid repository name`,
    66  }, {
    67  	testName: "startUpload",
    68  	method:   "POST",
    69  	url:      "/v2/somerepo/blobs/uploads/",
    70  	wantRequest: &Request{
    71  		Kind: ReqBlobStartUpload,
    72  		Repo: "somerepo",
    73  	},
    74  }, {
    75  	testName: "uploadChunk",
    76  	method:   "PATCH",
    77  	url:      "/v2/somerepo/blobs/uploads/YmxhaGJsYWg",
    78  	wantRequest: &Request{
    79  		Kind:     ReqBlobUploadChunk,
    80  		Repo:     "somerepo",
    81  		UploadID: "blahblah",
    82  	},
    83  }, {
    84  	testName: "uploadChunk",
    85  	method:   "PATCH",
    86  	url:      "/v2/somerepo/blobs/uploads/YmxhaGJsYWg",
    87  	wantRequest: &Request{
    88  		Kind:     ReqBlobUploadChunk,
    89  		Repo:     "somerepo",
    90  		UploadID: "blahblah",
    91  	},
    92  }, {
    93  	testName:  "badlyFormedUploadDigest",
    94  	method:    "POST",
    95  	url:       "/v2/foo/blobs/uploads?digest=sha256:fake",
    96  	wantError: "badly formed digest",
    97  }, {
    98  	testName: "getUploadInfo",
    99  	method:   "GET",
   100  	url:      "/v2/myorg/myrepo/blobs/uploads/YmxhaGJsYWg",
   101  	wantRequest: &Request{
   102  		Kind:     ReqBlobUploadInfo,
   103  		Repo:     "myorg/myrepo",
   104  		UploadID: "blahblah",
   105  	},
   106  }, {
   107  	testName: "mount",
   108  	method:   "POST",
   109  	url:      "/v2/x/y/blobs/uploads/?mount=sha256:c659529df24a1878f6df8d93c652280235a50b95e862d8e5cb566ee5b9ed6386&from=somewhere/other",
   110  	wantRequest: &Request{
   111  		Kind:     ReqBlobMount,
   112  		Repo:     "x/y",
   113  		Digest:   "sha256:c659529df24a1878f6df8d93c652280235a50b95e862d8e5cb566ee5b9ed6386",
   114  		FromRepo: "somewhere/other",
   115  	},
   116  }, {
   117  	testName: "mount2",
   118  	method:   "POST",
   119  	url:      "/v2/myorg/other/blobs/uploads/?from=myorg%2Fmyrepo&mount=sha256%3Ad647b322fff1e9dcb828ee67a6c6d1ed0ceef760988fdf54f9cfdeb96186e001",
   120  	wantRequest: &Request{
   121  		Kind:     ReqBlobMount,
   122  		Repo:     "myorg/other",
   123  		Digest:   "sha256:d647b322fff1e9dcb828ee67a6c6d1ed0ceef760988fdf54f9cfdeb96186e001",
   124  		FromRepo: "myorg/myrepo",
   125  	},
   126  }, {
   127  	testName: "mountWithNoFrom",
   128  	method:   "POST",
   129  	url:      "/v2/x/y/blobs/uploads/?mount=sha256:c659529df24a1878f6df8d93c652280235a50b95e862d8e5cb566ee5b9ed6386",
   130  	wantRequest: &Request{
   131  		Kind: ReqBlobStartUpload,
   132  		Repo: "x/y",
   133  	},
   134  	wantConstruct: "/v2/x/y/blobs/uploads/",
   135  }, {
   136  	testName: "manifestHead",
   137  	method:   "HEAD",
   138  	url:      "/v2/myorg/myrepo/manifests/sha256:681aef2367e055f33cb8a6ab9c3090931f6eefd0c3ef15c6e4a79bdadfdb8982",
   139  	wantRequest: &Request{
   140  		Kind:   ReqManifestHead,
   141  		Repo:   "myorg/myrepo",
   142  		Digest: "sha256:681aef2367e055f33cb8a6ab9c3090931f6eefd0c3ef15c6e4a79bdadfdb8982",
   143  	},
   144  }}
   145  
   146  func TestParseRequest(t *testing.T) {
   147  	for _, test := range parseRequestTests {
   148  		t.Run(test.testName, func(t *testing.T) {
   149  			u, err := url.Parse(test.url)
   150  			if err != nil {
   151  				t.Fatal(err)
   152  			}
   153  			rreq, err := Parse(test.method, u)
   154  			if test.wantError != "" {
   155  				qt.Assert(t, qt.ErrorMatches(err, test.wantError))
   156  				// TODO http code
   157  				return
   158  			}
   159  			qt.Assert(t, qt.IsNil(err))
   160  			qt.Assert(t, qt.DeepEquals(rreq, test.wantRequest))
   161  			method, ustr := rreq.MustConstruct()
   162  			if test.wantConstruct == "" {
   163  				test.wantConstruct = test.url
   164  			}
   165  
   166  			qt.Check(t, qt.Equals(method, test.method))
   167  			qt.Check(t, qt.Equals(canonURL(ustr), canonURL(test.wantConstruct)))
   168  		})
   169  	}
   170  }
   171  
   172  func canonURL(ustr string) string {
   173  	u, err := url.Parse(ustr)
   174  	if err != nil {
   175  		panic(err)
   176  	}
   177  	qv := u.Query()
   178  	if len(qv) == 0 {
   179  		return ustr
   180  	}
   181  	u.RawQuery = qv.Encode()
   182  	return u.String()
   183  }
   184  

View as plain text