github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/hookstate/ctlcmd/unset_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 ctlcmd_test 21 22 import ( 23 "strings" 24 25 "github.com/snapcore/snapd/overlord/configstate/config" 26 "github.com/snapcore/snapd/overlord/hookstate" 27 "github.com/snapcore/snapd/overlord/hookstate/ctlcmd" 28 "github.com/snapcore/snapd/overlord/hookstate/hooktest" 29 "github.com/snapcore/snapd/overlord/state" 30 "github.com/snapcore/snapd/snap" 31 32 . "gopkg.in/check.v1" 33 ) 34 35 type unsetSuite struct { 36 mockContext *hookstate.Context 37 mockHandler *hooktest.MockHandler 38 } 39 40 var _ = Suite(&unsetSuite{}) 41 42 func (s *unsetSuite) SetUpTest(c *C) { 43 s.mockHandler = hooktest.NewMockHandler() 44 45 state := state.New(nil) 46 state.Lock() 47 defer state.Unlock() 48 49 task := state.NewTask("test-task", "my test task") 50 setup := &hookstate.HookSetup{Snap: "test-snap", Revision: snap.R(1), Hook: "hook"} 51 52 var err error 53 s.mockContext, err = hookstate.NewContext(task, task.State(), setup, s.mockHandler, "") 54 c.Assert(err, IsNil) 55 } 56 57 func (s *unsetSuite) TestInvalidArguments(c *C) { 58 _, _, err := ctlcmd.Run(s.mockContext, []string{"unset"}, 0) 59 c.Check(err, ErrorMatches, "unset which option.*") 60 } 61 62 func (s *unsetSuite) TestUnsetOne(c *C) { 63 // Setup an initial configuration 64 s.mockContext.State().Lock() 65 tr := config.NewTransaction(s.mockContext.State()) 66 tr.Set("test-snap", "foo", "a") 67 tr.Commit() 68 s.mockContext.State().Unlock() 69 70 // Sanity check 71 var value interface{} 72 s.mockContext.State().Lock() 73 tr = config.NewTransaction(s.mockContext.State()) 74 c.Check(tr.Get("test-snap", "foo", &value), IsNil) 75 s.mockContext.State().Unlock() 76 c.Check(value, Equals, "a") 77 78 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"unset", "foo"}, 0) 79 c.Check(err, IsNil) 80 c.Check(string(stdout), Equals, "") 81 c.Check(string(stderr), Equals, "") 82 83 // Notify the context that we're done. This should save the config. 84 s.mockContext.Lock() 85 defer s.mockContext.Unlock() 86 c.Check(s.mockContext.Done(), IsNil) 87 88 // Verify that the global config has been updated. 89 tr = config.NewTransaction(s.mockContext.State()) 90 c.Check(tr.Get("test-snap", "foo", &value), ErrorMatches, `snap "test-snap" has no "foo" configuration option`) 91 } 92 93 func (s *unsetSuite) TestUnsetMany(c *C) { 94 // Setup an initial configuration 95 s.mockContext.State().Lock() 96 tr := config.NewTransaction(s.mockContext.State()) 97 tr.Set("test-snap", "foo", "a") 98 tr.Set("test-snap", "bar", "b") 99 tr.Set("test-snap", "baz", "c") 100 tr.Commit() 101 s.mockContext.State().Unlock() 102 103 stdout, stderr, err := ctlcmd.Run(s.mockContext, []string{"unset", "foo", "bar"}, 0) 104 c.Check(err, IsNil) 105 c.Check(string(stdout), Equals, "") 106 c.Check(string(stderr), Equals, "") 107 108 // Notify the context that we're done. This should save the config. 109 s.mockContext.Lock() 110 defer s.mockContext.Unlock() 111 c.Check(s.mockContext.Done(), IsNil) 112 113 // Verify that the global config has been updated. 114 var value interface{} 115 tr = config.NewTransaction(s.mockContext.State()) 116 c.Check(tr.Get("test-snap", "foo", &value), ErrorMatches, `snap "test-snap" has no "foo" configuration option`) 117 c.Check(tr.Get("test-snap", "bar", &value), ErrorMatches, `snap "test-snap" has no "bar" configuration option`) 118 c.Check(tr.Get("test-snap", "baz", &value), IsNil) 119 c.Check(value, Equals, "c") 120 } 121 122 func (s *unsetSuite) TestUnsetRegularUserForbidden(c *C) { 123 _, _, err := ctlcmd.Run(s.mockContext, []string{"unset", "key"}, 1000) 124 c.Assert(err, ErrorMatches, `cannot use "unset" with uid 1000, try with sudo`) 125 forbidden, _ := err.(*ctlcmd.ForbiddenCommandError) 126 c.Assert(forbidden, NotNil) 127 } 128 129 func (s *unsetSuite) TestUnsetHelpRegularUserAllowed(c *C) { 130 _, _, err := ctlcmd.Run(s.mockContext, []string{"unset", "-h"}, 1000) 131 c.Assert(strings.HasPrefix(err.Error(), "Usage:"), Equals, true) 132 } 133 134 func (s *unsetSuite) TestCommandWithoutContext(c *C) { 135 _, _, err := ctlcmd.Run(nil, []string{"unset", "foo"}, 0) 136 c.Check(err, ErrorMatches, ".*cannot unset without a context.*") 137 }