github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap/cmd_known_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package main_test 21 22 import ( 23 "fmt" 24 "net/http" 25 "net/http/httptest" 26 "net/url" 27 28 "github.com/jessevdk/go-flags" 29 "gopkg.in/check.v1" 30 31 "github.com/snapcore/snapd/client" 32 "github.com/snapcore/snapd/store" 33 34 snap "github.com/snapcore/snapd/cmd/snap" 35 ) 36 37 // acquire example data via: 38 // curl -H "accept: application/x.ubuntu.assertion" https://assertions.ubuntu.com/v1/assertions/model/16/canonical/pi2 39 const mockModelAssertion = `type: model 40 authority-id: canonical 41 series: 16 42 brand-id: canonical 43 model: pi99 44 architecture: armhf 45 gadget: pi99 46 kernel: pi99-kernel 47 timestamp: 2016-08-31T00:00:00.0Z 48 sign-key-sha3-384: 9tydnLa6MTJ-jaQTFUXEwHl1yRx7ZS4K5cyFDhYDcPzhS7uyEkDxdUjg9g08BtNn 49 50 AcLorsomethingthatlooksvaguelylikeasignature== 51 ` 52 53 func (s *SnapSuite) TestKnownViaSnapd(c *check.C) { 54 n := 0 55 expectedQuery := url.Values{ 56 "series": []string{"16"}, 57 "brand-id": []string{"canonical"}, 58 "model": []string{"pi99"}, 59 } 60 61 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 62 switch n { 63 case 0: 64 c.Check(r.URL.Path, check.Equals, "/v2/assertions/model") 65 c.Check(r.URL.Query(), check.DeepEquals, expectedQuery) 66 w.Header().Set("X-Ubuntu-Assertions-Count", "1") 67 fmt.Fprintln(w, mockModelAssertion) 68 default: 69 c.Fatalf("expected to get 1 requests, now on %d", n+1) 70 } 71 n++ 72 }) 73 74 // first run "normal" 75 rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "model", "series=16", "brand-id=canonical", "model=pi99"}) 76 c.Assert(err, check.IsNil) 77 c.Assert(rest, check.DeepEquals, []string{}) 78 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 79 c.Check(s.Stderr(), check.Equals, "") 80 c.Check(n, check.Equals, 1) 81 82 // then with "--remote" 83 n = 0 84 s.stdout.Reset() 85 expectedQuery["remote"] = []string{"true"} 86 rest, err = snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"}) 87 c.Assert(err, check.IsNil) 88 c.Assert(rest, check.DeepEquals, []string{}) 89 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 90 c.Check(s.Stderr(), check.Equals, "") 91 c.Check(n, check.Equals, 1) 92 } 93 94 func (s *SnapSuite) TestKnownRemoteViaSnapd(c *check.C) { 95 n := 0 96 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 97 switch n { 98 case 0: 99 c.Check(r.URL.Path, check.Equals, "/v2/assertions/model") 100 c.Check(r.URL.Query(), check.DeepEquals, url.Values{ 101 "series": []string{"16"}, 102 "brand-id": []string{"canonical"}, 103 "model": []string{"pi99"}, 104 "remote": []string{"true"}, 105 }) 106 w.Header().Set("X-Ubuntu-Assertions-Count", "1") 107 fmt.Fprintln(w, mockModelAssertion) 108 default: 109 c.Fatalf("expected to get 1 requests, now on %d", n+1) 110 } 111 n++ 112 }) 113 114 rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"}) 115 c.Assert(err, check.IsNil) 116 c.Assert(rest, check.DeepEquals, []string{}) 117 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 118 c.Check(s.Stderr(), check.Equals, "") 119 c.Check(n, check.Equals, 1) 120 } 121 122 func (s *SnapSuite) TestKnownRemoteDirect(c *check.C) { 123 var server *httptest.Server 124 125 restorer := snap.MockStoreNew(func(cfg *store.Config, stoCtx store.DeviceAndAuthContext) *store.Store { 126 if cfg == nil { 127 cfg = store.DefaultConfig() 128 } 129 serverURL, _ := url.Parse(server.URL) 130 cfg.AssertionsBaseURL = serverURL 131 return store.New(cfg, stoCtx) 132 }) 133 defer restorer() 134 135 n := 0 136 server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 137 c.Assert(r.URL.Path, check.Matches, ".*/assertions/.*") // sanity check request 138 switch n { 139 case 0: 140 c.Check(r.Method, check.Equals, "GET") 141 c.Check(r.URL.Path, check.Equals, "/api/v1/snaps/assertions/model/16/canonical/pi99") 142 fmt.Fprintln(w, mockModelAssertion) 143 default: 144 c.Fatalf("expected to get 1 requests, now on %d", n+1) 145 } 146 147 n++ 148 })) 149 150 // first test "--remote --direct" 151 rest, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "--direct", "model", "series=16", "brand-id=canonical", "model=pi99"}) 152 c.Assert(err, check.IsNil) 153 c.Assert(rest, check.DeepEquals, []string{}) 154 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 155 c.Check(s.Stderr(), check.Equals, "") 156 c.Check(n, check.Equals, 1) 157 158 // "--direct" behave the same as "--remote --direct" 159 s.stdout.Reset() 160 n = 0 161 rest, err = snap.Parser(snap.Client()).ParseArgs([]string{"known", "--direct", "model", "series=16", "brand-id=canonical", "model=pi99"}) 162 c.Assert(err, check.IsNil) 163 c.Assert(rest, check.DeepEquals, []string{}) 164 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 165 c.Check(s.Stderr(), check.Equals, "") 166 c.Check(n, check.Equals, 1) 167 } 168 169 func (s *SnapSuite) TestKnownRemoteAutoFallback(c *check.C) { 170 var server *httptest.Server 171 172 restorer := snap.MockStoreNew(func(cfg *store.Config, stoCtx store.DeviceAndAuthContext) *store.Store { 173 if cfg == nil { 174 cfg = store.DefaultConfig() 175 } 176 serverURL, _ := url.Parse(server.URL) 177 cfg.AssertionsBaseURL = serverURL 178 return store.New(cfg, stoCtx) 179 }) 180 defer restorer() 181 182 n := 0 183 server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 184 c.Assert(r.URL.Path, check.Matches, ".*/assertions/.*") // sanity check request 185 switch n { 186 case 0: 187 c.Check(r.Method, check.Equals, "GET") 188 c.Check(r.URL.Path, check.Equals, "/api/v1/snaps/assertions/model/16/canonical/pi99") 189 fmt.Fprintln(w, mockModelAssertion) 190 default: 191 c.Fatalf("expected to get 1 requests, now on %d", n+1) 192 } 193 n++ 194 })) 195 196 cli := snap.Client() 197 cli.Hijack(func(*http.Request) (*http.Response, error) { 198 return nil, client.ConnectionError{Err: fmt.Errorf("no snapd")} 199 }) 200 201 rest, err := snap.Parser(cli).ParseArgs([]string{"known", "--remote", "model", "series=16", "brand-id=canonical", "model=pi99"}) 202 c.Assert(err, check.IsNil) 203 c.Assert(rest, check.DeepEquals, []string{}) 204 c.Check(s.Stdout(), check.Equals, mockModelAssertion) 205 c.Check(s.Stderr(), check.Equals, "") 206 } 207 208 func (s *SnapSuite) TestKnownRemoteMissingPrimaryKey(c *check.C) { 209 _, err := snap.Parser(snap.Client()).ParseArgs([]string{"known", "--remote", "--direct", "model", "series=16", "brand-id=canonical"}) 210 c.Assert(err, check.ErrorMatches, `cannot query remote assertion: must provide primary key: model`) 211 } 212 213 func (s *SnapSuite) TestAssertTypeNameCompletion(c *check.C) { 214 n := 0 215 s.RedirectClientToTestServer(func(w http.ResponseWriter, r *http.Request) { 216 switch n { 217 case 0: 218 c.Check(r.Method, check.Equals, "GET") 219 c.Check(r.URL.Path, check.Equals, "/v2/assertions") 220 fmt.Fprintln(w, `{"type": "sync", "result": { "types": [ "account", "... more stuff ...", "validation" ] } }`) 221 default: 222 c.Fatalf("expected to get 1 requests, now on %d", n+1) 223 } 224 225 n++ 226 }) 227 228 c.Check(snap.AssertTypeNameCompletion("v"), check.DeepEquals, []flags.Completion{{Item: "validation"}}) 229 c.Check(n, check.Equals, 1) 230 }