github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/overlord/snapstate/snapstate_try_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2020 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 "bytes" 24 "io/ioutil" 25 "os" 26 "path/filepath" 27 28 . "gopkg.in/check.v1" 29 30 "github.com/snapcore/snapd/overlord/snapstate" 31 "github.com/snapcore/snapd/snap" 32 ) 33 34 func (s *snapmgrTestSuite) TestTrySetsTryMode(c *C) { 35 s.testTrySetsTryMode(snapstate.Flags{}, c) 36 } 37 38 func (s *snapmgrTestSuite) TestTrySetsTryModeDevMode(c *C) { 39 s.testTrySetsTryMode(snapstate.Flags{DevMode: true}, c) 40 } 41 func (s *snapmgrTestSuite) TestTrySetsTryModeJailMode(c *C) { 42 s.testTrySetsTryMode(snapstate.Flags{JailMode: true}, c) 43 } 44 func (s *snapmgrTestSuite) TestTrySetsTryModeClassic(c *C) { 45 restore := maybeMockClassicSupport(c) 46 defer restore() 47 48 s.testTrySetsTryMode(snapstate.Flags{Classic: true}, c, "confinement: classic\n") 49 } 50 51 func (s *snapmgrTestSuite) testTrySetsTryMode(flags snapstate.Flags, c *C, extraYaml ...string) { 52 s.state.Lock() 53 defer s.state.Unlock() 54 55 // make mock try dir 56 d := c.MkDir() 57 c.Assert(os.Chmod(d, 0755), IsNil) 58 tryYaml := filepath.Join(d, "meta", "snap.yaml") 59 err := os.MkdirAll(filepath.Dir(tryYaml), 0755) 60 c.Assert(err, IsNil) 61 buf := bytes.Buffer{} 62 buf.WriteString("name: foo\nversion: 1.0\n") 63 if len(extraYaml) > 0 { 64 for _, extra := range extraYaml { 65 buf.WriteString(extra) 66 } 67 } 68 err = ioutil.WriteFile(tryYaml, buf.Bytes(), 0644) 69 c.Assert(err, IsNil) 70 71 chg := s.state.NewChange("try", "try snap") 72 ts, err := snapstate.TryPath(s.state, "foo", d, flags) 73 c.Assert(err, IsNil) 74 chg.AddAll(ts) 75 76 s.state.Unlock() 77 defer s.se.Stop() 78 s.settle(c) 79 s.state.Lock() 80 81 c.Assert(chg.Err(), IsNil) 82 c.Assert(chg.IsReady(), Equals, true) 83 84 // verify snap is in TryMode 85 var snapst snapstate.SnapState 86 err = snapstate.Get(s.state, "foo", &snapst) 87 c.Assert(err, IsNil) 88 89 flags.TryMode = true 90 c.Check(snapst.Flags, DeepEquals, flags) 91 92 c.Check(s.state.TaskCount(), Equals, len(ts.Tasks())) 93 c.Check(taskKinds(ts.Tasks()), DeepEquals, []string{ 94 "prerequisites", 95 "prepare-snap", 96 "mount-snap", 97 "copy-snap-data", 98 "setup-profiles", 99 "link-snap", 100 "auto-connect", 101 "set-auto-aliases", 102 "setup-aliases", 103 "run-hook[install]", 104 "start-snap-services", 105 "run-hook[configure]", 106 "run-hook[check-health]", 107 }) 108 109 } 110 111 func (s *snapmgrTestSuite) TestTryUndoRemovesTryFlag(c *C) { 112 restore := maybeMockClassicSupport(c) 113 defer restore() 114 s.testTrySetsTryMode(snapstate.Flags{}, c) 115 } 116 117 func (s *snapmgrTestSuite) TestTryUndoRemovesTryFlagLeavesDevMode(c *C) { 118 s.testTrySetsTryMode(snapstate.Flags{DevMode: true}, c) 119 } 120 func (s *snapmgrTestSuite) TestTryUndoRemovesTryFlagLeavesJailMode(c *C) { 121 s.testTrySetsTryMode(snapstate.Flags{JailMode: true}, c) 122 } 123 func (s *snapmgrTestSuite) TestTryUndoRemovesTryFlagLeavesClassic(c *C) { 124 restore := maybeMockClassicSupport(c) 125 defer restore() 126 s.testTrySetsTryMode(snapstate.Flags{Classic: true}, c, "confinement: classic\n") 127 } 128 129 func (s *snapmgrTestSuite) testTryUndoRemovesTryFlag(flags snapstate.Flags, c *C) { 130 s.state.Lock() 131 defer s.state.Unlock() 132 133 // simulate existing state for foo 134 var snapst snapstate.SnapState 135 snapst.Sequence = []*snap.SideInfo{ 136 { 137 RealName: "foo", 138 Revision: snap.R(23), 139 }, 140 } 141 snapst.Flags = flags 142 snapst.Current = snap.R(23) 143 snapstate.Set(s.state, "foo", &snapst) 144 c.Check(snapst.TryMode, Equals, false) 145 146 chg := s.state.NewChange("try", "try snap") 147 ts, err := snapstate.TryPath(s.state, "foo", c.MkDir(), flags) 148 c.Assert(err, IsNil) 149 chg.AddAll(ts) 150 151 last := ts.Tasks()[len(ts.Tasks())-1] 152 terr := s.state.NewTask("error-trigger", "provoking total undo") 153 terr.WaitFor(last) 154 chg.AddTask(terr) 155 156 s.state.Unlock() 157 defer s.se.Stop() 158 s.settle(c) 159 s.state.Lock() 160 161 // verify snap is not in try mode, the state got undone 162 err = snapstate.Get(s.state, "foo", &snapst) 163 c.Assert(err, IsNil) 164 c.Check(snapst.Flags, DeepEquals, flags) 165 }