github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/client/model_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 client_test 21 22 import ( 23 "encoding/json" 24 "errors" 25 "io/ioutil" 26 "net/http" 27 28 "golang.org/x/xerrors" 29 30 . "gopkg.in/check.v1" 31 32 "github.com/snapcore/snapd/asserts" 33 ) 34 35 const happyModelAssertionResponse = `type: model 36 authority-id: mememe 37 series: 16 38 brand-id: mememe 39 model: test-model 40 architecture: amd64 41 base: core18 42 gadget: pc=18 43 kernel: pc-kernel=18 44 required-snaps: 45 - core 46 - hello-world 47 timestamp: 2017-07-27T00:00:00.0Z 48 sign-key-sha3-384: 8B3Wmemeu3H6i4dEV4Q85Q4gIUCHIBCNMHq49e085QeLGHi7v27l3Cqmemer4__t 49 50 AcLBcwQAAQoAHRYhBMbX+t6MbKGH5C3nnLZW7+q0g6ELBQJdTdwTAAoJELZW7+q0g6ELEvgQAI3j 51 jXTqR6kKOqvw94pArwdMDUaZ++tebASAZgso8ejrW2DQGWSc0Q7SQICIR8bvHxqS1GtupQswOzwS 52 U8hjDTv7WEchH1jylyTj/1W1GernmitTKycecRlEkSOE+EpuqBFgTtj6PdA1Fj3CiCRi1rLMhgF2 53 luCOitBLaP+E8P3fuATsLqqDLYzt1VY4Y14MU75hMn+CxAQdnOZTI+NzGMasPsldmOYCPNaN/b3N 54 6/fDLU47RtNlMJ3K0Tz8kj0bqRbegKlD0RdNbAgo9iZwNmrr5E9WCu9f/0rUor/NIxO77H2ExIll 55 zhmsZ7E6qlxvAgBmzKgAXrn68gGrBkIb0eXKiCaKy/i2ApvjVZ9HkOzA6Ldd+SwNJv/iA8rdiMsq 56 p2BfKV5f3ju5b6+WktHxAakJ8iqQmj9Yh7piHjsOAUf1PEJd2s2nqQ+pEEn1F0B23gVCY/Fa9YRQ 57 iKtWVeL3rBw4dSAaK9rpTMqlNcr+yrdXfTK5YzkCC6RU4yzc5MW0hKeseeSiEDSaRYxvftjFfVNa 58 ZaVXKg8Lu+cHtCJDeYXEkPIDQzXswdBO1M8Mb9D0mYxQwHxwvsWv1DByB+Otq08EYgPh4kyHo7ag 59 85yK2e/NQ/fxSwQJMhBF74jM1z9arq6RMiE/KOleFAOraKn2hcROKnEeinABW+sOn6vNuMVv 60 ` 61 62 // note: this serial assertion was generated by adding print statements to the 63 // test in api_model_test.go that generate a fake serial assertion 64 const happySerialAssertionResponse = `type: serial 65 authority-id: my-brand 66 brand-id: my-brand 67 model: my-old-model 68 serial: serialserial 69 device-key: 70 AcZrBFaFwYABAvCgEOrrLA6FKcreHxCcOoTgBUZ+IRG7Nb8tzmEAklaQPGpv7skapUjwD1luE2go 71 mTcoTssVHrfLpBoSDV1aBs44rg3NK40ZKPJP7d2zkds1GxUo1Ea5vfet3SJ4h3aRABEBAAE= 72 device-key-sha3-384: iqLo9doLzK8De9925UrdUyuvPbBad72OTWVE9YJXqd6nz9dKvwJ_lHP5bVxrl3VO 73 timestamp: 2019-08-26T16:34:21-05:00 74 sign-key-sha3-384: anCEGC2NYq7DzDEi6y7OafQCVeVLS90XlLt9PNjrRl9sim5rmRHDDNFNO7ODcWQW 75 76 AcJwBAABCgAGBQJdZFBdAADCLALwR6Sy24wm9PffwbvUhOEXneyY3BnxKC0+NgdHu1gU8go9vEP1 77 i+Flh5uoS70+MBIO+nmF8T+9JWIx2QWFDDxvcuFosnIhvUajCEQohauys5FMz/H/WvB0vrbTBpvK 78 eg==` 79 80 const noModelAssertionYetResponse = ` 81 { 82 "type": "error", 83 "status-code": 404, 84 "status": "Not Found", 85 "result": { 86 "message": "no model assertion yet", 87 "kind": "assertion-not-found", 88 "value": "model" 89 } 90 }` 91 92 const noSerialAssertionYetResponse = ` 93 { 94 "type": "error", 95 "status-code": 404, 96 "status": "Not Found", 97 "result": { 98 "message": "no serial assertion yet", 99 "kind": "assertion-not-found", 100 "value": "serial" 101 } 102 }` 103 104 func (cs *clientSuite) TestClientRemodelEndpoint(c *C) { 105 cs.cli.Remodel([]byte(`{"new-model": "some-model"}`)) 106 c.Check(cs.req.Method, Equals, "POST") 107 c.Check(cs.req.URL.Path, Equals, "/v2/model") 108 } 109 110 func (cs *clientSuite) TestClientRemodel(c *C) { 111 cs.status = 202 112 cs.rsp = `{ 113 "type": "async", 114 "status-code": 202, 115 "result": {}, 116 "change": "d728" 117 }` 118 remodelJsonData := []byte(`{"new-model": "some-model"}`) 119 id, err := cs.cli.Remodel(remodelJsonData) 120 c.Assert(err, IsNil) 121 c.Check(id, Equals, "d728") 122 c.Assert(cs.req.Header.Get("Content-Type"), Equals, "application/json") 123 124 body, err := ioutil.ReadAll(cs.req.Body) 125 c.Assert(err, IsNil) 126 jsonBody := make(map[string]string) 127 err = json.Unmarshal(body, &jsonBody) 128 c.Assert(err, IsNil) 129 c.Check(jsonBody, HasLen, 1) 130 c.Check(jsonBody["new-model"], Equals, string(remodelJsonData)) 131 } 132 133 func (cs *clientSuite) TestClientGetModelHappy(c *C) { 134 cs.status = 200 135 cs.rsp = happyModelAssertionResponse 136 modelAssertion, err := cs.cli.CurrentModelAssertion() 137 c.Assert(err, IsNil) 138 expectedAssert, err := asserts.Decode([]byte(happyModelAssertionResponse)) 139 c.Assert(err, IsNil) 140 c.Assert(modelAssertion, DeepEquals, expectedAssert) 141 } 142 143 func (cs *clientSuite) TestClientGetModelNoModel(c *C) { 144 cs.status = 404 145 cs.rsp = noModelAssertionYetResponse 146 cs.header = http.Header{} 147 cs.header.Add("Content-Type", "application/json") 148 _, err := cs.cli.CurrentModelAssertion() 149 c.Assert(err, ErrorMatches, "no model assertion yet") 150 } 151 152 func (cs *clientSuite) TestClientGetModelNoSerial(c *C) { 153 cs.status = 404 154 cs.rsp = noSerialAssertionYetResponse 155 cs.header = http.Header{} 156 cs.header.Add("Content-Type", "application/json") 157 _, err := cs.cli.CurrentSerialAssertion() 158 c.Assert(err, ErrorMatches, "no serial assertion yet") 159 } 160 161 func (cs *clientSuite) TestClientGetSerialHappy(c *C) { 162 cs.status = 200 163 cs.rsp = happySerialAssertionResponse 164 serialAssertion, err := cs.cli.CurrentSerialAssertion() 165 c.Assert(err, IsNil) 166 expectedAssert, err := asserts.Decode([]byte(happySerialAssertionResponse)) 167 c.Assert(err, IsNil) 168 c.Assert(serialAssertion, DeepEquals, expectedAssert) 169 } 170 171 func (cs *clientSuite) TestClientCurrentModelAssertionErrIsWrapped(c *C) { 172 cs.err = errors.New("boom") 173 _, err := cs.cli.CurrentModelAssertion() 174 var e xerrors.Wrapper 175 c.Assert(err, Implements, &e) 176 }