1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package remote
16
17 import (
18 "context"
19 "fmt"
20 "net/http"
21 "net/http/httptest"
22 "net/url"
23 "strings"
24 "testing"
25
26 "github.com/google/go-cmp/cmp"
27 "github.com/google/go-containerregistry/pkg/name"
28 )
29
30 func TestList(t *testing.T) {
31 cases := []struct {
32 name string
33 responseBody []byte
34 wantErr bool
35 wantTags []string
36 }{{
37 name: "success",
38 responseBody: []byte(`{"tags":["foo","bar"]}`),
39 wantErr: false,
40 wantTags: []string{"foo", "bar"},
41 }, {
42 name: "not json",
43 responseBody: []byte("notjson"),
44 wantErr: true,
45 }}
46
47 repoName := "ubuntu"
48
49 for _, tc := range cases {
50 t.Run(tc.name, func(t *testing.T) {
51 tagsPath := fmt.Sprintf("/v2/%s/tags/list", repoName)
52 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
53 switch r.URL.Path {
54 case "/v2/":
55 w.WriteHeader(http.StatusOK)
56 case tagsPath:
57 if r.Method != http.MethodGet {
58 t.Errorf("Method; got %v, want %v", r.Method, http.MethodGet)
59 }
60
61 w.Write(tc.responseBody)
62 default:
63 t.Fatalf("Unexpected path: %v", r.URL.Path)
64 }
65 }))
66 defer server.Close()
67 u, err := url.Parse(server.URL)
68 if err != nil {
69 t.Fatalf("url.Parse(%v) = %v", server.URL, err)
70 }
71
72 repo, err := name.NewRepository(fmt.Sprintf("%s/%s", u.Host, repoName), name.WeakValidation)
73 if err != nil {
74 t.Fatalf("name.NewRepository(%v) = %v", repoName, err)
75 }
76
77 tags, err := List(repo)
78 if (err != nil) != tc.wantErr {
79 t.Errorf("List() wrong error: %v, want %v: %v\n", (err != nil), tc.wantErr, err)
80 }
81
82 if diff := cmp.Diff(tc.wantTags, tags); diff != "" {
83 t.Errorf("List() wrong tags (-want +got) = %s", diff)
84 }
85 })
86 }
87 }
88
89 func TestCancelledList(t *testing.T) {
90 ctx, cancel := context.WithCancel(context.Background())
91 cancel()
92
93 repoName := "doesnotmatter"
94 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
95 switch r.URL.Path {
96 case "/v2/":
97 w.WriteHeader(http.StatusOK)
98 default:
99 t.Fatalf("Unexpected path: %v", r.URL.Path)
100 }
101 }))
102 defer server.Close()
103 u, err := url.Parse(server.URL)
104 if err != nil {
105 t.Fatalf("url.Parse(%v) = %v", server.URL, err)
106 }
107
108 repo, err := name.NewRepository(fmt.Sprintf("%s/%s", u.Host, repoName), name.WeakValidation)
109 if err != nil {
110 t.Fatalf("name.NewRepository(%v) = %v", repoName, err)
111 }
112
113 _, err = ListWithContext(ctx, repo)
114 if err == nil || !strings.Contains(err.Error(), "context canceled") {
115 t.Errorf(`unexpected error; want "context canceled", got %v`, err)
116 }
117 }
118
119 func makeResp(hdr string) *http.Response {
120 return &http.Response{
121 Header: http.Header{
122 "Link": []string{hdr},
123 },
124 }
125 }
126
127 func TestGetNextPageURL(t *testing.T) {
128 for _, hdr := range []string{
129 "",
130 "<",
131 "><",
132 "<>",
133 fmt.Sprintf("<%c>", 0x7f),
134 } {
135 u, err := getNextPageURL(makeResp(hdr))
136 if err == nil && u != nil {
137 t.Errorf("Expected err, got %+v", u)
138 }
139 }
140
141 good := &http.Response{
142 Header: http.Header{
143 "Link": []string{"<example.com>"},
144 },
145 Request: &http.Request{
146 URL: &url.URL{
147 Scheme: "https",
148 },
149 },
150 }
151 u, err := getNextPageURL(good)
152 if err != nil {
153 t.Fatal(err)
154 }
155
156 if u.Scheme != "https" {
157 t.Errorf("expected scheme to match request, got %s", u.Scheme)
158 }
159 }
160
View as plain text