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