github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/configstate/configcore/refresh_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017-2018 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 configcore_test 21 22 import ( 23 "time" 24 25 . "gopkg.in/check.v1" 26 27 "github.com/snapcore/snapd/overlord/configstate/configcore" 28 ) 29 30 type refreshSuite struct { 31 configcoreSuite 32 } 33 34 var _ = Suite(&refreshSuite{}) 35 36 func (s *refreshSuite) TestConfigureRefreshTimerHappy(c *C) { 37 err := configcore.Run(classicDev, &mockConf{ 38 state: s.state, 39 conf: map[string]interface{}{ 40 "refresh.timer": "8:00~12:00/2", 41 }, 42 }) 43 c.Assert(err, IsNil) 44 } 45 46 func (s *refreshSuite) TestConfigureRefreshTimerRejected(c *C) { 47 err := configcore.Run(classicDev, &mockConf{ 48 state: s.state, 49 conf: map[string]interface{}{ 50 "refresh.timer": "invalid", 51 }, 52 }) 53 c.Assert(err, ErrorMatches, `cannot parse "invalid": "invalid" is not a valid weekday`) 54 } 55 56 func (s *refreshSuite) TestConfigureRefreshTimerManagedIgnored(c *C) { 57 for _, opt := range []string{"refresh.timer", "refresh.schedule"} { 58 cfg := &mockConf{ 59 state: s.state, 60 // invalid value present in the state 61 conf: map[string]interface{}{ 62 opt: "managed", 63 }, 64 } 65 s.state.Lock() 66 s.state.OkayWarnings(time.Now()) 67 s.state.Unlock() 68 err := configcore.Run(classicDev, cfg) 69 c.Assert(err, IsNil) 70 71 s.state.Lock() 72 c.Check(cfg.conf[opt], Equals, "managed") 73 s.state.Unlock() 74 } 75 } 76 77 func (s *refreshSuite) TestConfigureRefreshTimerManagedChangeError(c *C) { 78 for _, opt := range []string{"refresh.timer", "refresh.schedule"} { 79 cfg := &mockConf{ 80 state: s.state, 81 conf: map[string]interface{}{ 82 // valid value in the state, should remain intact 83 opt: "fri", 84 }, 85 changes: map[string]interface{}{ 86 opt: "managed", 87 }, 88 } 89 err := configcore.Run(classicDev, cfg) 90 c.Assert(err, ErrorMatches, `cannot set schedule to managed`) 91 // old value still present 92 c.Check(cfg.conf[opt], Equals, "fri") 93 } 94 } 95 96 func (s *refreshSuite) TestConfigureLegacyRefreshScheduleHappy(c *C) { 97 err := configcore.Run(classicDev, &mockConf{ 98 state: s.state, 99 conf: map[string]interface{}{ 100 "refresh.schedule": "8:00-12:00", 101 }, 102 }) 103 c.Assert(err, IsNil) 104 } 105 106 func (s *refreshSuite) TestConfigureLegacyRefreshScheduleRejected(c *C) { 107 err := configcore.Run(classicDev, &mockConf{ 108 state: s.state, 109 conf: map[string]interface{}{ 110 "refresh.schedule": "invalid", 111 }, 112 }) 113 c.Assert(err, ErrorMatches, `cannot parse "invalid": not a valid interval`) 114 115 // check that refresh.schedule is verified against legacy parser 116 err = configcore.Run(classicDev, &mockConf{ 117 state: s.state, 118 conf: map[string]interface{}{ 119 "refresh.schedule": "8:00~12:00/2", 120 }, 121 }) 122 c.Assert(err, ErrorMatches, `cannot parse "8:00~12:00": not a valid interval`) 123 } 124 125 func (s *refreshSuite) TestConfigureRefreshHoldHappy(c *C) { 126 err := configcore.Run(classicDev, &mockConf{ 127 state: s.state, 128 conf: map[string]interface{}{ 129 "refresh.hold": "2018-08-18T15:00:00Z", 130 }, 131 }) 132 c.Assert(err, IsNil) 133 } 134 135 func (s *refreshSuite) TestConfigureRefreshHoldInvalid(c *C) { 136 err := configcore.Run(classicDev, &mockConf{ 137 state: s.state, 138 conf: map[string]interface{}{ 139 "refresh.hold": "invalid", 140 }, 141 }) 142 c.Assert(err, ErrorMatches, `refresh\.hold cannot be parsed:.*`) 143 } 144 145 func (s *refreshSuite) TestConfigureRefreshHoldOnMeteredInvalid(c *C) { 146 err := configcore.Run(classicDev, &mockConf{ 147 state: s.state, 148 conf: map[string]interface{}{ 149 "refresh.metered": "invalid", 150 }, 151 }) 152 c.Assert(err, ErrorMatches, `refresh\.metered value "invalid" is invalid`) 153 } 154 155 func (s *refreshSuite) TestConfigureRefreshHoldOnMeteredHappy(c *C) { 156 err := configcore.Run(classicDev, &mockConf{ 157 state: s.state, 158 conf: map[string]interface{}{ 159 "refresh.metered": "hold", 160 }, 161 }) 162 c.Assert(err, IsNil) 163 164 err = configcore.Run(classicDev, &mockConf{ 165 state: s.state, 166 conf: map[string]interface{}{ 167 "refresh.metered": "", 168 }, 169 }) 170 c.Assert(err, IsNil) 171 } 172 173 func (s *refreshSuite) TestConfigureRefreshRetainHappy(c *C) { 174 err := configcore.Run(classicDev, &mockConf{ 175 state: s.state, 176 conf: map[string]interface{}{ 177 "refresh.retain": "4", 178 }, 179 }) 180 c.Assert(err, IsNil) 181 } 182 183 func (s *refreshSuite) TestConfigureRefreshRetainUnderRange(c *C) { 184 err := configcore.Run(classicDev, &mockConf{ 185 state: s.state, 186 conf: map[string]interface{}{ 187 "refresh.retain": "1", 188 }, 189 }) 190 c.Assert(err, ErrorMatches, `retain must be a number between 2 and 20, not "1"`) 191 } 192 193 func (s *refreshSuite) TestConfigureRefreshRetainOverRange(c *C) { 194 err := configcore.Run(classicDev, &mockConf{ 195 state: s.state, 196 conf: map[string]interface{}{ 197 "refresh.retain": "100", 198 }, 199 }) 200 c.Assert(err, ErrorMatches, `retain must be a number between 2 and 20, not "100"`) 201 } 202 203 func (s *refreshSuite) TestConfigureRefreshRetainInvalid(c *C) { 204 err := configcore.Run(classicDev, &mockConf{ 205 state: s.state, 206 conf: map[string]interface{}{ 207 "refresh.retain": "invalid", 208 }, 209 }) 210 c.Assert(err, ErrorMatches, `retain must be a number between 2 and 20, not "invalid"`) 211 }