gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/overlord/patch/patch6_2_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 patch_test 21 22 import ( 23 "bytes" 24 25 . "gopkg.in/check.v1" 26 27 "github.com/snapcore/snapd/dirs" 28 "github.com/snapcore/snapd/overlord/patch" 29 "github.com/snapcore/snapd/overlord/snapstate" 30 "github.com/snapcore/snapd/overlord/state" 31 "github.com/snapcore/snapd/snap" 32 ) 33 34 type patch62Suite struct{} 35 36 var _ = Suite(&patch62Suite{}) 37 38 // State with snapd snap marked as 'app' (to be converted to 'snapd' 39 // type) and a regular 'other' snap, plus three tasks - two of them 40 // need to have their SnapSetup migrated to 'snapd' type. 41 var statePatch6_2JSON = []byte(` 42 { 43 "data": { 44 "patch-level": 6, 45 "snaps": { 46 "snapd": { 47 "type": "app", 48 "sequence": [ 49 { 50 "name": "snapd", 51 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 52 "revision": "2" 53 } 54 ], 55 "active": true, 56 "current": "2", 57 "channel": "stable" 58 }, 59 "other": { 60 "type": "app", 61 "sequence": [ 62 { 63 "name": "snapd", 64 "snap-id": "foo", 65 "revision": "2" 66 } 67 ], 68 "active": true, 69 "current": "2", 70 "channel": "stable" 71 } 72 } 73 }, 74 "changes": { 75 "6": { 76 "id": "6", 77 "kind": "auto-refresh", 78 "summary": "...", 79 "status": 0, 80 "clean": true, 81 "data": { 82 "api-data": { 83 "snap-names": ["snapd"] 84 }, 85 "snap-names": ["snapd"] 86 }, 87 "task-ids": ["1", "8"] 88 }, 89 "9": { 90 "id": "9", 91 "kind": "auto-refresh", 92 "summary": "...", 93 "status": 4, 94 "clean": true, 95 "data": { 96 "api-data": { 97 "snap-names": ["snapd"] 98 }, 99 "snap-names": ["snapd"] 100 }, 101 "task-ids": ["10"] 102 } 103 }, 104 "tasks": { 105 "1": { 106 "id": "1", 107 "kind": "download-snap", 108 "summary": "...", 109 "status": 2, 110 "clean": true, 111 "data": { 112 "snap-setup": { 113 "channel": "stable", 114 "type": "app", 115 "is-auto-refresh": true, 116 "snap-path": "/path", 117 "download-info": { 118 "download-url": "foo", 119 "size": 1234, 120 "sha3-384": "123456", 121 "deltas": [ 122 { 123 "from-revision": 10934, 124 "to-revision": 10972, 125 "format": "xdelta3", 126 "download-url": "foo", 127 "size": 16431136, 128 "sha3-384": "1" 129 } 130 ] 131 }, 132 "side-info": { 133 "name": "snapd", 134 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 135 "revision": "1", 136 "channel": "stable", 137 "title": "snapd" 138 }, 139 "media": [ 140 { 141 "type": "icon", 142 "url": "a" 143 }, 144 { 145 "type": "screenshot", 146 "url": "2" 147 }, 148 { 149 "type": "screenshot", 150 "url": "3" 151 }, 152 { 153 "type": "screenshot", 154 "url": "4" 155 }, 156 { 157 "type": "video", 158 "url": "5" 159 } 160 ] 161 } 162 }, 163 "change": "6" 164 }, 165 "8": { 166 "id": "8", 167 "kind": "other", 168 "summary": "", 169 "status": 4, 170 "data": { 171 "snap-setup": { 172 "channel": "stable", 173 "type": "app", 174 "snap-path": "/path", 175 "side-info": { 176 "name": "snapd", 177 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 178 "revision": "1", 179 "channel": "stable", 180 "title": "snapd" 181 } 182 } 183 }, 184 "change": "6" 185 }, 186 "10": { 187 "id": "10", 188 "kind": "other", 189 "summary": "", 190 "status": 4, 191 "data": { 192 "snap-setup": { 193 "channel": "stable", 194 "type": "app", 195 "snap-path": "/path", 196 "side-info": { 197 "name": "snapd", 198 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 199 "revision": "1", 200 "channel": "stable", 201 "title": "snapd" 202 } 203 } 204 }, 205 "change": "9" 206 } 207 } 208 } 209 } 210 }`) 211 212 // State with 'snapd' snap with proper snap type, and an extra 'other' 213 // snap with snapd snap-id (PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4) but 214 // improper 'app' type. 215 var statePatch6_2JSONWithSnapd = []byte(` 216 { 217 "data": { 218 "patch-level": 6, 219 "snaps": { 220 "snapd": { 221 "type": "snapd", 222 "sequence": [ 223 { 224 "name": "snapd", 225 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 226 "revision": "2" 227 } 228 ], 229 "active": true, 230 "current": "2", 231 "channel": "stable" 232 }, 233 "other": { 234 "type": "app", 235 "sequence": [ 236 { 237 "name": "other", 238 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 239 "revision": "1" 240 } 241 ], 242 "active": true, 243 "current": "1", 244 "channel": "stable" 245 } 246 } 247 }, 248 "changes": {} 249 }, 250 "tasks": {} 251 } 252 }`) 253 254 // State with two snaps with snapd snap-id 255 // (PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4) and improper snap types 256 var statePatch6_2JSONWithSnapd2 = []byte(` 257 { 258 "data": { 259 "patch-level": 6, 260 "snaps": { 261 "snapd": { 262 "type": "app", 263 "sequence": [ 264 { 265 "name": "snapd", 266 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 267 "revision": "2" 268 } 269 ], 270 "active": true, 271 "current": "2", 272 "channel": "stable" 273 }, 274 "other": { 275 "type": "app", 276 "sequence": [ 277 { 278 "name": "other", 279 "snap-id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", 280 "revision": "1" 281 } 282 ], 283 "active": true, 284 "current": "1", 285 "channel": "stable" 286 } 287 } 288 }, 289 "changes": {} 290 }, 291 "tasks": {} 292 } 293 }`) 294 295 func (s *patch62Suite) SetUpTest(c *C) { 296 dirs.SetRootDir(c.MkDir()) 297 snap.MockSanitizePlugsSlots(func(*snap.Info) {}) 298 } 299 300 func (s *patch62Suite) TestPatch62(c *C) { 301 restore1 := patch.MockLevel(6, 2) 302 defer restore1() 303 304 r := bytes.NewReader(statePatch6_2JSON) 305 st, err := state.ReadState(nil, r) 306 c.Assert(err, IsNil) 307 308 c.Assert(patch.Apply(st), IsNil) 309 st.Lock() 310 defer st.Unlock() 311 312 // our mocks are correct 313 c.Assert(st.Changes(), HasLen, 2) 314 c.Assert(st.Tasks(), HasLen, 3) 315 316 var snapst snapstate.SnapState 317 c.Assert(snapstate.Get(st, "snapd", &snapst), IsNil) 318 c.Check(snapst.SnapType, Equals, "snapd") 319 320 // sanity check - "other" is untouched 321 c.Assert(snapstate.Get(st, "other", &snapst), IsNil) 322 c.Check(snapst.SnapType, Equals, "app") 323 324 // check tasks 325 task := st.Task("1") 326 c.Assert(task, NotNil) 327 328 var snapsup snapstate.SnapSetup 329 err = task.Get("snap-setup", &snapsup) 330 c.Assert(err, IsNil) 331 c.Check(snapsup.Type, Equals, snap.TypeSnapd) 332 333 // sanity check, structures not defined explicitly via patch62* are preserved 334 c.Check(snapsup.Flags.IsAutoRefresh, Equals, true) 335 c.Assert(snapsup.Media, HasLen, 5) 336 c.Check(snapsup.Media[0].URL, Equals, "a") 337 c.Assert(snapsup.DownloadInfo, NotNil) 338 c.Check(snapsup.DownloadInfo.DownloadURL, Equals, "foo") 339 c.Check(snapsup.DownloadInfo.Deltas, HasLen, 1) 340 341 task = st.Task("8") 342 c.Assert(task, NotNil) 343 c.Assert(task.Get("snap-setup", &snapsup), IsNil) 344 c.Check(snapsup.Type, Equals, snap.TypeSnapd) 345 346 // task 10 not updated because the change is ready 347 task = st.Task("10") 348 c.Assert(task, NotNil) 349 c.Assert(task.Get("snap-setup", &snapsup), IsNil) 350 c.Check(snapsup.Type, Equals, snap.TypeApp) 351 } 352 353 func (s *patch62Suite) TestPatch62StopsAfterFirstSnapd(c *C) { 354 restore1 := patch.MockLevel(6, 2) 355 defer restore1() 356 357 for i, sj := range [][]byte{statePatch6_2JSONWithSnapd, statePatch6_2JSONWithSnapd2} { 358 // sanity check 359 c.Assert(patch.Level, Equals, 6) 360 c.Assert(patch.Sublevel, Equals, 2) 361 362 r := bytes.NewReader(sj) 363 st, err := state.ReadState(nil, r) 364 c.Assert(err, IsNil) 365 366 c.Assert(patch.Apply(st), IsNil) 367 st.Lock() 368 defer st.Unlock() 369 370 var snapdCount int 371 for _, name := range []string{"snapd", "other"} { 372 var snapst snapstate.SnapState 373 c.Assert(snapstate.Get(st, name, &snapst), IsNil) 374 if snapst.SnapType == "snapd" { 375 snapdCount++ 376 } 377 } 378 c.Check(snapdCount, Equals, 1, Commentf("#%d", i)) 379 } 380 }