github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/hookstate/ctlcmd/system_mode_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2021 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 ctlcmd_test 21 22 import ( 23 "fmt" 24 25 . "gopkg.in/check.v1" 26 27 "github.com/snapcore/snapd/dirs" 28 "github.com/snapcore/snapd/overlord/devicestate" 29 "github.com/snapcore/snapd/overlord/hookstate" 30 "github.com/snapcore/snapd/overlord/hookstate/ctlcmd" 31 "github.com/snapcore/snapd/overlord/hookstate/hooktest" 32 "github.com/snapcore/snapd/overlord/state" 33 "github.com/snapcore/snapd/snap" 34 "github.com/snapcore/snapd/testutil" 35 ) 36 37 type systemModeSuite struct { 38 testutil.BaseTest 39 st *state.State 40 mockHandler *hooktest.MockHandler 41 } 42 43 var _ = Suite(&systemModeSuite{}) 44 45 func (s *systemModeSuite) SetUpTest(c *C) { 46 s.BaseTest.SetUpTest(c) 47 dirs.SetRootDir(c.MkDir()) 48 s.AddCleanup(func() { dirs.SetRootDir("/") }) 49 s.st = state.New(nil) 50 s.mockHandler = hooktest.NewMockHandler() 51 } 52 53 func (s *systemModeSuite) TestSystemMode(c *C) { 54 s.st.Lock() 55 task := s.st.NewTask("test-task", "my test task") 56 setup := &hookstate.HookSetup{Snap: "snap1", Revision: snap.R(1), Hook: "test-hook"} 57 mockContext, err := hookstate.NewContext(task, s.st, setup, s.mockHandler, "") 58 c.Check(err, IsNil) 59 s.st.Unlock() 60 61 var smi *devicestate.SystemModeInfo 62 var smiErr error 63 r := ctlcmd.MockDevicestateSystemModeInfoFromState(func(s *state.State) (*devicestate.SystemModeInfo, error) { 64 // the mocked function requires the state lock, 65 // panic if it is not held 66 s.Unlock() 67 defer s.Lock() 68 return smi, smiErr 69 }) 70 defer r() 71 72 tests := []struct { 73 smi devicestate.SystemModeInfo 74 smiErr error 75 stdout, stderr, err string 76 exitCode int 77 }{ 78 { 79 smiErr: fmt.Errorf("too early"), 80 err: "too early", 81 }, { 82 smi: devicestate.SystemModeInfo{ 83 Mode: "run", 84 Seeded: true, 85 }, 86 stdout: "system-mode: run\nseed-loaded: true\n", 87 }, { 88 smi: devicestate.SystemModeInfo{ 89 Mode: "install", 90 HasModeenv: true, 91 Seeded: true, 92 BootFlags: []string{"factory"}, 93 }, 94 stdout: "system-mode: install\nseed-loaded: true\nfactory: true\n", 95 }, { 96 smi: devicestate.SystemModeInfo{ 97 Mode: "run", 98 HasModeenv: true, 99 Seeded: false, 100 }, 101 stdout: "system-mode: run\nseed-loaded: false\n", 102 }, 103 } 104 105 for _, uid := range []uint32{0 /* root */, 1000 /* regular */} { 106 for _, test := range tests { 107 smi = &test.smi 108 smiErr = test.smiErr 109 110 stdout, stderr, err := ctlcmd.Run(mockContext, []string{"system-mode"}, uid) 111 comment := Commentf("%v", test) 112 if test.exitCode > 0 { 113 c.Check(err, DeepEquals, &ctlcmd.UnsuccessfulError{ExitCode: test.exitCode}, comment) 114 } else { 115 if test.err == "" { 116 c.Check(err, IsNil, comment) 117 } else { 118 c.Check(err, ErrorMatches, test.err, comment) 119 } 120 } 121 122 c.Check(string(stdout), Equals, test.stdout, comment) 123 c.Check(string(stderr), Equals, "", comment) 124 } 125 } 126 }