github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/overlord/snapstate/handlers_aliasesv2_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 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 snapstate_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 "gopkg.in/tomb.v2" 25 26 "github.com/snapcore/snapd/overlord/snapstate" 27 "github.com/snapcore/snapd/overlord/snapstate/backend" 28 "github.com/snapcore/snapd/overlord/state" 29 "github.com/snapcore/snapd/snap" 30 ) 31 32 func (s *snapmgrTestSuite) TestDoSetAutoAliases(c *C) { 33 s.state.Lock() 34 defer s.state.Unlock() 35 36 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 37 c.Check(info.InstanceName(), Equals, "alias-snap") 38 return map[string]string{ 39 "alias1": "cmd1", 40 "alias2": "cmd2", 41 "alias4": "cmd4", 42 }, nil 43 } 44 45 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 46 Sequence: []*snap.SideInfo{ 47 {RealName: "alias-snap", Revision: snap.R(11)}, 48 }, 49 Current: snap.R(11), 50 Active: true, 51 AutoAliasesDisabled: false, 52 AliasesPending: true, 53 Aliases: map[string]*snapstate.AliasTarget{ 54 "alias1": {Auto: "cmd1"}, 55 "alias2": {Auto: "cmd2x"}, 56 "alias3": {Auto: "cmd3"}, 57 }, 58 }) 59 60 t := s.state.NewTask("set-auto-aliases", "test") 61 t.Set("snap-setup", &snapstate.SnapSetup{ 62 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 63 }) 64 chg := s.state.NewChange("dummy", "...") 65 chg.AddTask(t) 66 67 s.state.Unlock() 68 69 s.se.Ensure() 70 s.se.Wait() 71 72 s.state.Lock() 73 74 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 75 76 var snapst snapstate.SnapState 77 err := snapstate.Get(s.state, "alias-snap", &snapst) 78 c.Assert(err, IsNil) 79 80 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 81 "alias1": {Auto: "cmd1"}, 82 "alias2": {Auto: "cmd2"}, 83 "alias4": {Auto: "cmd4"}, 84 }) 85 } 86 87 func (s *snapmgrTestSuite) TestDoSetAutoAliasesFirstInstall(c *C) { 88 s.state.Lock() 89 defer s.state.Unlock() 90 91 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 92 c.Check(info.InstanceName(), Equals, "alias-snap") 93 return map[string]string{ 94 "alias1": "cmd1", 95 "alias2": "cmd2", 96 "alias4": "cmd4", 97 }, nil 98 } 99 100 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 101 Sequence: []*snap.SideInfo{ 102 {RealName: "alias-snap", Revision: snap.R(11)}, 103 }, 104 Current: snap.R(11), 105 Active: true, 106 }) 107 108 t := s.state.NewTask("set-auto-aliases", "test") 109 t.Set("snap-setup", &snapstate.SnapSetup{ 110 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 111 }) 112 chg := s.state.NewChange("dummy", "...") 113 chg.AddTask(t) 114 115 s.state.Unlock() 116 117 s.se.Ensure() 118 s.se.Wait() 119 120 s.state.Lock() 121 122 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 123 124 var snapst snapstate.SnapState 125 err := snapstate.Get(s.state, "alias-snap", &snapst) 126 c.Assert(err, IsNil) 127 128 c.Check(snapst.AutoAliasesDisabled, Equals, false) 129 c.Check(snapst.AliasesPending, Equals, true) 130 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 131 "alias1": {Auto: "cmd1"}, 132 "alias2": {Auto: "cmd2"}, 133 "alias4": {Auto: "cmd4"}, 134 }) 135 } 136 137 func (s *snapmgrTestSuite) TestDoUndoSetAutoAliases(c *C) { 138 s.state.Lock() 139 defer s.state.Unlock() 140 141 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 142 c.Check(info.InstanceName(), Equals, "alias-snap") 143 return map[string]string{ 144 "alias1": "cmd1", 145 "alias2": "cmd2", 146 "alias4": "cmd4", 147 }, nil 148 } 149 150 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 151 Sequence: []*snap.SideInfo{ 152 {RealName: "alias-snap", Revision: snap.R(11)}, 153 }, 154 Current: snap.R(11), 155 Active: true, 156 AliasesPending: true, 157 Aliases: map[string]*snapstate.AliasTarget{ 158 "alias1": {Auto: "cmd1"}, 159 "alias2": {Auto: "cmd2x"}, 160 "alias3": {Auto: "cmd3"}, 161 }, 162 }) 163 164 t := s.state.NewTask("set-auto-aliases", "test") 165 t.Set("snap-setup", &snapstate.SnapSetup{ 166 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 167 }) 168 chg := s.state.NewChange("dummy", "...") 169 chg.AddTask(t) 170 171 terr := s.state.NewTask("error-trigger", "provoking total undo") 172 terr.WaitFor(t) 173 chg.AddTask(terr) 174 175 s.state.Unlock() 176 177 for i := 0; i < 3; i++ { 178 s.se.Ensure() 179 s.se.Wait() 180 } 181 182 s.state.Lock() 183 184 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 185 186 var snapst snapstate.SnapState 187 err := snapstate.Get(s.state, "alias-snap", &snapst) 188 c.Assert(err, IsNil) 189 190 c.Check(snapst.AliasesPending, Equals, true) 191 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 192 "alias1": {Auto: "cmd1"}, 193 "alias2": {Auto: "cmd2x"}, 194 "alias3": {Auto: "cmd3"}, 195 }) 196 } 197 198 func (s *snapmgrTestSuite) TestDoSetAutoAliasesConflict(c *C) { 199 s.state.Lock() 200 defer s.state.Unlock() 201 202 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 203 c.Check(info.InstanceName(), Equals, "alias-snap") 204 return map[string]string{ 205 "alias1": "cmd1", 206 "alias2": "cmd2", 207 "alias4": "cmd4", 208 }, nil 209 } 210 211 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 212 Sequence: []*snap.SideInfo{ 213 {RealName: "alias-snap", Revision: snap.R(11)}, 214 }, 215 Current: snap.R(11), 216 Active: true, 217 AliasesPending: true, 218 Aliases: map[string]*snapstate.AliasTarget{ 219 "alias1": {Auto: "cmd1"}, 220 "alias2": {Auto: "cmd2x"}, 221 "alias3": {Auto: "cmd3"}, 222 }, 223 }) 224 snapstate.Set(s.state, "other-snap", &snapstate.SnapState{ 225 Sequence: []*snap.SideInfo{ 226 {RealName: "other-snap", Revision: snap.R(3)}, 227 }, 228 Current: snap.R(3), 229 Active: true, 230 AliasesPending: true, 231 Aliases: map[string]*snapstate.AliasTarget{ 232 "alias4": {Auto: "cmd4"}, 233 }, 234 }) 235 236 t := s.state.NewTask("set-auto-aliases", "test") 237 t.Set("snap-setup", &snapstate.SnapSetup{ 238 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 239 }) 240 chg := s.state.NewChange("dummy", "...") 241 chg.AddTask(t) 242 243 s.state.Unlock() 244 245 s.se.Ensure() 246 s.se.Wait() 247 248 s.state.Lock() 249 250 c.Check(t.Status(), Equals, state.ErrorStatus, Commentf("%v", chg.Err())) 251 c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias4" for "alias-snap", already enabled for "other-snap".*`) 252 } 253 254 func (s *snapmgrTestSuite) TestDoUndoSetAutoAliasesConflict(c *C) { 255 s.state.Lock() 256 defer s.state.Unlock() 257 258 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 259 c.Check(info.InstanceName(), Equals, "alias-snap") 260 return map[string]string{ 261 "alias1": "cmd1", 262 "alias2": "cmd2", 263 "alias4": "cmd4", 264 }, nil 265 } 266 267 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 268 Sequence: []*snap.SideInfo{ 269 {RealName: "alias-snap", Revision: snap.R(11)}, 270 }, 271 Current: snap.R(11), 272 Active: true, 273 AliasesPending: true, 274 Aliases: map[string]*snapstate.AliasTarget{ 275 "alias1": {Auto: "cmd1"}, 276 "alias2": {Auto: "cmd2x"}, 277 "alias3": {Auto: "cmd3"}, 278 }, 279 }) 280 281 otherSnapState := &snapstate.SnapState{ 282 Sequence: []*snap.SideInfo{ 283 {RealName: "other-snap", Revision: snap.R(3)}, 284 }, 285 Current: snap.R(3), 286 Active: true, 287 AutoAliasesDisabled: false, 288 Aliases: map[string]*snapstate.AliasTarget{ 289 "alias5": {Auto: "cmd5"}, 290 }, 291 } 292 snapstate.Set(s.state, "other-snap", otherSnapState) 293 294 grabAlias3 := func(t *state.Task, _ *tomb.Tomb) error { 295 st := t.State() 296 st.Lock() 297 defer st.Unlock() 298 299 otherSnapState.Aliases = map[string]*snapstate.AliasTarget{ 300 "alias3": {Auto: "cmd3"}, 301 "alias5": {Auto: "cmd5"}, 302 } 303 snapstate.Set(s.state, "other-snap", otherSnapState) 304 305 return nil 306 } 307 308 s.o.TaskRunner().AddHandler("grab-alias3", grabAlias3, nil) 309 310 t := s.state.NewTask("set-auto-aliases", "test") 311 t.Set("snap-setup", &snapstate.SnapSetup{ 312 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 313 }) 314 chg := s.state.NewChange("dummy", "...") 315 chg.AddTask(t) 316 317 tgrab3 := s.state.NewTask("grab-alias3", "grab alias3 for other-snap") 318 tgrab3.WaitFor(t) 319 chg.AddTask(tgrab3) 320 321 terr := s.state.NewTask("error-trigger", "provoking total undo") 322 terr.WaitFor(t) 323 chg.AddTask(terr) 324 325 s.state.Unlock() 326 327 for i := 0; i < 5; i++ { 328 s.se.Ensure() 329 s.se.Wait() 330 } 331 332 s.state.Lock() 333 334 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 335 336 var snapst snapstate.SnapState 337 err := snapstate.Get(s.state, "alias-snap", &snapst) 338 c.Assert(err, IsNil) 339 340 c.Check(snapst.AutoAliasesDisabled, Equals, true) 341 c.Check(snapst.AliasesPending, Equals, true) 342 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 343 "alias1": {Auto: "cmd1"}, 344 "alias2": {Auto: "cmd2x"}, 345 "alias3": {Auto: "cmd3"}, 346 }) 347 348 c.Check(t.Log(), HasLen, 1) 349 c.Check(t.Log()[0], Matches, `.* ERROR cannot reinstate alias state because of conflicts, disabling: cannot enable alias "alias3" for "alias-snap", already enabled for "other-snap".*`) 350 } 351 352 func (s *snapmgrTestSuite) TestDoSetAutoAliasesFirstInstallUnaliased(c *C) { 353 s.state.Lock() 354 defer s.state.Unlock() 355 356 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 357 c.Check(info.InstanceName(), Equals, "alias-snap") 358 return map[string]string{ 359 "alias1": "cmd1", 360 "alias2": "cmd2", 361 "alias4": "cmd4", 362 }, nil 363 } 364 365 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 366 Sequence: []*snap.SideInfo{ 367 {RealName: "alias-snap", Revision: snap.R(11)}, 368 }, 369 Current: snap.R(11), 370 Active: true, 371 }) 372 373 t := s.state.NewTask("set-auto-aliases", "test") 374 t.Set("snap-setup", &snapstate.SnapSetup{ 375 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 376 Flags: snapstate.Flags{Unaliased: true}, 377 }) 378 chg := s.state.NewChange("dummy", "...") 379 chg.AddTask(t) 380 381 s.state.Unlock() 382 383 s.se.Ensure() 384 s.se.Wait() 385 386 s.state.Lock() 387 388 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 389 390 var snapst snapstate.SnapState 391 err := snapstate.Get(s.state, "alias-snap", &snapst) 392 c.Assert(err, IsNil) 393 394 c.Check(snapst.AutoAliasesDisabled, Equals, true) 395 c.Check(snapst.AliasesPending, Equals, true) 396 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 397 "alias1": {Auto: "cmd1"}, 398 "alias2": {Auto: "cmd2"}, 399 "alias4": {Auto: "cmd4"}, 400 }) 401 } 402 403 func (s *snapmgrTestSuite) TestDoUndoSetAutoAliasesFirstInstallUnaliased(c *C) { 404 s.state.Lock() 405 defer s.state.Unlock() 406 407 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 408 c.Check(info.InstanceName(), Equals, "alias-snap") 409 return map[string]string{ 410 "alias1": "cmd1", 411 "alias2": "cmd2", 412 "alias4": "cmd4", 413 }, nil 414 } 415 416 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 417 Sequence: []*snap.SideInfo{ 418 {RealName: "alias-snap", Revision: snap.R(11)}, 419 }, 420 Current: snap.R(11), 421 Active: true, 422 }) 423 424 t := s.state.NewTask("set-auto-aliases", "test") 425 t.Set("snap-setup", &snapstate.SnapSetup{ 426 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 427 Flags: snapstate.Flags{Unaliased: true}, 428 }) 429 chg := s.state.NewChange("dummy", "...") 430 chg.AddTask(t) 431 432 terr := s.state.NewTask("error-trigger", "provoking total undo") 433 terr.WaitFor(t) 434 chg.AddTask(terr) 435 436 s.state.Unlock() 437 438 for i := 0; i < 3; i++ { 439 s.se.Ensure() 440 s.se.Wait() 441 } 442 443 s.state.Lock() 444 445 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 446 447 var snapst snapstate.SnapState 448 err := snapstate.Get(s.state, "alias-snap", &snapst) 449 c.Assert(err, IsNil) 450 451 c.Check(snapst.AutoAliasesDisabled, Equals, false) 452 c.Check(snapst.AliasesPending, Equals, true) 453 c.Check(snapst.Aliases, HasLen, 0) 454 } 455 456 func (s *snapmgrTestSuite) TestDoSetupAliases(c *C) { 457 s.state.Lock() 458 defer s.state.Unlock() 459 460 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 461 Sequence: []*snap.SideInfo{ 462 {RealName: "alias-snap", Revision: snap.R(11)}, 463 }, 464 Current: snap.R(11), 465 Active: true, 466 AutoAliasesDisabled: true, 467 AliasesPending: true, 468 Aliases: map[string]*snapstate.AliasTarget{ 469 "manual1": {Manual: "cmd1"}, 470 }, 471 }) 472 473 t := s.state.NewTask("setup-aliases", "test") 474 t.Set("snap-setup", &snapstate.SnapSetup{ 475 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 476 }) 477 chg := s.state.NewChange("dummy", "...") 478 chg.AddTask(t) 479 480 s.state.Unlock() 481 482 s.se.Ensure() 483 s.se.Wait() 484 485 s.state.Lock() 486 487 c.Check(t.Status(), Equals, state.DoneStatus) 488 expected := fakeOps{ 489 { 490 op: "update-aliases", 491 aliases: []*backend.Alias{{Name: "manual1", Target: "alias-snap.cmd1"}}, 492 }, 493 } 494 // start with an easier-to-read error if this fails: 495 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 496 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 497 498 var snapst snapstate.SnapState 499 err := snapstate.Get(s.state, "alias-snap", &snapst) 500 c.Assert(err, IsNil) 501 502 c.Check(snapst.AutoAliasesDisabled, Equals, true) 503 c.Check(snapst.AliasesPending, Equals, false) 504 } 505 506 func (s *snapmgrTestSuite) TestDoUndoSetupAliases(c *C) { 507 s.state.Lock() 508 defer s.state.Unlock() 509 510 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 511 Sequence: []*snap.SideInfo{ 512 {RealName: "alias-snap", Revision: snap.R(11)}, 513 }, 514 Current: snap.R(11), 515 Active: true, 516 AutoAliasesDisabled: true, 517 AliasesPending: true, 518 Aliases: map[string]*snapstate.AliasTarget{ 519 "manual1": {Manual: "cmd1"}, 520 }, 521 }) 522 523 t := s.state.NewTask("setup-aliases", "test") 524 t.Set("snap-setup", &snapstate.SnapSetup{ 525 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 526 }) 527 chg := s.state.NewChange("dummy", "...") 528 chg.AddTask(t) 529 530 terr := s.state.NewTask("error-trigger", "provoking total undo") 531 terr.WaitFor(t) 532 chg.AddTask(terr) 533 534 s.state.Unlock() 535 536 for i := 0; i < 3; i++ { 537 s.se.Ensure() 538 s.se.Wait() 539 } 540 541 s.state.Lock() 542 543 c.Check(t.Status(), Equals, state.UndoneStatus) 544 expected := fakeOps{ 545 { 546 op: "update-aliases", 547 aliases: []*backend.Alias{{Name: "manual1", Target: "alias-snap.cmd1"}}, 548 }, 549 { 550 op: "remove-snap-aliases", 551 name: "alias-snap", 552 }, 553 } 554 // start with an easier-to-read error if this fails: 555 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 556 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 557 558 var snapst snapstate.SnapState 559 err := snapstate.Get(s.state, "alias-snap", &snapst) 560 c.Assert(err, IsNil) 561 562 c.Check(snapst.AutoAliasesDisabled, Equals, true) 563 c.Check(snapst.AliasesPending, Equals, true) 564 } 565 566 func (s *snapmgrTestSuite) TestDoSetupAliasesAuto(c *C) { 567 s.state.Lock() 568 defer s.state.Unlock() 569 570 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 571 Sequence: []*snap.SideInfo{ 572 {RealName: "alias-snap", Revision: snap.R(11)}, 573 }, 574 Current: snap.R(11), 575 Active: true, 576 AutoAliasesDisabled: false, 577 AliasesPending: true, 578 Aliases: map[string]*snapstate.AliasTarget{ 579 "alias1": {Auto: "cmd1"}, 580 }, 581 }) 582 583 t := s.state.NewTask("setup-aliases", "test") 584 t.Set("snap-setup", &snapstate.SnapSetup{ 585 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 586 }) 587 chg := s.state.NewChange("dummy", "...") 588 chg.AddTask(t) 589 590 s.state.Unlock() 591 592 s.se.Ensure() 593 s.se.Wait() 594 595 s.state.Lock() 596 597 c.Check(t.Status(), Equals, state.DoneStatus) 598 expected := fakeOps{ 599 { 600 op: "update-aliases", 601 aliases: []*backend.Alias{{Name: "alias1", Target: "alias-snap.cmd1"}}, 602 }, 603 } 604 // start with an easier-to-read error if this fails: 605 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 606 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 607 608 var snapst snapstate.SnapState 609 err := snapstate.Get(s.state, "alias-snap", &snapst) 610 c.Assert(err, IsNil) 611 612 c.Check(snapst.AutoAliasesDisabled, Equals, false) 613 c.Check(snapst.AliasesPending, Equals, false) 614 } 615 616 func (s *snapmgrTestSuite) TestDoUndoSetupAliasesAuto(c *C) { 617 s.state.Lock() 618 defer s.state.Unlock() 619 620 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 621 Sequence: []*snap.SideInfo{ 622 {RealName: "alias-snap", Revision: snap.R(11)}, 623 }, 624 Current: snap.R(11), 625 Active: true, 626 AutoAliasesDisabled: false, 627 AliasesPending: true, 628 Aliases: map[string]*snapstate.AliasTarget{ 629 "alias1": {Auto: "cmd1"}, 630 }, 631 }) 632 633 t := s.state.NewTask("setup-aliases", "test") 634 t.Set("snap-setup", &snapstate.SnapSetup{ 635 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 636 }) 637 chg := s.state.NewChange("dummy", "...") 638 chg.AddTask(t) 639 640 terr := s.state.NewTask("error-trigger", "provoking total undo") 641 terr.WaitFor(t) 642 chg.AddTask(terr) 643 644 s.state.Unlock() 645 646 for i := 0; i < 3; i++ { 647 s.se.Ensure() 648 s.se.Wait() 649 } 650 651 s.state.Lock() 652 653 c.Check(t.Status(), Equals, state.UndoneStatus) 654 expected := fakeOps{ 655 { 656 op: "update-aliases", 657 aliases: []*backend.Alias{{Name: "alias1", Target: "alias-snap.cmd1"}}, 658 }, 659 { 660 op: "remove-snap-aliases", 661 name: "alias-snap", 662 }, 663 } 664 // start with an easier-to-read error if this fails: 665 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 666 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 667 668 var snapst snapstate.SnapState 669 err := snapstate.Get(s.state, "alias-snap", &snapst) 670 c.Assert(err, IsNil) 671 672 c.Check(snapst.AutoAliasesDisabled, Equals, false) 673 c.Check(snapst.AliasesPending, Equals, true) 674 } 675 676 func (s *snapmgrTestSuite) TestDoSetupAliasesNothing(c *C) { 677 s.state.Lock() 678 defer s.state.Unlock() 679 680 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 681 Sequence: []*snap.SideInfo{ 682 {RealName: "alias-snap", Revision: snap.R(11)}, 683 }, 684 Current: snap.R(11), 685 Active: true, 686 }) 687 688 t := s.state.NewTask("setup-aliases", "test") 689 t.Set("snap-setup", &snapstate.SnapSetup{ 690 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 691 }) 692 chg := s.state.NewChange("dummy", "...") 693 chg.AddTask(t) 694 695 s.state.Unlock() 696 697 for i := 0; i < 3; i++ { 698 s.se.Ensure() 699 s.se.Wait() 700 } 701 702 s.state.Lock() 703 704 c.Check(t.Status(), Equals, state.DoneStatus) 705 expected := fakeOps{ 706 { 707 op: "update-aliases", 708 }, 709 } 710 // start with an easier-to-read error if this fails: 711 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 712 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 713 714 var snapst snapstate.SnapState 715 err := snapstate.Get(s.state, "alias-snap", &snapst) 716 c.Assert(err, IsNil) 717 718 c.Check(snapst.AutoAliasesDisabled, Equals, false) 719 c.Check(snapst.AliasesPending, Equals, false) 720 } 721 722 func (s *snapmgrTestSuite) TestDoUndoSetupAliasesNothing(c *C) { 723 s.state.Lock() 724 defer s.state.Unlock() 725 726 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 727 Sequence: []*snap.SideInfo{ 728 {RealName: "alias-snap", Revision: snap.R(11)}, 729 }, 730 Current: snap.R(11), 731 Active: true, 732 }) 733 734 t := s.state.NewTask("setup-aliases", "test") 735 t.Set("snap-setup", &snapstate.SnapSetup{ 736 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 737 }) 738 chg := s.state.NewChange("dummy", "...") 739 chg.AddTask(t) 740 741 terr := s.state.NewTask("error-trigger", "provoking total undo") 742 terr.WaitFor(t) 743 chg.AddTask(terr) 744 745 s.state.Unlock() 746 747 for i := 0; i < 3; i++ { 748 s.se.Ensure() 749 s.se.Wait() 750 } 751 752 s.state.Lock() 753 754 c.Check(t.Status(), Equals, state.UndoneStatus) 755 expected := fakeOps{ 756 { 757 op: "update-aliases", 758 }, 759 { 760 op: "remove-snap-aliases", 761 name: "alias-snap", 762 }, 763 } 764 // start with an easier-to-read error if this fails: 765 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 766 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 767 768 var snapst snapstate.SnapState 769 err := snapstate.Get(s.state, "alias-snap", &snapst) 770 c.Assert(err, IsNil) 771 772 c.Check(snapst.AutoAliasesDisabled, Equals, false) 773 c.Check(snapst.AliasesPending, Equals, true) 774 } 775 776 func (s *snapmgrTestSuite) TestDoPruneAutoAliasesAuto(c *C) { 777 s.state.Lock() 778 defer s.state.Unlock() 779 780 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 781 Sequence: []*snap.SideInfo{ 782 {RealName: "alias-snap", Revision: snap.R(11)}, 783 }, 784 Current: snap.R(11), 785 Active: true, 786 AliasesPending: false, 787 Aliases: map[string]*snapstate.AliasTarget{ 788 "alias1": {Auto: "cmd1"}, 789 "alias2": {Auto: "cmd2"}, 790 "alias3": {Auto: "cmd3"}, 791 }, 792 }) 793 794 t := s.state.NewTask("prune-auto-aliases", "test") 795 t.Set("snap-setup", &snapstate.SnapSetup{ 796 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 797 }) 798 t.Set("aliases", []string{"alias2", "alias3"}) 799 chg := s.state.NewChange("dummy", "...") 800 chg.AddTask(t) 801 802 s.state.Unlock() 803 804 s.se.Ensure() 805 s.se.Wait() 806 807 s.state.Lock() 808 809 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 810 811 expected := fakeOps{ 812 { 813 op: "update-aliases", 814 rmAliases: []*backend.Alias{ 815 {Name: "alias2", Target: "alias-snap.cmd2"}, 816 {Name: "alias3", Target: "alias-snap.cmd3"}, 817 }, 818 }, 819 } 820 // start with an easier-to-read error if this fails: 821 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 822 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 823 824 var snapst snapstate.SnapState 825 err := snapstate.Get(s.state, "alias-snap", &snapst) 826 c.Assert(err, IsNil) 827 828 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 829 "alias1": {Auto: "cmd1"}, 830 }) 831 } 832 833 func (s *snapmgrTestSuite) TestDoPruneAutoAliasesAutoPending(c *C) { 834 s.state.Lock() 835 defer s.state.Unlock() 836 837 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 838 Sequence: []*snap.SideInfo{ 839 {RealName: "alias-snap", Revision: snap.R(11)}, 840 }, 841 Current: snap.R(11), 842 Active: true, 843 AliasesPending: true, 844 Aliases: map[string]*snapstate.AliasTarget{ 845 "alias1": {Auto: "cmd1"}, 846 "alias2": {Auto: "cmd2"}, 847 "alias3": {Auto: "cmd3"}, 848 }, 849 }) 850 851 t := s.state.NewTask("prune-auto-aliases", "test") 852 t.Set("snap-setup", &snapstate.SnapSetup{ 853 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 854 }) 855 t.Set("aliases", []string{"alias2", "alias3"}) 856 chg := s.state.NewChange("dummy", "...") 857 chg.AddTask(t) 858 859 s.state.Unlock() 860 861 s.se.Ensure() 862 s.se.Wait() 863 864 s.state.Lock() 865 866 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 867 868 // pending: nothing to do on disk 869 c.Assert(s.fakeBackend.ops, HasLen, 0) 870 871 var snapst snapstate.SnapState 872 err := snapstate.Get(s.state, "alias-snap", &snapst) 873 c.Assert(err, IsNil) 874 875 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 876 "alias1": {Auto: "cmd1"}, 877 }) 878 } 879 880 func (s *snapmgrTestSuite) TestDoPruneAutoAliasesManualAndDisabled(c *C) { 881 s.state.Lock() 882 defer s.state.Unlock() 883 884 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 885 Sequence: []*snap.SideInfo{ 886 {RealName: "alias-snap", Revision: snap.R(11)}, 887 }, 888 Current: snap.R(11), 889 Active: true, 890 AutoAliasesDisabled: true, 891 AliasesPending: false, 892 Aliases: map[string]*snapstate.AliasTarget{ 893 "alias1": {Auto: "cmd1"}, 894 "alias2": {Auto: "cmd2"}, 895 "alias3": {Manual: "cmdx", Auto: "cmd3"}, 896 "alias4": {Manual: "cmd4"}, 897 }, 898 }) 899 900 t := s.state.NewTask("prune-auto-aliases", "test") 901 t.Set("snap-setup", &snapstate.SnapSetup{ 902 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 903 }) 904 t.Set("aliases", []string{"alias2", "alias3", "alias4"}) 905 chg := s.state.NewChange("dummy", "...") 906 chg.AddTask(t) 907 908 s.state.Unlock() 909 910 s.se.Ensure() 911 s.se.Wait() 912 913 s.state.Lock() 914 915 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 916 917 expected := fakeOps{ 918 { 919 op: "update-aliases", 920 }, 921 } 922 // start with an easier-to-read error if this fails: 923 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 924 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 925 926 var snapst snapstate.SnapState 927 err := snapstate.Get(s.state, "alias-snap", &snapst) 928 c.Assert(err, IsNil) 929 930 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 931 "alias1": {Auto: "cmd1"}, 932 "alias3": {Manual: "cmdx"}, 933 "alias4": {Manual: "cmd4"}, 934 }) 935 } 936 937 func (s *snapmgrTestSuite) TestDoRefreshAliases(c *C) { 938 s.state.Lock() 939 defer s.state.Unlock() 940 941 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 942 c.Check(info.InstanceName(), Equals, "alias-snap") 943 return map[string]string{ 944 "alias1": "cmd1", 945 "alias2": "cmd2", 946 "alias4": "cmd4", 947 }, nil 948 } 949 950 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 951 Sequence: []*snap.SideInfo{ 952 {RealName: "alias-snap", Revision: snap.R(11)}, 953 }, 954 Current: snap.R(11), 955 Active: true, 956 AliasesPending: false, 957 Aliases: map[string]*snapstate.AliasTarget{ 958 "alias1": {Auto: "cmd1"}, 959 "alias2": {Auto: "cmd2x"}, 960 "alias3": {Auto: "cmd3"}, 961 }, 962 }) 963 964 t := s.state.NewTask("refresh-aliases", "test") 965 t.Set("snap-setup", &snapstate.SnapSetup{ 966 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 967 }) 968 chg := s.state.NewChange("dummy", "...") 969 chg.AddTask(t) 970 971 s.state.Unlock() 972 973 s.se.Ensure() 974 s.se.Wait() 975 976 s.state.Lock() 977 978 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 979 980 expected := fakeOps{ 981 { 982 op: "update-aliases", 983 rmAliases: []*backend.Alias{ 984 {Name: "alias2", Target: "alias-snap.cmd2x"}, 985 {Name: "alias3", Target: "alias-snap.cmd3"}, 986 }, 987 aliases: []*backend.Alias{ 988 {Name: "alias2", Target: "alias-snap.cmd2"}, 989 {Name: "alias4", Target: "alias-snap.cmd4"}, 990 }, 991 }, 992 } 993 // start with an easier-to-read error if this fails: 994 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 995 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 996 997 var snapst snapstate.SnapState 998 err := snapstate.Get(s.state, "alias-snap", &snapst) 999 c.Assert(err, IsNil) 1000 1001 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1002 c.Check(snapst.AliasesPending, Equals, false) 1003 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1004 "alias1": {Auto: "cmd1"}, 1005 "alias2": {Auto: "cmd2"}, 1006 "alias4": {Auto: "cmd4"}, 1007 }) 1008 } 1009 1010 func (s *snapmgrTestSuite) TestDoUndoRefreshAliases(c *C) { 1011 s.state.Lock() 1012 defer s.state.Unlock() 1013 1014 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1015 c.Check(info.InstanceName(), Equals, "alias-snap") 1016 return map[string]string{ 1017 "alias1": "cmd1", 1018 "alias2": "cmd2", 1019 "alias4": "cmd4", 1020 }, nil 1021 } 1022 1023 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1024 Sequence: []*snap.SideInfo{ 1025 {RealName: "alias-snap", Revision: snap.R(11)}, 1026 }, 1027 Current: snap.R(11), 1028 Active: true, 1029 AliasesPending: false, 1030 Aliases: map[string]*snapstate.AliasTarget{ 1031 "alias1": {Auto: "cmd1"}, 1032 "alias2": {Auto: "cmd2x"}, 1033 "alias3": {Auto: "cmd3"}, 1034 }, 1035 }) 1036 1037 t := s.state.NewTask("refresh-aliases", "test") 1038 t.Set("snap-setup", &snapstate.SnapSetup{ 1039 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1040 }) 1041 chg := s.state.NewChange("dummy", "...") 1042 chg.AddTask(t) 1043 1044 terr := s.state.NewTask("error-trigger", "provoking total undo") 1045 terr.WaitFor(t) 1046 chg.AddTask(terr) 1047 1048 s.state.Unlock() 1049 1050 for i := 0; i < 3; i++ { 1051 s.se.Ensure() 1052 s.se.Wait() 1053 } 1054 1055 s.state.Lock() 1056 1057 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1058 1059 expected := fakeOps{ 1060 { 1061 op: "update-aliases", 1062 rmAliases: []*backend.Alias{ 1063 {Name: "alias2", Target: "alias-snap.cmd2x"}, 1064 {Name: "alias3", Target: "alias-snap.cmd3"}, 1065 }, 1066 aliases: []*backend.Alias{ 1067 {Name: "alias2", Target: "alias-snap.cmd2"}, 1068 {Name: "alias4", Target: "alias-snap.cmd4"}, 1069 }, 1070 }, 1071 { 1072 op: "update-aliases", 1073 aliases: []*backend.Alias{ 1074 {Name: "alias2", Target: "alias-snap.cmd2x"}, 1075 {Name: "alias3", Target: "alias-snap.cmd3"}, 1076 }, 1077 rmAliases: []*backend.Alias{ 1078 {Name: "alias2", Target: "alias-snap.cmd2"}, 1079 {Name: "alias4", Target: "alias-snap.cmd4"}, 1080 }, 1081 }, 1082 } 1083 // start with an easier-to-read error if this fails: 1084 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 1085 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 1086 1087 var snapst snapstate.SnapState 1088 err := snapstate.Get(s.state, "alias-snap", &snapst) 1089 c.Assert(err, IsNil) 1090 1091 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1092 c.Check(snapst.AliasesPending, Equals, false) 1093 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1094 "alias1": {Auto: "cmd1"}, 1095 "alias2": {Auto: "cmd2x"}, 1096 "alias3": {Auto: "cmd3"}, 1097 }) 1098 } 1099 1100 func (s *snapmgrTestSuite) TestDoUndoRefreshAliasesFromEmpty(c *C) { 1101 s.state.Lock() 1102 defer s.state.Unlock() 1103 1104 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1105 c.Check(info.InstanceName(), Equals, "alias-snap") 1106 return map[string]string{ 1107 "alias1": "cmd1", 1108 "alias2": "cmd2", 1109 "alias4": "cmd4", 1110 }, nil 1111 } 1112 1113 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1114 Sequence: []*snap.SideInfo{ 1115 {RealName: "alias-snap", Revision: snap.R(11)}, 1116 }, 1117 Current: snap.R(11), 1118 Active: true, 1119 AliasesPending: false, 1120 }) 1121 1122 t := s.state.NewTask("refresh-aliases", "test") 1123 t.Set("snap-setup", &snapstate.SnapSetup{ 1124 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1125 }) 1126 chg := s.state.NewChange("dummy", "...") 1127 chg.AddTask(t) 1128 1129 terr := s.state.NewTask("error-trigger", "provoking total undo") 1130 terr.WaitFor(t) 1131 chg.AddTask(terr) 1132 1133 s.state.Unlock() 1134 1135 for i := 0; i < 3; i++ { 1136 s.se.Ensure() 1137 s.se.Wait() 1138 } 1139 1140 s.state.Lock() 1141 1142 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1143 1144 expected := fakeOps{ 1145 { 1146 op: "update-aliases", 1147 aliases: []*backend.Alias{ 1148 {Name: "alias1", Target: "alias-snap.cmd1"}, 1149 {Name: "alias2", Target: "alias-snap.cmd2"}, 1150 {Name: "alias4", Target: "alias-snap.cmd4"}, 1151 }, 1152 }, 1153 { 1154 op: "update-aliases", 1155 rmAliases: []*backend.Alias{ 1156 {Name: "alias1", Target: "alias-snap.cmd1"}, 1157 {Name: "alias2", Target: "alias-snap.cmd2"}, 1158 {Name: "alias4", Target: "alias-snap.cmd4"}, 1159 }, 1160 }, 1161 } 1162 // start with an easier-to-read error if this fails: 1163 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 1164 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 1165 1166 var snapst snapstate.SnapState 1167 err := snapstate.Get(s.state, "alias-snap", &snapst) 1168 c.Assert(err, IsNil) 1169 1170 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1171 c.Check(snapst.AliasesPending, Equals, false) 1172 c.Check(snapst.Aliases, HasLen, 0) 1173 } 1174 1175 func (s *snapmgrTestSuite) TestDoRefreshAliasesPending(c *C) { 1176 s.state.Lock() 1177 defer s.state.Unlock() 1178 1179 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1180 c.Check(info.InstanceName(), Equals, "alias-snap") 1181 return map[string]string{ 1182 "alias1": "cmd1", 1183 "alias2": "cmd2", 1184 "alias4": "cmd4", 1185 }, nil 1186 } 1187 1188 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1189 Sequence: []*snap.SideInfo{ 1190 {RealName: "alias-snap", Revision: snap.R(11)}, 1191 }, 1192 Current: snap.R(11), 1193 Active: true, 1194 AliasesPending: true, 1195 Aliases: map[string]*snapstate.AliasTarget{ 1196 "alias1": {Auto: "cmd1"}, 1197 "alias2": {Auto: "cmd2x"}, 1198 "alias3": {Auto: "cmd3"}, 1199 }, 1200 }) 1201 1202 t := s.state.NewTask("refresh-aliases", "test") 1203 t.Set("snap-setup", &snapstate.SnapSetup{ 1204 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1205 }) 1206 chg := s.state.NewChange("dummy", "...") 1207 chg.AddTask(t) 1208 1209 s.state.Unlock() 1210 1211 s.se.Ensure() 1212 s.se.Wait() 1213 1214 s.state.Lock() 1215 1216 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 1217 1218 // pending: nothing to do on disk 1219 c.Assert(s.fakeBackend.ops, HasLen, 0) 1220 1221 var snapst snapstate.SnapState 1222 err := snapstate.Get(s.state, "alias-snap", &snapst) 1223 c.Assert(err, IsNil) 1224 1225 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1226 c.Check(snapst.AliasesPending, Equals, true) 1227 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1228 "alias1": {Auto: "cmd1"}, 1229 "alias2": {Auto: "cmd2"}, 1230 "alias4": {Auto: "cmd4"}, 1231 }) 1232 } 1233 1234 func (s *snapmgrTestSuite) TestDoUndoRefreshAliasesPending(c *C) { 1235 s.state.Lock() 1236 defer s.state.Unlock() 1237 1238 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1239 c.Check(info.InstanceName(), Equals, "alias-snap") 1240 return map[string]string{ 1241 "alias1": "cmd1", 1242 "alias2": "cmd2", 1243 "alias4": "cmd4", 1244 }, nil 1245 } 1246 1247 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1248 Sequence: []*snap.SideInfo{ 1249 {RealName: "alias-snap", Revision: snap.R(11)}, 1250 }, 1251 Current: snap.R(11), 1252 Active: true, 1253 AliasesPending: true, 1254 Aliases: map[string]*snapstate.AliasTarget{ 1255 "alias1": {Auto: "cmd1"}, 1256 "alias2": {Auto: "cmd2x"}, 1257 "alias3": {Auto: "cmd3"}, 1258 }, 1259 }) 1260 1261 t := s.state.NewTask("refresh-aliases", "test") 1262 t.Set("snap-setup", &snapstate.SnapSetup{ 1263 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1264 }) 1265 chg := s.state.NewChange("dummy", "...") 1266 chg.AddTask(t) 1267 1268 terr := s.state.NewTask("error-trigger", "provoking total undo") 1269 terr.WaitFor(t) 1270 chg.AddTask(terr) 1271 1272 s.state.Unlock() 1273 1274 for i := 0; i < 3; i++ { 1275 s.se.Ensure() 1276 s.se.Wait() 1277 } 1278 1279 s.state.Lock() 1280 1281 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1282 1283 // pending: nothing to do on disk 1284 c.Assert(s.fakeBackend.ops, HasLen, 0) 1285 1286 var snapst snapstate.SnapState 1287 err := snapstate.Get(s.state, "alias-snap", &snapst) 1288 c.Assert(err, IsNil) 1289 1290 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1291 c.Check(snapst.AliasesPending, Equals, true) 1292 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1293 "alias1": {Auto: "cmd1"}, 1294 "alias2": {Auto: "cmd2x"}, 1295 "alias3": {Auto: "cmd3"}, 1296 }) 1297 } 1298 1299 func (s *snapmgrTestSuite) TestDoRefreshAliasesConflict(c *C) { 1300 s.state.Lock() 1301 defer s.state.Unlock() 1302 1303 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1304 c.Check(info.InstanceName(), Equals, "alias-snap") 1305 return map[string]string{ 1306 "alias1": "cmd1", 1307 "alias2": "cmd2", 1308 "alias4": "cmd4", 1309 }, nil 1310 } 1311 1312 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1313 Sequence: []*snap.SideInfo{ 1314 {RealName: "alias-snap", Revision: snap.R(11)}, 1315 }, 1316 Current: snap.R(11), 1317 Active: true, 1318 Aliases: map[string]*snapstate.AliasTarget{ 1319 "alias1": {Auto: "cmd1"}, 1320 "alias2": {Auto: "cmd2x"}, 1321 "alias3": {Auto: "cmd3"}, 1322 }, 1323 }) 1324 snapstate.Set(s.state, "other-snap", &snapstate.SnapState{ 1325 Sequence: []*snap.SideInfo{ 1326 {RealName: "other-snap", Revision: snap.R(3)}, 1327 }, 1328 Current: snap.R(3), 1329 Active: true, 1330 Aliases: map[string]*snapstate.AliasTarget{ 1331 "alias4": {Auto: "cmd4"}, 1332 }, 1333 }) 1334 1335 t := s.state.NewTask("refresh-aliases", "test") 1336 t.Set("snap-setup", &snapstate.SnapSetup{ 1337 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1338 }) 1339 chg := s.state.NewChange("dummy", "...") 1340 chg.AddTask(t) 1341 1342 s.state.Unlock() 1343 1344 s.se.Ensure() 1345 s.se.Wait() 1346 1347 s.state.Lock() 1348 1349 c.Check(t.Status(), Equals, state.ErrorStatus, Commentf("%v", chg.Err())) 1350 c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias4" for "alias-snap", already enabled for "other-snap".*`) 1351 } 1352 1353 func (s *snapmgrTestSuite) TestDoUndoRefreshAliasesConflict(c *C) { 1354 s.state.Lock() 1355 defer s.state.Unlock() 1356 1357 snapstate.AutoAliases = func(st *state.State, info *snap.Info) (map[string]string, error) { 1358 c.Check(info.InstanceName(), Equals, "alias-snap") 1359 return map[string]string{ 1360 "alias1": "cmd1", 1361 "alias2": "cmd2", 1362 "alias4": "cmd4", 1363 }, nil 1364 } 1365 1366 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1367 Sequence: []*snap.SideInfo{ 1368 {RealName: "alias-snap", Revision: snap.R(11)}, 1369 }, 1370 Current: snap.R(11), 1371 Active: true, 1372 AliasesPending: false, 1373 Aliases: map[string]*snapstate.AliasTarget{ 1374 "alias1": {Auto: "cmd1"}, 1375 "alias2": {Auto: "cmd2x"}, 1376 "alias3": {Auto: "cmd3"}, 1377 }, 1378 }) 1379 1380 grabAlias3 := func(t *state.Task, _ *tomb.Tomb) error { 1381 st := t.State() 1382 st.Lock() 1383 defer st.Unlock() 1384 1385 snapstate.Set(s.state, "other-snap", &snapstate.SnapState{ 1386 Sequence: []*snap.SideInfo{ 1387 {RealName: "other-snap", Revision: snap.R(3)}, 1388 }, 1389 Current: snap.R(3), 1390 Active: true, 1391 AliasesPending: false, 1392 Aliases: map[string]*snapstate.AliasTarget{ 1393 "alias3": {Auto: "cmd3x"}, 1394 }, 1395 }) 1396 1397 return nil 1398 } 1399 1400 s.o.TaskRunner().AddHandler("grab-alias3", grabAlias3, nil) 1401 1402 t := s.state.NewTask("refresh-aliases", "test") 1403 t.Set("snap-setup", &snapstate.SnapSetup{ 1404 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1405 }) 1406 chg := s.state.NewChange("dummy", "...") 1407 chg.AddTask(t) 1408 1409 tgrab3 := s.state.NewTask("grab-alias3", "grab alias3 for other-snap") 1410 tgrab3.WaitFor(t) 1411 chg.AddTask(tgrab3) 1412 1413 terr := s.state.NewTask("error-trigger", "provoking total undo") 1414 terr.WaitFor(t) 1415 chg.AddTask(terr) 1416 1417 s.state.Unlock() 1418 1419 for i := 0; i < 5; i++ { 1420 s.se.Ensure() 1421 s.se.Wait() 1422 } 1423 1424 s.state.Lock() 1425 1426 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1427 1428 expected := fakeOps{ 1429 { 1430 op: "update-aliases", 1431 rmAliases: []*backend.Alias{ 1432 {Name: "alias2", Target: "alias-snap.cmd2x"}, 1433 {Name: "alias3", Target: "alias-snap.cmd3"}, 1434 }, 1435 aliases: []*backend.Alias{ 1436 {Name: "alias2", Target: "alias-snap.cmd2"}, 1437 {Name: "alias4", Target: "alias-snap.cmd4"}, 1438 }, 1439 }, 1440 { 1441 op: "update-aliases", 1442 rmAliases: []*backend.Alias{ 1443 {Name: "alias1", Target: "alias-snap.cmd1"}, 1444 {Name: "alias2", Target: "alias-snap.cmd2"}, 1445 {Name: "alias4", Target: "alias-snap.cmd4"}, 1446 }, 1447 }, 1448 } 1449 // start with an easier-to-read error if this fails: 1450 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 1451 c.Check(s.fakeBackend.ops, DeepEquals, expected) 1452 1453 var snapst snapstate.SnapState 1454 err := snapstate.Get(s.state, "alias-snap", &snapst) 1455 c.Assert(err, IsNil) 1456 1457 c.Check(snapst.AutoAliasesDisabled, Equals, true) 1458 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1459 "alias1": {Auto: "cmd1"}, 1460 "alias2": {Auto: "cmd2x"}, 1461 "alias3": {Auto: "cmd3"}, 1462 }) 1463 1464 var snapst2 snapstate.SnapState 1465 err = snapstate.Get(s.state, "other-snap", &snapst2) 1466 c.Assert(err, IsNil) 1467 1468 c.Check(snapst2.AutoAliasesDisabled, Equals, false) 1469 c.Check(snapst2.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1470 "alias3": {Auto: "cmd3x"}, 1471 }) 1472 1473 c.Check(t.Log(), HasLen, 1) 1474 c.Check(t.Log()[0], Matches, `.* ERROR cannot reinstate alias state because of conflicts, disabling: cannot enable alias "alias3" for "alias-snap", already enabled for "other-snap".*`) 1475 } 1476 1477 func (s *snapmgrTestSuite) TestDoUndoDisableAliases(c *C) { 1478 s.state.Lock() 1479 defer s.state.Unlock() 1480 1481 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1482 Sequence: []*snap.SideInfo{ 1483 {RealName: "alias-snap", Revision: snap.R(11)}, 1484 }, 1485 Current: snap.R(11), 1486 Active: true, 1487 Aliases: map[string]*snapstate.AliasTarget{ 1488 "alias1": {Manual: "cmd5", Auto: "cmd1"}, 1489 "alias2": {Auto: "cmd2"}, 1490 "alias3": {Manual: "cmd3"}, 1491 }, 1492 }) 1493 1494 t := s.state.NewTask("disable-aliases", "test") 1495 t.Set("snap-setup", &snapstate.SnapSetup{ 1496 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1497 }) 1498 chg := s.state.NewChange("dummy", "...") 1499 chg.AddTask(t) 1500 1501 terr := s.state.NewTask("error-trigger", "provoking total undo") 1502 terr.WaitFor(t) 1503 chg.AddTask(terr) 1504 1505 s.state.Unlock() 1506 1507 for i := 0; i < 3; i++ { 1508 s.se.Ensure() 1509 s.se.Wait() 1510 } 1511 1512 s.state.Lock() 1513 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1514 1515 expected := fakeOps{ 1516 { 1517 op: "update-aliases", 1518 rmAliases: []*backend.Alias{ 1519 {Name: "alias1", Target: "alias-snap.cmd5"}, 1520 {Name: "alias2", Target: "alias-snap.cmd2"}, 1521 {Name: "alias3", Target: "alias-snap.cmd3"}, 1522 }, 1523 }, 1524 { 1525 op: "update-aliases", 1526 aliases: []*backend.Alias{ 1527 {Name: "alias1", Target: "alias-snap.cmd5"}, 1528 {Name: "alias2", Target: "alias-snap.cmd2"}, 1529 {Name: "alias3", Target: "alias-snap.cmd3"}, 1530 }, 1531 }, 1532 } 1533 // start with an easier-to-read error if this fails: 1534 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) 1535 c.Assert(s.fakeBackend.ops, DeepEquals, expected) 1536 1537 var snapst snapstate.SnapState 1538 err := snapstate.Get(s.state, "alias-snap", &snapst) 1539 c.Assert(err, IsNil) 1540 1541 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1542 c.Check(snapst.AliasesPending, Equals, false) 1543 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1544 "alias1": {Manual: "cmd5", Auto: "cmd1"}, 1545 "alias2": {Auto: "cmd2"}, 1546 "alias3": {Manual: "cmd3"}, 1547 }) 1548 } 1549 1550 func (s *snapmgrTestSuite) TestDoPreferAliases(c *C) { 1551 s.state.Lock() 1552 defer s.state.Unlock() 1553 1554 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1555 Sequence: []*snap.SideInfo{ 1556 {RealName: "alias-snap", Revision: snap.R(11)}, 1557 }, 1558 Current: snap.R(11), 1559 Active: true, 1560 AutoAliasesDisabled: true, 1561 Aliases: map[string]*snapstate.AliasTarget{ 1562 "alias1": {Auto: "cmd1"}, 1563 "alias2": {Auto: "cmd2"}, 1564 "alias3": {Auto: "cmd3"}, 1565 }, 1566 }) 1567 snapstate.Set(s.state, "other-alias-snap1", &snapstate.SnapState{ 1568 Sequence: []*snap.SideInfo{ 1569 {RealName: "other-alias-snap1", Revision: snap.R(3)}, 1570 }, 1571 Current: snap.R(3), 1572 Active: true, 1573 Aliases: map[string]*snapstate.AliasTarget{ 1574 "alias1": {Auto: "cmd1"}, 1575 }, 1576 }) 1577 snapstate.Set(s.state, "other-alias-snap2", &snapstate.SnapState{ 1578 Sequence: []*snap.SideInfo{ 1579 {RealName: "other-alias-snap2", Revision: snap.R(3)}, 1580 }, 1581 Current: snap.R(3), 1582 Active: true, 1583 AliasesPending: true, 1584 Aliases: map[string]*snapstate.AliasTarget{ 1585 "alias2": {Manual: "cmd2"}, 1586 "aliasx": {Manual: "cmdx"}, 1587 }, 1588 }) 1589 snapstate.Set(s.state, "other-alias-snap3", &snapstate.SnapState{ 1590 Sequence: []*snap.SideInfo{ 1591 {RealName: "other-alias-snap3", Revision: snap.R(3)}, 1592 }, 1593 Current: snap.R(3), 1594 Active: true, 1595 Aliases: map[string]*snapstate.AliasTarget{ 1596 "alias3": {Manual: "cmd5", Auto: "cmd3"}, 1597 }, 1598 }) 1599 1600 t := s.state.NewTask("prefer-aliases", "test") 1601 t.Set("snap-setup", &snapstate.SnapSetup{ 1602 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1603 }) 1604 chg := s.state.NewChange("dummy", "...") 1605 chg.AddTask(t) 1606 1607 s.state.Unlock() 1608 for i := 0; i < 3; i++ { 1609 s.se.Ensure() 1610 s.se.Wait() 1611 } 1612 s.state.Lock() 1613 c.Check(t.Status(), Equals, state.DoneStatus, Commentf("%v", chg.Err())) 1614 1615 // start with an easier-to-read error if this fails: 1616 c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, []string{"update-aliases", "update-aliases", "update-aliases"}) 1617 c.Assert(s.fakeBackend.ops[0].aliases, HasLen, 0) 1618 c.Assert(s.fakeBackend.ops[0].rmAliases, HasLen, 1) 1619 c.Assert(s.fakeBackend.ops[1].aliases, HasLen, 0) 1620 c.Assert(s.fakeBackend.ops[1].rmAliases, HasLen, 1) 1621 c.Assert(s.fakeBackend.ops[2], DeepEquals, fakeOp{ 1622 op: "update-aliases", 1623 aliases: []*backend.Alias{ 1624 {Name: "alias1", Target: "alias-snap.cmd1"}, 1625 {Name: "alias2", Target: "alias-snap.cmd2"}, 1626 {Name: "alias3", Target: "alias-snap.cmd3"}, 1627 }, 1628 }) 1629 1630 var snapst snapstate.SnapState 1631 err := snapstate.Get(s.state, "alias-snap", &snapst) 1632 c.Assert(err, IsNil) 1633 1634 c.Check(snapst.AutoAliasesDisabled, Equals, false) 1635 c.Check(snapst.AliasesPending, Equals, false) 1636 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1637 "alias1": {Auto: "cmd1"}, 1638 "alias2": {Auto: "cmd2"}, 1639 "alias3": {Auto: "cmd3"}, 1640 }) 1641 1642 var otherst1 snapstate.SnapState 1643 err = snapstate.Get(s.state, "other-alias-snap1", &otherst1) 1644 c.Assert(err, IsNil) 1645 c.Check(otherst1.AutoAliasesDisabled, Equals, true) 1646 c.Check(otherst1.AliasesPending, Equals, false) 1647 c.Check(otherst1.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1648 "alias1": {Auto: "cmd1"}, 1649 }) 1650 1651 var otherst2 snapstate.SnapState 1652 err = snapstate.Get(s.state, "other-alias-snap2", &otherst2) 1653 c.Assert(err, IsNil) 1654 c.Check(otherst2.AutoAliasesDisabled, Equals, false) 1655 c.Check(otherst2.AliasesPending, Equals, true) 1656 c.Check(otherst2.Aliases, HasLen, 0) 1657 1658 var otherst3 snapstate.SnapState 1659 err = snapstate.Get(s.state, "other-alias-snap3", &otherst3) 1660 c.Assert(err, IsNil) 1661 c.Check(otherst3.AutoAliasesDisabled, Equals, true) 1662 c.Check(otherst3.AliasesPending, Equals, false) 1663 c.Check(otherst3.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1664 "alias3": {Auto: "cmd3"}, 1665 }) 1666 1667 var trace traceData 1668 err = chg.Get("api-data", &trace) 1669 c.Assert(err, IsNil) 1670 c.Check(trace.Added, HasLen, 3) 1671 c.Check(trace.Removed, HasLen, 4) 1672 } 1673 1674 func (s *snapmgrTestSuite) TestDoUndoPreferAliases(c *C) { 1675 s.state.Lock() 1676 defer s.state.Unlock() 1677 1678 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1679 Sequence: []*snap.SideInfo{ 1680 {RealName: "alias-snap", Revision: snap.R(11)}, 1681 }, 1682 Current: snap.R(11), 1683 Active: true, 1684 AutoAliasesDisabled: true, 1685 Aliases: map[string]*snapstate.AliasTarget{ 1686 "alias1": {Auto: "cmd1"}, 1687 "alias2": {Auto: "cmd2"}, 1688 "alias3": {Auto: "cmd3"}, 1689 }, 1690 }) 1691 snapstate.Set(s.state, "other-alias-snap1", &snapstate.SnapState{ 1692 Sequence: []*snap.SideInfo{ 1693 {RealName: "other-alias-snap1", Revision: snap.R(3)}, 1694 }, 1695 Current: snap.R(3), 1696 Active: true, 1697 Aliases: map[string]*snapstate.AliasTarget{ 1698 "alias1": {Auto: "cmd1"}, 1699 }, 1700 }) 1701 snapstate.Set(s.state, "other-alias-snap2", &snapstate.SnapState{ 1702 Sequence: []*snap.SideInfo{ 1703 {RealName: "other-alias-snap2", Revision: snap.R(3)}, 1704 }, 1705 Current: snap.R(3), 1706 Active: true, 1707 AliasesPending: true, 1708 Aliases: map[string]*snapstate.AliasTarget{ 1709 "alias2": {Manual: "cmd2"}, 1710 "aliasx": {Manual: "cmdx"}, 1711 }, 1712 }) 1713 snapstate.Set(s.state, "other-alias-snap3", &snapstate.SnapState{ 1714 Sequence: []*snap.SideInfo{ 1715 {RealName: "other-alias-snap3", Revision: snap.R(3)}, 1716 }, 1717 Current: snap.R(3), 1718 Active: true, 1719 Aliases: map[string]*snapstate.AliasTarget{ 1720 "alias3": {Manual: "cmd5", Auto: "cmd3"}, 1721 }, 1722 }) 1723 1724 t := s.state.NewTask("prefer-aliases", "test") 1725 t.Set("snap-setup", &snapstate.SnapSetup{ 1726 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1727 }) 1728 chg := s.state.NewChange("dummy", "...") 1729 chg.AddTask(t) 1730 1731 terr := s.state.NewTask("error-trigger", "provoking total undo") 1732 terr.WaitFor(t) 1733 chg.AddTask(terr) 1734 1735 s.state.Unlock() 1736 for i := 0; i < 3; i++ { 1737 s.se.Ensure() 1738 s.se.Wait() 1739 } 1740 s.state.Lock() 1741 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1742 1743 // start with an easier-to-read error if this fails: 1744 c.Assert(s.fakeBackend.ops.Ops(), HasLen, 6) 1745 c.Assert(s.fakeBackend.ops[3], DeepEquals, fakeOp{ 1746 op: "update-aliases", 1747 rmAliases: []*backend.Alias{ 1748 {Name: "alias1", Target: "alias-snap.cmd1"}, 1749 {Name: "alias2", Target: "alias-snap.cmd2"}, 1750 {Name: "alias3", Target: "alias-snap.cmd3"}, 1751 }, 1752 }) 1753 c.Assert(s.fakeBackend.ops[4].aliases, HasLen, 1) 1754 c.Assert(s.fakeBackend.ops[4].rmAliases, HasLen, 0) 1755 c.Assert(s.fakeBackend.ops[5].aliases, HasLen, 1) 1756 c.Assert(s.fakeBackend.ops[5].rmAliases, HasLen, 0) 1757 1758 var snapst snapstate.SnapState 1759 err := snapstate.Get(s.state, "alias-snap", &snapst) 1760 c.Assert(err, IsNil) 1761 1762 c.Check(snapst.AutoAliasesDisabled, Equals, true) 1763 c.Check(snapst.AliasesPending, Equals, false) 1764 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1765 "alias1": {Auto: "cmd1"}, 1766 "alias2": {Auto: "cmd2"}, 1767 "alias3": {Auto: "cmd3"}, 1768 }) 1769 1770 var otherst1 snapstate.SnapState 1771 err = snapstate.Get(s.state, "other-alias-snap1", &otherst1) 1772 c.Assert(err, IsNil) 1773 c.Check(otherst1.AutoAliasesDisabled, Equals, false) 1774 c.Check(otherst1.AliasesPending, Equals, false) 1775 c.Check(otherst1.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1776 "alias1": {Auto: "cmd1"}, 1777 }) 1778 1779 var otherst2 snapstate.SnapState 1780 err = snapstate.Get(s.state, "other-alias-snap2", &otherst2) 1781 c.Assert(err, IsNil) 1782 c.Check(otherst2.AutoAliasesDisabled, Equals, false) 1783 c.Check(otherst2.AliasesPending, Equals, true) 1784 c.Check(otherst2.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1785 "alias2": {Manual: "cmd2"}, 1786 }) 1787 1788 var otherst3 snapstate.SnapState 1789 err = snapstate.Get(s.state, "other-alias-snap3", &otherst3) 1790 c.Assert(err, IsNil) 1791 c.Check(otherst3.AutoAliasesDisabled, Equals, false) 1792 c.Check(otherst3.AliasesPending, Equals, false) 1793 c.Check(otherst3.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1794 "alias3": {Manual: "cmd5", Auto: "cmd3"}, 1795 }) 1796 } 1797 1798 func (s *snapmgrTestSuite) TestDoUndoPreferAliasesConflict(c *C) { 1799 s.state.Lock() 1800 defer s.state.Unlock() 1801 1802 snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ 1803 Sequence: []*snap.SideInfo{ 1804 {RealName: "alias-snap", Revision: snap.R(11)}, 1805 }, 1806 Current: snap.R(11), 1807 Active: true, 1808 AutoAliasesDisabled: true, 1809 Aliases: map[string]*snapstate.AliasTarget{ 1810 "alias1": {Auto: "cmd1"}, 1811 "alias2": {Auto: "cmd2"}, 1812 "alias3": {Auto: "cmd3"}, 1813 }, 1814 }) 1815 snapstate.Set(s.state, "other-alias-snap1", &snapstate.SnapState{ 1816 Sequence: []*snap.SideInfo{ 1817 {RealName: "other-alias-snap1", Revision: snap.R(3)}, 1818 }, 1819 Current: snap.R(3), 1820 Active: true, 1821 Aliases: map[string]*snapstate.AliasTarget{ 1822 "alias1": {Auto: "cmd1"}, 1823 }, 1824 }) 1825 snapstate.Set(s.state, "other-alias-snap2", &snapstate.SnapState{ 1826 Sequence: []*snap.SideInfo{ 1827 {RealName: "other-alias-snap2", Revision: snap.R(3)}, 1828 }, 1829 Current: snap.R(3), 1830 Active: true, 1831 AliasesPending: true, 1832 Aliases: map[string]*snapstate.AliasTarget{ 1833 "alias2": {Manual: "cmd2"}, 1834 "aliasx": {Manual: "cmdx"}, 1835 }, 1836 }) 1837 snapstate.Set(s.state, "other-alias-snap3", &snapstate.SnapState{ 1838 Sequence: []*snap.SideInfo{ 1839 {RealName: "other-alias-snap3", Revision: snap.R(3)}, 1840 }, 1841 Current: snap.R(3), 1842 Active: true, 1843 Aliases: map[string]*snapstate.AliasTarget{ 1844 "alias3": {Manual: "cmd5", Auto: "cmd3"}, 1845 }, 1846 }) 1847 1848 conflictAlias5 := func(t *state.Task, _ *tomb.Tomb) error { 1849 st := t.State() 1850 st.Lock() 1851 defer st.Unlock() 1852 1853 var snapst1, snapst2 snapstate.SnapState 1854 err := snapstate.Get(st, "other-alias-snap1", &snapst1) 1855 c.Assert(err, IsNil) 1856 err = snapstate.Get(st, "other-alias-snap2", &snapst2) 1857 c.Assert(err, IsNil) 1858 snapst1.Aliases = map[string]*snapstate.AliasTarget{ 1859 "alias1": {Auto: "cmd1"}, 1860 "alias5": {Auto: "cmd5"}, 1861 } 1862 snapst2.Aliases = map[string]*snapstate.AliasTarget{ 1863 "alias5": {Manual: "cmd5"}, 1864 } 1865 snapstate.Set(st, "other-alias-snap1", &snapst1) 1866 snapstate.Set(st, "other-alias-snap2", &snapst2) 1867 1868 return nil 1869 } 1870 1871 s.o.TaskRunner().AddHandler("conflict-alias5", conflictAlias5, nil) 1872 1873 t := s.state.NewTask("prefer-aliases", "test") 1874 t.Set("snap-setup", &snapstate.SnapSetup{ 1875 SideInfo: &snap.SideInfo{RealName: "alias-snap"}, 1876 }) 1877 chg := s.state.NewChange("dummy", "...") 1878 chg.AddTask(t) 1879 1880 tconflict5 := s.state.NewTask("conflict-alias5", "create conflict on alias5") 1881 tconflict5.WaitFor(t) 1882 chg.AddTask(tconflict5) 1883 1884 terr := s.state.NewTask("error-trigger", "provoking total undo") 1885 terr.WaitFor(tconflict5) 1886 chg.AddTask(terr) 1887 1888 s.state.Unlock() 1889 for i := 0; i < 5; i++ { 1890 s.se.Ensure() 1891 s.se.Wait() 1892 } 1893 s.state.Lock() 1894 c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) 1895 1896 // start with an easier-to-read error if this fails: 1897 c.Assert(s.fakeBackend.ops.Ops(), HasLen, 5) 1898 c.Assert(s.fakeBackend.ops[3], DeepEquals, fakeOp{ 1899 op: "update-aliases", 1900 rmAliases: []*backend.Alias{ 1901 {Name: "alias1", Target: "alias-snap.cmd1"}, 1902 {Name: "alias2", Target: "alias-snap.cmd2"}, 1903 {Name: "alias3", Target: "alias-snap.cmd3"}, 1904 }, 1905 }) 1906 c.Assert(s.fakeBackend.ops[4], DeepEquals, fakeOp{ 1907 op: "update-aliases", 1908 aliases: []*backend.Alias{ 1909 {Name: "alias3", Target: "other-alias-snap3.cmd5"}, 1910 }, 1911 }) 1912 1913 var snapst snapstate.SnapState 1914 err := snapstate.Get(s.state, "alias-snap", &snapst) 1915 c.Assert(err, IsNil) 1916 1917 c.Check(snapst.AutoAliasesDisabled, Equals, true) 1918 c.Check(snapst.AliasesPending, Equals, false) 1919 c.Check(snapst.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1920 "alias1": {Auto: "cmd1"}, 1921 "alias2": {Auto: "cmd2"}, 1922 "alias3": {Auto: "cmd3"}, 1923 }) 1924 1925 var otherst1 snapstate.SnapState 1926 err = snapstate.Get(s.state, "other-alias-snap1", &otherst1) 1927 c.Assert(err, IsNil) 1928 c.Check(otherst1.AutoAliasesDisabled, Equals, true) 1929 c.Check(otherst1.AliasesPending, Equals, false) 1930 c.Check(otherst1.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1931 "alias1": {Auto: "cmd1"}, 1932 "alias5": {Auto: "cmd5"}, 1933 }) 1934 1935 var otherst2 snapstate.SnapState 1936 err = snapstate.Get(s.state, "other-alias-snap2", &otherst2) 1937 c.Assert(err, IsNil) 1938 c.Check(otherst2.AutoAliasesDisabled, Equals, false) 1939 c.Check(otherst2.AliasesPending, Equals, true) 1940 c.Check(otherst2.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1941 "alias5": {Manual: "cmd5"}, 1942 }) 1943 1944 var otherst3 snapstate.SnapState 1945 err = snapstate.Get(s.state, "other-alias-snap3", &otherst3) 1946 c.Assert(err, IsNil) 1947 c.Check(otherst3.AutoAliasesDisabled, Equals, false) 1948 c.Check(otherst3.AliasesPending, Equals, false) 1949 c.Check(otherst3.Aliases, DeepEquals, map[string]*snapstate.AliasTarget{ 1950 "alias3": {Manual: "cmd5", Auto: "cmd3"}, 1951 }) 1952 }