gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/overlord/assertstate/validation_set_tracking_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 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 assertstate_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 "github.com/snapcore/snapd/asserts" 26 "github.com/snapcore/snapd/asserts/assertstest" 27 "github.com/snapcore/snapd/overlord/assertstate" 28 "github.com/snapcore/snapd/overlord/assertstate/assertstatetest" 29 "github.com/snapcore/snapd/overlord/state" 30 ) 31 32 type validationSetTrackingSuite struct { 33 st *state.State 34 //storeSigning *assertstest.StoreStack 35 dev1Signing *assertstest.SigningDB 36 dev1acct *asserts.Account 37 } 38 39 var _ = Suite(&validationSetTrackingSuite{}) 40 41 func (s *validationSetTrackingSuite) SetUpTest(c *C) { 42 s.st = state.New(nil) 43 44 s.st.Lock() 45 defer s.st.Unlock() 46 storeSigning := assertstest.NewStoreStack("can0nical", nil) 47 db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ 48 Backstore: asserts.NewMemoryBackstore(), 49 Trusted: storeSigning.Trusted, 50 }) 51 c.Assert(err, IsNil) 52 c.Assert(db.Add(storeSigning.StoreAccountKey("")), IsNil) 53 assertstate.ReplaceDB(s.st, db) 54 55 s.dev1acct = assertstest.NewAccount(storeSigning, "developer1", nil, "") 56 c.Assert(storeSigning.Add(s.dev1acct), IsNil) 57 58 dev1PrivKey, _ = assertstest.GenerateKey(752) 59 acct1Key := assertstest.NewAccountKey(storeSigning, s.dev1acct, nil, dev1PrivKey.PublicKey(), "") 60 61 assertstatetest.AddMany(s.st, storeSigning.StoreAccountKey(""), s.dev1acct, acct1Key) 62 63 s.dev1Signing = assertstest.NewSigningDB(s.dev1acct.AccountID(), dev1PrivKey) 64 c.Check(s.dev1Signing, NotNil) 65 c.Assert(storeSigning.Add(acct1Key), IsNil) 66 } 67 68 func (s *validationSetTrackingSuite) TestUpdate(c *C) { 69 s.st.Lock() 70 defer s.st.Unlock() 71 72 all, err := assertstate.ValidationSets(s.st) 73 c.Assert(err, IsNil) 74 c.Assert(all, HasLen, 0) 75 76 tr := assertstate.ValidationSetTracking{ 77 AccountID: "foo", 78 Name: "bar", 79 Mode: assertstate.Enforce, 80 PinnedAt: 1, 81 Current: 2, 82 } 83 assertstate.UpdateValidationSet(s.st, &tr) 84 85 all, err = assertstate.ValidationSets(s.st) 86 c.Assert(err, IsNil) 87 c.Assert(all, HasLen, 1) 88 for k, v := range all { 89 c.Check(k, Equals, "foo/bar") 90 c.Check(v, DeepEquals, &assertstate.ValidationSetTracking{AccountID: "foo", Name: "bar", Mode: assertstate.Enforce, PinnedAt: 1, Current: 2}) 91 } 92 93 tr = assertstate.ValidationSetTracking{ 94 AccountID: "foo", 95 Name: "bar", 96 Mode: assertstate.Monitor, 97 PinnedAt: 2, 98 Current: 3, 99 } 100 assertstate.UpdateValidationSet(s.st, &tr) 101 102 all, err = assertstate.ValidationSets(s.st) 103 c.Assert(err, IsNil) 104 c.Assert(all, HasLen, 1) 105 for k, v := range all { 106 c.Check(k, Equals, "foo/bar") 107 c.Check(v, DeepEquals, &assertstate.ValidationSetTracking{AccountID: "foo", Name: "bar", Mode: assertstate.Monitor, PinnedAt: 2, Current: 3}) 108 } 109 110 tr = assertstate.ValidationSetTracking{ 111 AccountID: "foo", 112 Name: "baz", 113 Mode: assertstate.Enforce, 114 Current: 3, 115 } 116 assertstate.UpdateValidationSet(s.st, &tr) 117 118 all, err = assertstate.ValidationSets(s.st) 119 c.Assert(err, IsNil) 120 c.Assert(all, HasLen, 2) 121 122 var gotFirst, gotSecond bool 123 for k, v := range all { 124 if k == "foo/bar" { 125 gotFirst = true 126 c.Check(v, DeepEquals, &assertstate.ValidationSetTracking{AccountID: "foo", Name: "bar", Mode: assertstate.Monitor, PinnedAt: 2, Current: 3}) 127 } else { 128 gotSecond = true 129 c.Check(k, Equals, "foo/baz") 130 c.Check(v, DeepEquals, &assertstate.ValidationSetTracking{AccountID: "foo", Name: "baz", Mode: assertstate.Enforce, PinnedAt: 0, Current: 3}) 131 } 132 } 133 c.Check(gotFirst, Equals, true) 134 c.Check(gotSecond, Equals, true) 135 } 136 137 func (s *validationSetTrackingSuite) TestDelete(c *C) { 138 s.st.Lock() 139 defer s.st.Unlock() 140 141 // delete non-existing one is fine 142 assertstate.DeleteValidationSet(s.st, "foo", "bar") 143 all, err := assertstate.ValidationSets(s.st) 144 c.Assert(err, IsNil) 145 c.Assert(all, HasLen, 0) 146 147 tr := assertstate.ValidationSetTracking{ 148 AccountID: "foo", 149 Name: "bar", 150 Mode: assertstate.Monitor, 151 } 152 assertstate.UpdateValidationSet(s.st, &tr) 153 154 all, err = assertstate.ValidationSets(s.st) 155 c.Assert(err, IsNil) 156 c.Assert(all, HasLen, 1) 157 158 // deletes existing one 159 assertstate.DeleteValidationSet(s.st, "foo", "bar") 160 all, err = assertstate.ValidationSets(s.st) 161 c.Assert(err, IsNil) 162 c.Assert(all, HasLen, 0) 163 } 164 165 func (s *validationSetTrackingSuite) TestGet(c *C) { 166 s.st.Lock() 167 defer s.st.Unlock() 168 169 err := assertstate.GetValidationSet(s.st, "foo", "bar", nil) 170 c.Assert(err, ErrorMatches, `internal error: tr is nil`) 171 172 tr := assertstate.ValidationSetTracking{ 173 AccountID: "foo", 174 Name: "bar", 175 Mode: assertstate.Enforce, 176 Current: 3, 177 } 178 assertstate.UpdateValidationSet(s.st, &tr) 179 180 var res assertstate.ValidationSetTracking 181 err = assertstate.GetValidationSet(s.st, "foo", "bar", &res) 182 c.Assert(err, IsNil) 183 c.Check(res, DeepEquals, tr) 184 185 // non-existing 186 err = assertstate.GetValidationSet(s.st, "foo", "baz", &res) 187 c.Assert(err, Equals, state.ErrNoState) 188 } 189 190 func (s *validationSetTrackingSuite) mockAssert(c *C, name, sequence, presence string) asserts.Assertion { 191 snaps := []interface{}{map[string]interface{}{ 192 "id": "yOqKhntON3vR7kwEbVPsILm7bUViPDzz", 193 "name": "snap-b", 194 "presence": presence, 195 }} 196 headers := map[string]interface{}{ 197 "authority-id": s.dev1acct.AccountID(), 198 "account-id": s.dev1acct.AccountID(), 199 "name": name, 200 "series": "16", 201 "sequence": sequence, 202 "revision": "5", 203 "timestamp": "2030-11-06T09:16:26Z", 204 "snaps": snaps, 205 } 206 as, err := s.dev1Signing.Sign(asserts.ValidationSetType, headers, nil, "") 207 c.Assert(err, IsNil) 208 return as 209 } 210 211 func (s *validationSetTrackingSuite) TestEnforcedValidationSets(c *C) { 212 s.st.Lock() 213 defer s.st.Unlock() 214 215 tr := assertstate.ValidationSetTracking{ 216 AccountID: s.dev1acct.AccountID(), 217 Name: "foo", 218 Mode: assertstate.Enforce, 219 Current: 2, 220 } 221 assertstate.UpdateValidationSet(s.st, &tr) 222 223 tr = assertstate.ValidationSetTracking{ 224 AccountID: s.dev1acct.AccountID(), 225 Name: "bar", 226 Mode: assertstate.Enforce, 227 PinnedAt: 1, 228 Current: 3, 229 } 230 assertstate.UpdateValidationSet(s.st, &tr) 231 232 tr = assertstate.ValidationSetTracking{ 233 AccountID: s.dev1acct.AccountID(), 234 Name: "baz", 235 Mode: assertstate.Monitor, 236 Current: 5, 237 } 238 assertstate.UpdateValidationSet(s.st, &tr) 239 240 vs1 := s.mockAssert(c, "foo", "2", "required") 241 c.Assert(assertstate.Add(s.st, vs1), IsNil) 242 243 vs2 := s.mockAssert(c, "bar", "1", "invalid") 244 c.Assert(assertstate.Add(s.st, vs2), IsNil) 245 246 vs3 := s.mockAssert(c, "baz", "5", "invalid") 247 c.Assert(assertstate.Add(s.st, vs3), IsNil) 248 249 valsets, err := assertstate.EnforcedValidationSets(s.st) 250 c.Assert(err, IsNil) 251 252 // foo and bar are in conflict, use this as an indirect way of checking 253 // that both were added to valsets. 254 // XXX: switch to CheckPresenceInvalid / CheckPresenceRequired once available. 255 err = valsets.Conflict() 256 c.Check(err, ErrorMatches, `validation sets are in conflict:\n- cannot constrain snap "snap-b" as both invalid \(.*/bar\) and required at any revision \(.*/foo\)`) 257 }