github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/hookstate/ctlcmd/health_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 "gopkg.in/check.v1" 24 25 "github.com/snapcore/snapd/dirs" 26 "github.com/snapcore/snapd/overlord/healthstate" 27 "github.com/snapcore/snapd/overlord/hookstate" 28 "github.com/snapcore/snapd/overlord/hookstate/ctlcmd" 29 "github.com/snapcore/snapd/overlord/hookstate/hooktest" 30 "github.com/snapcore/snapd/overlord/state" 31 "github.com/snapcore/snapd/snap" 32 "github.com/snapcore/snapd/testutil" 33 ) 34 35 type healthSuite struct { 36 testutil.BaseTest 37 state *state.State 38 mockContext *hookstate.Context 39 mockHandler *hooktest.MockHandler 40 } 41 42 var _ = check.Suite(&healthSuite{}) 43 44 func (s *healthSuite) SetUpTest(c *check.C) { 45 s.BaseTest.SetUpTest(c) 46 dirs.SetRootDir(c.MkDir()) 47 48 testutil.MockCommand(c, "systemctl", "") 49 s.mockHandler = hooktest.NewMockHandler() 50 51 s.state = state.New(nil) 52 s.state.Lock() 53 defer s.state.Unlock() 54 task := s.state.NewTask("test-task", "my test task") 55 setup := &hookstate.HookSetup{Snap: "test-snap", Revision: snap.R(42), Hook: "check-health"} 56 57 ctx, err := hookstate.NewContext(task, s.state, setup, s.mockHandler, "") 58 c.Assert(err, check.IsNil) 59 s.mockContext = ctx 60 } 61 62 func (s *healthSuite) TestBadArgs(c *check.C) { 63 type tableT struct { 64 args []string 65 err string 66 } 67 table := []tableT{ 68 { 69 []string{"set-health"}, 70 "the required argument `<status>` was not provided", 71 }, { 72 []string{"set-health", "bananas", "message"}, 73 `invalid status "bananas".*`, 74 }, { 75 []string{"set-health", "unknown", "message"}, 76 `status cannot be manually set to "unknown"`, 77 }, { 78 []string{"set-health", "okay", "message"}, 79 `when status is "okay", message and code must be empty`, 80 }, { 81 []string{"set-health", "okay", "--code=what"}, 82 `when status is "okay", message and code must be empty`, 83 }, { 84 []string{"set-health", "blocked"}, 85 `when status is not "okay", message is required`, 86 }, { 87 []string{"set-health", "blocked", "message", "--code=xx"}, 88 `code must have between 3 and 30 characters, got 2`, 89 }, { 90 []string{"set-health", "blocked", "message", "--code=abcdefghijklmnopqrstuvwxyz12345"}, 91 `code must have between 3 and 30 characters, got 31`, 92 }, { 93 []string{"set-health", "blocked", "message", "--code=☠☢☣💣💢🐍✴👿‼"}, 94 `code must have between 3 and 30 characters, got 31`, 95 }, { 96 []string{"set-health", "blocked", "message", "--code=123"}, 97 `invalid code "123".*`, 98 }, { 99 []string{"set-health", "blocked", "what"}, 100 `message must be at least 7 characters long \(got 4\)`, 101 }, { 102 []string{"set-health", "blocked", "áéíóú"}, 103 `message must be at least 7 characters long \(got 5\)`, 104 }, { 105 []string{"set-health", "blocked", "message"}, 106 `cannot set-health without a context`, 107 }, 108 } 109 110 for i, t := range table { 111 _, _, err := ctlcmd.Run(nil, t.args, 0) 112 c.Check(err, check.ErrorMatches, t.err, check.Commentf("%d", i)) 113 } 114 } 115 116 func (s *healthSuite) TestRegularRun(c *check.C) { 117 _, _, err := ctlcmd.Run(s.mockContext, []string{"set-health", "blocked", "message", "--code=some-code"}, 0) 118 c.Assert(err, check.IsNil) 119 120 s.mockContext.Lock() 121 defer s.mockContext.Unlock() 122 123 var health healthstate.HealthState 124 c.Assert(s.mockContext.Get("health", &health), check.IsNil) 125 c.Check(health.Revision, check.Equals, snap.R(42)) 126 c.Check(health.Status, check.Equals, healthstate.BlockedStatus) 127 c.Check(health.Message, check.Equals, "message") 128 c.Check(health.Code, check.Equals, "some-code") 129 } 130 131 func (s *healthSuite) TestMessageTruncation(c *check.C) { 132 _, _, err := ctlcmd.Run(s.mockContext, []string{"set-health", "waiting", "Sometimes messages will get a little bit too verbose and this can lead to some rather nasty UX (as well as potential memory problems in extreme cases) so we kinda have to deal with that", "--code=some-code"}, 0) 133 c.Assert(err, check.IsNil) 134 135 s.mockContext.Lock() 136 defer s.mockContext.Unlock() 137 138 var health healthstate.HealthState 139 c.Assert(s.mockContext.Get("health", &health), check.IsNil) 140 c.Check(health.Revision, check.Equals, snap.R(42)) 141 c.Check(health.Status, check.Equals, healthstate.WaitingStatus) 142 c.Check(health.Message, check.Equals, "Sometimes messages will get a little bit too verbose and this can lea…") 143 c.Check(health.Code, check.Equals, "some-code") 144 }