github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/asserts/pool_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 asserts_test 21 22 import ( 23 "errors" 24 "sort" 25 26 . "gopkg.in/check.v1" 27 28 "github.com/snapcore/snapd/asserts" 29 "github.com/snapcore/snapd/asserts/assertstest" 30 "github.com/snapcore/snapd/testutil" 31 ) 32 33 type poolSuite struct { 34 testutil.BaseTest 35 36 hub *assertstest.StoreStack 37 dev1Acct *asserts.Account 38 dev2Acct *asserts.Account 39 40 decl1 *asserts.TestOnlyDecl 41 decl1_1 *asserts.TestOnlyDecl 42 rev1_1111 *asserts.TestOnlyRev 43 rev1_3333 *asserts.TestOnlyRev 44 45 decl2 *asserts.TestOnlyDecl 46 rev2_2222 *asserts.TestOnlyRev 47 48 seq1_1111r5 *asserts.TestOnlySeq 49 seq1_1111r6 *asserts.TestOnlySeq 50 seq2_1111r7 *asserts.TestOnlySeq 51 seq3_1111r5 *asserts.TestOnlySeq 52 53 db *asserts.Database 54 } 55 56 var _ = Suite(&poolSuite{}) 57 58 func (s *poolSuite) SetUpTest(c *C) { 59 s.BaseTest.SetUpTest(c) 60 61 s.hub = assertstest.NewStoreStack("hub", nil) 62 s.dev1Acct = assertstest.NewAccount(s.hub, "developer1", map[string]interface{}{ 63 "account-id": "developer1", 64 }, "") 65 s.dev2Acct = assertstest.NewAccount(s.hub, "developer2", map[string]interface{}{ 66 "account-id": "developer2", 67 }, "") 68 69 a, err := s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{ 70 "id": "one", 71 "dev-id": "developer1", 72 }, nil, "") 73 c.Assert(err, IsNil) 74 s.decl1 = a.(*asserts.TestOnlyDecl) 75 76 a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{ 77 "id": "one", 78 "dev-id": "developer1", 79 "revision": "1", 80 }, nil, "") 81 c.Assert(err, IsNil) 82 s.decl1_1 = a.(*asserts.TestOnlyDecl) 83 84 a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{ 85 "id": "two", 86 "dev-id": "developer2", 87 }, nil, "") 88 c.Assert(err, IsNil) 89 s.decl2 = a.(*asserts.TestOnlyDecl) 90 91 a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{ 92 "h": "1111", 93 "id": "one", 94 "dev-id": "developer1", 95 }, nil, "") 96 c.Assert(err, IsNil) 97 s.rev1_1111 = a.(*asserts.TestOnlyRev) 98 99 a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{ 100 "h": "3333", 101 "id": "one", 102 "dev-id": "developer1", 103 }, nil, "") 104 c.Assert(err, IsNil) 105 s.rev1_3333 = a.(*asserts.TestOnlyRev) 106 107 a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{ 108 "h": "2222", 109 "id": "two", 110 "dev-id": "developer2", 111 }, nil, "") 112 c.Assert(err, IsNil) 113 s.rev2_2222 = a.(*asserts.TestOnlyRev) 114 115 // sequence-forming 116 117 a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{ 118 "n": "1111", 119 "sequence": "1", 120 "id": "one", 121 "dev-id": "developer1", 122 "revision": "5", 123 }, nil, "") 124 c.Assert(err, IsNil) 125 s.seq1_1111r5 = a.(*asserts.TestOnlySeq) 126 127 a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{ 128 "n": "1111", 129 "sequence": "1", 130 "id": "one", 131 "dev-id": "developer1", 132 "revision": "6", 133 }, nil, "") 134 c.Assert(err, IsNil) 135 s.seq1_1111r6 = a.(*asserts.TestOnlySeq) 136 137 a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{ 138 "n": "1111", 139 "sequence": "2", 140 "id": "one", 141 "dev-id": "developer1", 142 "revision": "7", 143 }, nil, "") 144 c.Assert(err, IsNil) 145 s.seq2_1111r7 = a.(*asserts.TestOnlySeq) 146 147 a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{ 148 "n": "1111", 149 "sequence": "3", 150 "id": "one", 151 "dev-id": "developer1", 152 "revision": "4", 153 }, nil, "") 154 c.Assert(err, IsNil) 155 s.seq3_1111r5 = a.(*asserts.TestOnlySeq) 156 157 db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ 158 Backstore: asserts.NewMemoryBackstore(), 159 Trusted: s.hub.Trusted, 160 }) 161 c.Assert(err, IsNil) 162 s.db = db 163 } 164 165 func (s *poolSuite) TestAddUnresolved(c *C) { 166 pool := asserts.NewPool(s.db, 64) 167 168 at1 := &asserts.AtRevision{ 169 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 170 Revision: asserts.RevisionNotKnown, 171 } 172 err := pool.AddUnresolved(at1, "for_one") // group num: 0 173 c.Assert(err, IsNil) 174 175 toResolve, toResolveSeq, err := pool.ToResolve() 176 c.Assert(err, IsNil) 177 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 178 asserts.MakePoolGrouping(0): {at1}, 179 }) 180 c.Check(toResolveSeq, HasLen, 0) 181 } 182 183 func (s *poolSuite) TestAddUnresolvedPredefined(c *C) { 184 pool := asserts.NewPool(s.db, 64) 185 186 at := s.hub.TrustedAccount.At() 187 at.Revision = asserts.RevisionNotKnown 188 err := pool.AddUnresolved(at, "for_one") 189 c.Assert(err, IsNil) 190 191 // nothing to resolve 192 toResolve, toResolveSeq, err := pool.ToResolve() 193 c.Assert(err, IsNil) 194 c.Check(toResolve, HasLen, 0) 195 c.Check(toResolveSeq, HasLen, 0) 196 } 197 198 func (s *poolSuite) TestAddUnresolvedGrouping(c *C) { 199 pool := asserts.NewPool(s.db, 64) 200 201 storeKeyAt := s.hub.StoreAccountKey("").At() 202 203 pool.AddUnresolved(storeKeyAt, "for_two") // group num: 0 204 pool.AddUnresolved(storeKeyAt, "for_one") // group num: 1 205 206 toResolve, toResolveSeq, err := pool.ToResolve() 207 c.Assert(err, IsNil) 208 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 209 asserts.MakePoolGrouping(0, 1): {storeKeyAt}, 210 }) 211 c.Check(toResolveSeq, HasLen, 0) 212 } 213 214 func (s *poolSuite) TestAddUnresolvedDup(c *C) { 215 pool := asserts.NewPool(s.db, 64) 216 217 storeKeyAt := s.hub.StoreAccountKey("").At() 218 219 pool.AddUnresolved(storeKeyAt, "for_one") // group num: 0 220 pool.AddUnresolved(storeKeyAt, "for_one") // group num: 0 221 222 toResolve, toResolveSeq, err := pool.ToResolve() 223 c.Assert(err, IsNil) 224 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 225 asserts.MakePoolGrouping(0): {storeKeyAt}, 226 }) 227 c.Check(toResolveSeq, HasLen, 0) 228 } 229 230 type byAtRevision []*asserts.AtRevision 231 232 func (ats byAtRevision) Len() int { 233 return len(ats) 234 } 235 236 func (ats byAtRevision) Less(i, j int) bool { 237 return ats[i].Ref.Unique() < ats[j].Ref.Unique() 238 } 239 240 func (ats byAtRevision) Swap(i, j int) { 241 ats[i], ats[j] = ats[j], ats[i] 242 } 243 244 func sortToResolve(toResolve map[asserts.Grouping][]*asserts.AtRevision) { 245 for _, ats := range toResolve { 246 sort.Sort(byAtRevision(ats)) 247 } 248 } 249 250 func (s *poolSuite) TestFetch(c *C) { 251 pool := asserts.NewPool(s.db, 64) 252 253 at1111 := &asserts.AtRevision{ 254 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 255 Revision: asserts.RevisionNotKnown, 256 } 257 err := pool.AddUnresolved(at1111, "for_one") 258 c.Assert(err, IsNil) 259 260 toResolve, toResolveSeq, err := pool.ToResolve() 261 c.Assert(err, IsNil) 262 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 263 asserts.MakePoolGrouping(0): {at1111}, 264 }) 265 c.Check(toResolveSeq, HasLen, 0) 266 267 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0)) 268 c.Assert(err, IsNil) 269 c.Assert(ok, Equals, true) 270 271 toResolve, toResolveSeq, err = pool.ToResolve() 272 c.Assert(err, IsNil) 273 sortToResolve(toResolve) 274 dev1AcctAt := s.dev1Acct.At() 275 dev1AcctAt.Revision = asserts.RevisionNotKnown 276 decl1At := s.decl1.At() 277 decl1At.Revision = asserts.RevisionNotKnown 278 storeKeyAt := s.hub.StoreAccountKey("").At() 279 storeKeyAt.Revision = asserts.RevisionNotKnown 280 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 281 asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt, decl1At}, 282 }) 283 c.Check(toResolveSeq, HasLen, 0) 284 285 c.Check(pool.Err("for_one"), IsNil) 286 } 287 288 func (s *poolSuite) TestFetchSequenceForming(c *C) { 289 pool := asserts.NewPool(s.db, 64) 290 291 // revision and sequence not set 292 atseq := &asserts.AtSequence{ 293 Type: asserts.TestOnlySeqType, 294 SequenceKey: []string{"1111"}, 295 Revision: asserts.RevisionNotKnown, 296 } 297 err := pool.AddUnresolvedSequence(atseq, "for_one") 298 c.Assert(err, IsNil) 299 300 toResolve, toResolveSeq, err := pool.ToResolve() 301 c.Assert(err, IsNil) 302 c.Check(toResolve, HasLen, 0) 303 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 304 asserts.MakePoolGrouping(0): {atseq}, 305 }) 306 307 // resolve 308 ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0)) 309 c.Assert(err, IsNil) 310 c.Assert(ok, Equals, true) 311 312 toResolve, toResolveSeq, err = pool.ToResolve() 313 c.Assert(err, IsNil) 314 315 storeKeyAt := s.hub.StoreAccountKey("").At() 316 storeKeyAt.Revision = asserts.RevisionNotKnown 317 c.Check(toResolveSeq, HasLen, 0) 318 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 319 asserts.MakePoolGrouping(0): {storeKeyAt}, 320 }) 321 322 ok, err = pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0)) 323 c.Assert(err, IsNil) 324 c.Assert(ok, Equals, true) 325 326 c.Check(pool.Err("for_one"), IsNil) 327 328 err = pool.CommitTo(s.db) 329 c.Check(err, IsNil) 330 c.Assert(pool.Err("for_one"), IsNil) 331 } 332 333 func (s *poolSuite) TestCompleteFetch(c *C) { 334 pool := asserts.NewPool(s.db, 64) 335 336 at1111 := &asserts.AtRevision{ 337 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 338 Revision: asserts.RevisionNotKnown, 339 } 340 err := pool.AddUnresolved(at1111, "for_one") 341 c.Assert(err, IsNil) 342 343 toResolve, toResolveSeq, err := pool.ToResolve() 344 c.Assert(err, IsNil) 345 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 346 asserts.MakePoolGrouping(0): {at1111}, 347 }) 348 c.Check(toResolveSeq, HasLen, 0) 349 350 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0)) 351 c.Assert(err, IsNil) 352 c.Assert(ok, Equals, true) 353 354 toResolve, toResolveSeq, err = pool.ToResolve() 355 c.Assert(err, IsNil) 356 sortToResolve(toResolve) 357 dev1AcctAt := s.dev1Acct.At() 358 dev1AcctAt.Revision = asserts.RevisionNotKnown 359 decl1At := s.decl1.At() 360 decl1At.Revision = asserts.RevisionNotKnown 361 storeKey := s.hub.StoreAccountKey("") 362 storeKeyAt := storeKey.At() 363 storeKeyAt.Revision = asserts.RevisionNotKnown 364 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 365 asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt, decl1At}, 366 }) 367 c.Check(toResolveSeq, HasLen, 0) 368 369 b := asserts.NewBatch(nil) 370 err = b.Add(s.decl1) 371 c.Assert(err, IsNil) 372 err = b.Add(storeKey) 373 c.Assert(err, IsNil) 374 err = b.Add(s.dev1Acct) 375 c.Assert(err, IsNil) 376 377 ok, err = pool.AddBatch(b, asserts.MakePoolGrouping(0)) 378 c.Assert(err, IsNil) 379 c.Assert(ok, Equals, true) 380 381 toResolve, toResolveSeq, err = pool.ToResolve() 382 c.Assert(err, IsNil) 383 c.Check(toResolve, HasLen, 0) 384 c.Check(toResolveSeq, HasLen, 0) 385 386 c.Check(pool.Err("for_one"), IsNil) 387 388 err = pool.CommitTo(s.db) 389 c.Check(err, IsNil) 390 c.Assert(pool.Err("for_one"), IsNil) 391 392 a, err := at1111.Ref.Resolve(s.db.Find) 393 c.Assert(err, IsNil) 394 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111") 395 } 396 397 func (s *poolSuite) TestPushSuggestionForPrerequisite(c *C) { 398 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 399 400 pool := asserts.NewPool(s.db, 64) 401 402 at1111 := &asserts.AtRevision{ 403 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 404 Revision: asserts.RevisionNotKnown, 405 } 406 err := pool.AddUnresolved(at1111, "for_one") 407 c.Assert(err, IsNil) 408 409 toResolve, toResolveSeq, err := pool.ToResolve() 410 c.Assert(err, IsNil) 411 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 412 asserts.MakePoolGrouping(0): {at1111}, 413 }) 414 c.Check(toResolveSeq, HasLen, 0) 415 416 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0)) 417 c.Assert(err, IsNil) 418 c.Assert(ok, Equals, true) 419 420 // push prerequisite suggestion 421 ok, err = pool.Add(s.decl1, asserts.MakePoolGrouping(0)) 422 c.Assert(err, IsNil) 423 c.Assert(ok, Equals, true) 424 425 toResolve, toResolveSeq, err = pool.ToResolve() 426 c.Assert(err, IsNil) 427 sortToResolve(toResolve) 428 dev1AcctAt := s.dev1Acct.At() 429 dev1AcctAt.Revision = asserts.RevisionNotKnown 430 storeKey := s.hub.StoreAccountKey("") 431 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 432 asserts.MakePoolGrouping(0): {storeKey.At(), dev1AcctAt}, 433 }) 434 c.Check(toResolveSeq, HasLen, 0) 435 436 c.Check(pool.Err("for_one"), IsNil) 437 438 ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0)) 439 c.Assert(err, IsNil) 440 c.Assert(ok, Equals, true) 441 442 toResolve, toResolveSeq, err = pool.ToResolve() 443 c.Assert(err, IsNil) 444 c.Check(toResolve, HasLen, 0) 445 c.Check(toResolveSeq, HasLen, 0) 446 447 c.Check(pool.Err("for_one"), IsNil) 448 449 err = pool.CommitTo(s.db) 450 c.Check(err, IsNil) 451 c.Assert(pool.Err("for_one"), IsNil) 452 453 a, err := at1111.Ref.Resolve(s.db.Find) 454 c.Assert(err, IsNil) 455 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111") 456 } 457 458 func (s *poolSuite) TestPushSuggestionForNew(c *C) { 459 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 460 461 pool := asserts.NewPool(s.db, 64) 462 463 atOne := &asserts.AtRevision{ 464 Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}}, 465 Revision: asserts.RevisionNotKnown, 466 } 467 err := pool.AddUnresolved(atOne, "for_one") 468 c.Assert(err, IsNil) 469 470 toResolve, toResolveSeq, err := pool.ToResolve() 471 c.Assert(err, IsNil) 472 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 473 asserts.MakePoolGrouping(0): {atOne}, 474 }) 475 c.Check(toResolveSeq, HasLen, 0) 476 477 ok, err := pool.Add(s.decl1, asserts.MakePoolGrouping(0)) 478 c.Assert(err, IsNil) 479 c.Assert(ok, Equals, true) 480 481 // new push suggestion 482 ok, err = pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0)) 483 c.Assert(err, IsNil) 484 c.Assert(ok, Equals, true) 485 486 toResolve, toResolveSeq, err = pool.ToResolve() 487 c.Assert(err, IsNil) 488 sortToResolve(toResolve) 489 dev1AcctAt := s.dev1Acct.At() 490 dev1AcctAt.Revision = asserts.RevisionNotKnown 491 storeKeyAt := s.hub.StoreAccountKey("").At() 492 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 493 asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt}, 494 }) 495 c.Check(toResolveSeq, HasLen, 0) 496 497 c.Check(pool.Err("for_one"), IsNil) 498 499 ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0)) 500 c.Assert(err, IsNil) 501 c.Assert(ok, Equals, true) 502 503 toResolve, toResolveSeq, err = pool.ToResolve() 504 c.Assert(err, IsNil) 505 c.Check(toResolve, HasLen, 0) 506 c.Check(toResolveSeq, HasLen, 0) 507 508 c.Check(pool.Err("for_one"), IsNil) 509 510 err = pool.CommitTo(s.db) 511 c.Check(err, IsNil) 512 c.Assert(pool.Err("for_one"), IsNil) 513 514 a, err := s.rev1_1111.Ref().Resolve(s.db.Find) 515 c.Assert(err, IsNil) 516 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111") 517 } 518 519 func (s *poolSuite) TestPushSuggestionForNewSeqForming(c *C) { 520 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 521 522 pool := asserts.NewPool(s.db, 64) 523 524 atOne := &asserts.AtSequence{ 525 Type: asserts.TestOnlySeqType, 526 SequenceKey: []string{"1111"}, 527 Revision: asserts.RevisionNotKnown, 528 } 529 err := pool.AddUnresolvedSequence(atOne, "for_one") 530 c.Assert(err, IsNil) 531 532 toResolve, toResolveSeq, err := pool.ToResolve() 533 c.Assert(err, IsNil) 534 c.Check(toResolve, HasLen, 0) 535 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 536 asserts.MakePoolGrouping(0): {atOne}, 537 }) 538 539 ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0)) 540 c.Assert(err, IsNil) 541 c.Assert(ok, Equals, true) 542 543 // new push suggestion 544 ok, err = pool.Add(s.seq2_1111r7, asserts.MakePoolGrouping(0)) 545 c.Assert(err, IsNil) 546 c.Assert(ok, Equals, true) 547 548 toResolve, toResolveSeq, err = pool.ToResolve() 549 c.Assert(err, IsNil) 550 sortToResolve(toResolve) 551 dev1AcctAt := s.dev1Acct.At() 552 dev1AcctAt.Revision = asserts.RevisionNotKnown 553 554 c.Check(toResolve, HasLen, 1) 555 c.Check(toResolveSeq, HasLen, 0) 556 557 c.Check(pool.Err("for_one"), IsNil) 558 559 err = pool.CommitTo(s.db) 560 c.Check(err, IsNil) 561 c.Assert(pool.Err("for_one"), IsNil) 562 563 a, err := s.seq2_1111r7.Ref().Resolve(s.db.Find) 564 c.Assert(err, IsNil) 565 c.Check(a.(*asserts.TestOnlySeq).N(), Equals, "1111") 566 c.Check(a.Revision(), Equals, 7) 567 } 568 569 func (s *poolSuite) TestPushSuggestionForNewViaBatch(c *C) { 570 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 571 572 pool := asserts.NewPool(s.db, 64) 573 574 atOne := &asserts.AtRevision{ 575 Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}}, 576 Revision: asserts.RevisionNotKnown, 577 } 578 err := pool.AddUnresolved(atOne, "for_one") 579 c.Assert(err, IsNil) 580 581 toResolve, toResolveSeq, err := pool.ToResolve() 582 c.Assert(err, IsNil) 583 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 584 asserts.MakePoolGrouping(0): {atOne}, 585 }) 586 c.Check(toResolveSeq, HasLen, 0) 587 588 b := asserts.NewBatch(nil) 589 err = b.Add(s.decl1) 590 c.Assert(err, IsNil) 591 592 // new push suggestions 593 err = b.Add(s.rev1_1111) 594 c.Assert(err, IsNil) 595 err = b.Add(s.rev1_3333) 596 c.Assert(err, IsNil) 597 598 ok, err := pool.AddBatch(b, asserts.MakePoolGrouping(0)) 599 c.Assert(err, IsNil) 600 c.Assert(ok, Equals, true) 601 602 toResolve, toResolveSeq, err = pool.ToResolve() 603 c.Assert(err, IsNil) 604 sortToResolve(toResolve) 605 dev1AcctAt := s.dev1Acct.At() 606 dev1AcctAt.Revision = asserts.RevisionNotKnown 607 storeKeyAt := s.hub.StoreAccountKey("").At() 608 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 609 asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt}, 610 }) 611 c.Check(toResolveSeq, HasLen, 0) 612 613 c.Check(pool.Err("for_one"), IsNil) 614 615 ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0)) 616 c.Assert(err, IsNil) 617 c.Assert(ok, Equals, true) 618 619 toResolve, toResolveSeq, err = pool.ToResolve() 620 c.Assert(err, IsNil) 621 c.Check(toResolve, HasLen, 0) 622 c.Check(toResolveSeq, HasLen, 0) 623 624 c.Check(pool.Err("for_one"), IsNil) 625 626 err = pool.CommitTo(s.db) 627 c.Check(err, IsNil) 628 c.Assert(pool.Err("for_one"), IsNil) 629 630 a, err := s.rev1_1111.Ref().Resolve(s.db.Find) 631 c.Assert(err, IsNil) 632 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111") 633 634 a, err = s.rev1_3333.Ref().Resolve(s.db.Find) 635 c.Assert(err, IsNil) 636 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "3333") 637 } 638 639 func (s *poolSuite) TestAddUnresolvedUnresolved(c *C) { 640 pool := asserts.NewPool(s.db, 64) 641 642 at1 := &asserts.AtRevision{ 643 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 644 Revision: asserts.RevisionNotKnown, 645 } 646 err := pool.AddUnresolved(at1, "for_one") 647 c.Assert(err, IsNil) 648 649 toResolve, toResolveSeq, err := pool.ToResolve() 650 c.Assert(err, IsNil) 651 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 652 asserts.MakePoolGrouping(0): {at1}, 653 }) 654 c.Check(toResolveSeq, HasLen, 0) 655 656 toResolve, toResolveSeq, err = pool.ToResolve() 657 c.Assert(err, IsNil) 658 c.Check(toResolve, HasLen, 0) 659 c.Check(toResolveSeq, HasLen, 0) 660 661 c.Check(pool.Err("for_one"), Equals, asserts.ErrUnresolved) 662 } 663 664 func (s *poolSuite) TestAddFormatTooNew(c *C) { 665 pool := asserts.NewPool(s.db, 64) 666 667 _, _, err := pool.ToResolve() 668 c.Assert(err, IsNil) 669 670 var a asserts.Assertion 671 (func() { 672 restore := asserts.MockMaxSupportedFormat(asserts.TestOnlyDeclType, 2) 673 defer restore() 674 675 a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{ 676 "id": "three", 677 "dev-id": "developer1", 678 "format": "2", 679 }, nil, "") 680 c.Assert(err, IsNil) 681 })() 682 683 gSuggestion, err := pool.Singleton("suggestion") 684 c.Assert(err, IsNil) 685 686 ok, err := pool.Add(a, gSuggestion) 687 c.Check(err, IsNil) 688 c.Check(ok, Equals, false) 689 c.Assert(pool.Err("suggestion"), ErrorMatches, `proposed "test-only-decl" assertion has format 2 but 0 is latest supported`) 690 } 691 692 func (s *poolSuite) TestAddOlderIgnored(c *C) { 693 pool := asserts.NewPool(s.db, 64) 694 695 _, _, err := pool.ToResolve() 696 c.Assert(err, IsNil) 697 698 gSuggestion, err := pool.Singleton("suggestion") 699 c.Assert(err, IsNil) 700 701 ok, err := pool.Add(s.decl1_1, gSuggestion) 702 c.Assert(err, IsNil) 703 c.Assert(ok, Equals, true) 704 705 ok, err = pool.Add(s.decl1, gSuggestion) 706 c.Assert(err, IsNil) 707 c.Assert(ok, Equals, true) 708 709 toResolve, toResolveSeq, err := pool.ToResolve() 710 c.Assert(err, IsNil) 711 sortToResolve(toResolve) 712 dev1AcctAt := s.dev1Acct.At() 713 dev1AcctAt.Revision = asserts.RevisionNotKnown 714 storeKeyAt := s.hub.StoreAccountKey("").At() 715 storeKeyAt.Revision = asserts.RevisionNotKnown 716 717 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 718 gSuggestion: {storeKeyAt, dev1AcctAt}, 719 }) 720 c.Check(toResolveSeq, HasLen, 0) 721 } 722 723 func (s *poolSuite) TestUnknownGroup(c *C) { 724 pool := asserts.NewPool(s.db, 64) 725 726 _, err := pool.Singleton("suggestion") 727 c.Assert(err, IsNil) 728 // sanity 729 c.Check(pool.Err("suggestion"), IsNil) 730 731 c.Check(pool.Err("foo"), Equals, asserts.ErrUnknownPoolGroup) 732 } 733 734 func (s *poolSuite) TestAddCurrentRevision(c *C) { 735 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct, s.decl1) 736 737 pool := asserts.NewPool(s.db, 64) 738 739 atDev1Acct := s.dev1Acct.At() 740 atDev1Acct.Revision = asserts.RevisionNotKnown 741 err := pool.AddUnresolved(atDev1Acct, "one") 742 c.Assert(err, IsNil) 743 744 atDecl1 := s.decl1.At() 745 atDecl1.Revision = asserts.RevisionNotKnown 746 err = pool.AddUnresolved(atDecl1, "one") 747 c.Assert(err, IsNil) 748 749 toResolve, toResolveSeq, err := pool.ToResolve() 750 c.Assert(err, IsNil) 751 sortToResolve(toResolve) 752 753 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 754 asserts.MakePoolGrouping(0): {s.dev1Acct.At(), s.decl1.At()}, 755 }) 756 c.Check(toResolveSeq, HasLen, 0) 757 758 // re-adding of current revisions, is not what we expect 759 // but needs to not produce unnecessary roundtrips 760 761 ok, err := pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0)) 762 c.Assert(err, IsNil) 763 c.Assert(ok, Equals, true) 764 765 // this will be kept marked as unresolved until the ToResolve 766 ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0)) 767 c.Assert(err, IsNil) 768 c.Assert(ok, Equals, true) 769 770 ok, err = pool.Add(s.decl1_1, asserts.MakePoolGrouping(0)) 771 c.Assert(err, IsNil) 772 c.Assert(ok, Equals, true) 773 774 toResolve, toResolveSeq, err = pool.ToResolve() 775 c.Assert(err, IsNil) 776 c.Assert(toResolve, HasLen, 0) 777 c.Assert(toResolveSeq, HasLen, 0) 778 779 c.Check(pool.Err("one"), IsNil) 780 } 781 782 func (s *poolSuite) TestAddCurrentRevisionSeqForming(c *C) { 783 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct, s.decl1) 784 785 pool := asserts.NewPool(s.db, 64) 786 787 atSeq := &asserts.AtSequence{ 788 Type: asserts.TestOnlySeqType, 789 SequenceKey: []string{"1111"}, 790 Revision: asserts.RevisionNotKnown, 791 } 792 err := pool.AddUnresolvedSequence(atSeq, "one") 793 c.Assert(err, IsNil) 794 795 toResolve, toResolveSeq, err := pool.ToResolve() 796 c.Assert(err, IsNil) 797 798 c.Check(toResolve, HasLen, 0) 799 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 800 asserts.MakePoolGrouping(0): { 801 &asserts.AtSequence{ 802 Type: s.seq1_1111r5.Type(), 803 SequenceKey: []string{"1111"}, 804 Revision: asserts.RevisionNotKnown, 805 }}, 806 }) 807 808 // re-adding of current revisions, is not what we expect 809 // but needs to not produce unnecessary roundtrips 810 811 ok, err := pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0)) 812 c.Assert(err, IsNil) 813 c.Assert(ok, Equals, true) 814 815 // this will be kept marked as unresolved until the ToResolve 816 ok, err = pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0)) 817 c.Assert(err, IsNil) 818 c.Assert(ok, Equals, true) 819 820 toResolve, toResolveSeq, err = pool.ToResolve() 821 c.Assert(err, IsNil) 822 c.Assert(toResolve, HasLen, 0) 823 c.Assert(toResolveSeq, HasLen, 0) 824 825 c.Check(pool.Err("one"), IsNil) 826 } 827 828 func (s *poolSuite) TestUpdate(c *C) { 829 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 830 assertstest.AddMany(s.db, s.dev1Acct, s.decl1, s.rev1_1111) 831 assertstest.AddMany(s.db, s.dev2Acct, s.decl2, s.rev2_2222) 832 833 pool := asserts.NewPool(s.db, 64) 834 835 err := pool.AddToUpdate(s.decl1.Ref(), "for_one") // group num: 0 836 c.Assert(err, IsNil) 837 err = pool.AddToUpdate(s.decl2.Ref(), "for_two") // group num: 1 838 c.Assert(err, IsNil) 839 840 storeKeyAt := s.hub.StoreAccountKey("").At() 841 842 toResolve, toResolveSeq, err := pool.ToResolve() 843 c.Assert(err, IsNil) 844 sortToResolve(toResolve) 845 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 846 asserts.MakePoolGrouping(0, 1): {storeKeyAt}, 847 asserts.MakePoolGrouping(0): {s.dev1Acct.At(), s.decl1.At()}, 848 asserts.MakePoolGrouping(1): {s.dev2Acct.At(), s.decl2.At()}, 849 }) 850 c.Check(toResolveSeq, HasLen, 0) 851 852 ok, err := pool.Add(s.decl1_1, asserts.MakePoolGrouping(0)) 853 c.Assert(err, IsNil) 854 c.Assert(ok, Equals, true) 855 856 toResolve, toResolveSeq, err = pool.ToResolve() 857 c.Assert(err, IsNil) 858 c.Check(toResolve, HasLen, 0) 859 c.Check(toResolveSeq, HasLen, 0) 860 861 at2222 := &asserts.AtRevision{ 862 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"2222"}}, 863 Revision: asserts.RevisionNotKnown, 864 } 865 err = pool.AddUnresolved(at2222, "for_two") 866 c.Assert(err, IsNil) 867 868 toResolve, toResolveSeq, err = pool.ToResolve() 869 c.Assert(err, IsNil) 870 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 871 asserts.MakePoolGrouping(1): {&asserts.AtRevision{ 872 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"2222"}}, 873 Revision: 0, 874 }}, 875 }) 876 c.Check(toResolveSeq, HasLen, 0) 877 878 c.Check(pool.Err("for_one"), IsNil) 879 c.Check(pool.Err("for_two"), IsNil) 880 } 881 882 func (s *poolSuite) TestUpdateSeqFormingUnpinnedNewerSequence(c *C) { 883 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 884 885 pool := asserts.NewPool(s.db, 64) 886 887 atseq := &asserts.AtSequence{ 888 Type: s.seq1_1111r5.Type(), 889 SequenceKey: []string{"1111"}, 890 Sequence: 1, 891 Revision: 5, 892 } 893 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 894 c.Assert(err, IsNil) 895 896 toResolve, toResolveSeq, err := pool.ToResolve() 897 c.Assert(err, IsNil) 898 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 899 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 900 }) 901 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 902 asserts.MakePoolGrouping(0): { 903 &asserts.AtSequence{ 904 Type: s.seq1_1111r5.Type(), 905 SequenceKey: []string{"1111"}, 906 Sequence: 1, 907 Revision: 5, 908 }}, 909 }) 910 911 c.Check(pool.Err("for_one"), IsNil) 912 913 // resolve with sequence 3 914 ok, err := pool.Add(s.seq3_1111r5, asserts.MakePoolGrouping(0)) 915 c.Assert(err, IsNil) 916 c.Assert(ok, Equals, true) 917 918 toResolve, toResolveSeq, err = pool.ToResolve() 919 c.Assert(err, IsNil) 920 921 c.Check(toResolve, HasLen, 0) 922 c.Check(toResolveSeq, HasLen, 0) 923 c.Check(pool.Err("for_one"), IsNil) 924 925 err = pool.CommitTo(s.db) 926 c.Check(err, IsNil) 927 c.Assert(pool.Err("for_one"), IsNil) 928 929 // sequence point 1, revision 5 is still in the db. 930 _, err = s.seq1_1111r5.Ref().Resolve(s.db.Find) 931 c.Assert(err, IsNil) 932 933 // and sequence point 3 revision 5 is in the database. 934 _, err = s.seq3_1111r5.Ref().Resolve(s.db.Find) 935 c.Assert(err, IsNil) 936 } 937 938 func (s *poolSuite) TestUpdateSeqFormingUnpinnedSameSequenceNewerRev(c *C) { 939 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 940 941 pool := asserts.NewPool(s.db, 64) 942 943 atseq := &asserts.AtSequence{ 944 Type: s.seq1_1111r5.Type(), 945 SequenceKey: []string{"1111"}, 946 Sequence: 1, 947 Revision: 5, 948 } 949 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 950 c.Assert(err, IsNil) 951 952 toResolve, toResolveSeq, err := pool.ToResolve() 953 c.Assert(err, IsNil) 954 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 955 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 956 }) 957 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 958 asserts.MakePoolGrouping(0): { 959 &asserts.AtSequence{ 960 Type: s.seq1_1111r5.Type(), 961 SequenceKey: []string{"1111"}, 962 Sequence: 1, 963 Revision: 5, 964 }}, 965 }) 966 967 c.Check(pool.Err("for_one"), IsNil) 968 969 // resolve 970 ok, err := pool.Add(s.seq1_1111r6, asserts.MakePoolGrouping(0)) 971 c.Assert(err, IsNil) 972 c.Assert(ok, Equals, true) 973 974 toResolve, toResolveSeq, err = pool.ToResolve() 975 c.Assert(err, IsNil) 976 977 c.Check(toResolve, HasLen, 0) 978 c.Check(toResolveSeq, HasLen, 0) 979 c.Check(pool.Err("for_one"), IsNil) 980 981 err = pool.CommitTo(s.db) 982 c.Check(err, IsNil) 983 c.Assert(pool.Err("for_one"), IsNil) 984 985 // sequence point 1, revision 5 is still in the database. 986 _, err = s.seq1_1111r5.Ref().Resolve(s.db.Find) 987 c.Assert(err, IsNil) 988 989 // and sequence point 1 revision 6 is in the database. 990 _, err = s.seq1_1111r6.Ref().Resolve(s.db.Find) 991 c.Assert(err, IsNil) 992 } 993 994 func (s *poolSuite) TestUpdateSeqFormingUnpinnedSameSequenceSameRevNoop(c *C) { 995 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 996 997 pool := asserts.NewPool(s.db, 64) 998 999 atseq := &asserts.AtSequence{ 1000 Type: s.seq1_1111r5.Type(), 1001 SequenceKey: []string{"1111"}, 1002 Sequence: 1, 1003 Revision: 5, 1004 } 1005 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 1006 c.Assert(err, IsNil) 1007 1008 toResolve, toResolveSeq, err := pool.ToResolve() 1009 c.Assert(err, IsNil) 1010 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1011 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 1012 }) 1013 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1014 asserts.MakePoolGrouping(0): { 1015 &asserts.AtSequence{ 1016 Type: s.seq1_1111r5.Type(), 1017 SequenceKey: []string{"1111"}, 1018 Sequence: 1, 1019 Revision: 5, 1020 }}, 1021 }) 1022 1023 c.Check(pool.Err("for_one"), IsNil) 1024 1025 // update with same assertion 1026 ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0)) 1027 c.Assert(err, IsNil) 1028 c.Assert(ok, Equals, true) 1029 1030 toResolve, toResolveSeq, err = pool.ToResolve() 1031 c.Assert(err, IsNil) 1032 c.Check(toResolve, HasLen, 0) 1033 c.Check(toResolveSeq, HasLen, 0) 1034 c.Check(pool.Err("for_one"), IsNil) 1035 1036 err = pool.CommitTo(s.db) 1037 c.Check(err, IsNil) 1038 c.Assert(pool.Err("for_one"), IsNil) 1039 1040 // sequence point 1, revision 5 is still in the database. 1041 _, err = s.seq1_1111r5.Ref().Resolve(s.db.Find) 1042 c.Assert(err, IsNil) 1043 } 1044 1045 func (s *poolSuite) TestUpdateSeqFormingPinnedNewerSequenceSameRevisionNoop(c *C) { 1046 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 1047 1048 pool := asserts.NewPool(s.db, 64) 1049 1050 atseq := &asserts.AtSequence{ 1051 Type: s.seq1_1111r5.Type(), 1052 SequenceKey: []string{"1111"}, 1053 Sequence: 1, 1054 Revision: 5, 1055 Pinned: true, 1056 } 1057 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 1058 c.Assert(err, IsNil) 1059 1060 toResolve, toResolveSeq, err := pool.ToResolve() 1061 c.Assert(err, IsNil) 1062 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1063 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 1064 }) 1065 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1066 asserts.MakePoolGrouping(0): { 1067 &asserts.AtSequence{ 1068 Type: s.seq1_1111r5.Type(), 1069 SequenceKey: []string{"1111"}, 1070 Sequence: 1, 1071 Revision: 5, 1072 Pinned: true, 1073 }}, 1074 }) 1075 1076 c.Check(pool.Err("for_one"), IsNil) 1077 1078 // resolve 1079 ok, err := pool.Add(s.seq3_1111r5, asserts.MakePoolGrouping(0)) 1080 c.Assert(err, IsNil) 1081 c.Assert(ok, Equals, true) 1082 1083 toResolve, toResolveSeq, err = pool.ToResolve() 1084 c.Assert(err, IsNil) 1085 c.Check(toResolve, HasLen, 0) 1086 c.Check(toResolveSeq, HasLen, 0) 1087 c.Check(pool.Err("for_one"), IsNil) 1088 1089 err = pool.CommitTo(s.db) 1090 c.Check(err, IsNil) 1091 c.Assert(pool.Err("for_one"), IsNil) 1092 1093 // sequence point 1, revision 5 is still the latest. 1094 _, err = s.seq1_1111r5.Ref().Resolve(s.db.Find) 1095 c.Assert(err, IsNil) 1096 1097 // and sequence point 3 revision 5 wasn't added to asserts database. 1098 _, err = s.seq3_1111r5.Ref().Resolve(s.db.Find) 1099 c.Assert(asserts.IsNotFound(err), Equals, true) 1100 } 1101 1102 func (s *poolSuite) TestUpdateSeqFormingPinnedNewerSequenceNewerRevisionNoop(c *C) { 1103 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 1104 1105 pool := asserts.NewPool(s.db, 64) 1106 1107 atseq := &asserts.AtSequence{ 1108 Type: s.seq1_1111r5.Type(), 1109 SequenceKey: []string{"1111"}, 1110 Sequence: 1, 1111 Revision: 5, 1112 Pinned: true, 1113 } 1114 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 1115 c.Assert(err, IsNil) 1116 1117 toResolve, toResolveSeq, err := pool.ToResolve() 1118 c.Assert(err, IsNil) 1119 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1120 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 1121 }) 1122 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1123 asserts.MakePoolGrouping(0): { 1124 &asserts.AtSequence{ 1125 Type: s.seq1_1111r5.Type(), 1126 SequenceKey: []string{"1111"}, 1127 Sequence: 1, 1128 Revision: 5, 1129 Pinned: true, 1130 }}, 1131 }) 1132 1133 c.Check(pool.Err("for_one"), IsNil) 1134 1135 // resolve 1136 ok, err := pool.Add(s.seq2_1111r7, asserts.MakePoolGrouping(0)) 1137 c.Assert(err, IsNil) 1138 c.Assert(ok, Equals, true) 1139 1140 err = pool.CommitTo(s.db) 1141 c.Check(err, IsNil) 1142 c.Assert(pool.Err("for_one"), IsNil) 1143 1144 // sequence point 1, revision 5 is still the latest. 1145 _, err = s.seq1_1111r5.Ref().Resolve(s.db.Find) 1146 c.Assert(err, IsNil) 1147 1148 // and sequence point 2 revision 7 wasn't added to asserts database. 1149 _, err = s.seq2_1111r7.Ref().Resolve(s.db.Find) 1150 c.Assert(asserts.IsNotFound(err), Equals, true) 1151 } 1152 1153 func (s *poolSuite) TestUpdateSeqFormingPinnedSameSequenceNewerRevision(c *C) { 1154 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 1155 pool := asserts.NewPool(s.db, 64) 1156 1157 atseq := &asserts.AtSequence{ 1158 Type: s.seq1_1111r5.Type(), 1159 SequenceKey: []string{"1111"}, 1160 Sequence: 1, 1161 Revision: 5, 1162 Pinned: true, 1163 } 1164 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 1165 c.Assert(err, IsNil) 1166 1167 toResolve, toResolveSeq, err := pool.ToResolve() 1168 c.Assert(err, IsNil) 1169 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1170 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 1171 }) 1172 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1173 asserts.MakePoolGrouping(0): { 1174 &asserts.AtSequence{ 1175 Type: s.seq1_1111r5.Type(), 1176 SequenceKey: []string{"1111"}, 1177 Sequence: 1, 1178 Revision: 5, 1179 Pinned: true, 1180 }}, 1181 }) 1182 1183 c.Check(pool.Err("for_one"), IsNil) 1184 1185 // resolve 1186 ok, err := pool.Add(s.seq1_1111r6, asserts.MakePoolGrouping(0)) 1187 c.Assert(err, IsNil) 1188 c.Assert(ok, Equals, true) 1189 1190 err = pool.CommitTo(s.db) 1191 c.Check(err, IsNil) 1192 c.Assert(pool.Err("for_one"), IsNil) 1193 1194 // sequence point 1, revision 6 is in db. 1195 _, err = s.seq1_1111r6.Ref().Resolve(s.db.Find) 1196 c.Assert(err, IsNil) 1197 } 1198 1199 func (s *poolSuite) TestUpdateSeqFormingUseAssertRevision(c *C) { 1200 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 1201 1202 pool := asserts.NewPool(s.db, 64) 1203 1204 atseq := &asserts.AtSequence{ 1205 Type: s.seq1_1111r5.Type(), 1206 SequenceKey: []string{"1111"}, 1207 Sequence: 1, 1208 Revision: 0, // intentionaly unset 1209 } 1210 err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0 1211 c.Assert(err, IsNil) 1212 1213 toResolve, toResolveSeq, err := pool.ToResolve() 1214 c.Assert(err, IsNil) 1215 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1216 asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()}, 1217 }) 1218 1219 // verify that revision number from the existing assertion to update was used. 1220 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1221 asserts.MakePoolGrouping(0): { 1222 &asserts.AtSequence{ 1223 Type: s.seq1_1111r5.Type(), 1224 SequenceKey: []string{"1111"}, 1225 Sequence: 1, 1226 Revision: 5, 1227 }}, 1228 }) 1229 } 1230 1231 func (s *poolSuite) TestAddSequenceToUpdateMissingSequenceError(c *C) { 1232 pool := asserts.NewPool(s.db, 64) 1233 atseq := &asserts.AtSequence{ 1234 Type: s.seq1_1111r5.Type(), 1235 SequenceKey: []string{"1111"}, 1236 Revision: asserts.RevisionNotKnown, 1237 } 1238 err := pool.AddSequenceToUpdate(atseq, "for_one") 1239 c.Assert(err, ErrorMatches, `internal error: sequence to update must have a sequence number set`) 1240 } 1241 1242 func (s *poolSuite) TestAddUnresolvedSeqUnresolved(c *C) { 1243 pool := asserts.NewPool(s.db, 64) 1244 1245 atseq := &asserts.AtSequence{ 1246 Type: s.seq1_1111r5.Type(), 1247 SequenceKey: []string{"1111"}, 1248 Revision: asserts.RevisionNotKnown, 1249 Sequence: 1, 1250 } 1251 err := pool.AddUnresolvedSequence(atseq, "for_one") 1252 c.Assert(err, IsNil) 1253 1254 toResolve, toResolveSeq, err := pool.ToResolve() 1255 c.Assert(err, IsNil) 1256 c.Check(toResolve, HasLen, 0) 1257 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1258 asserts.MakePoolGrouping(0): { 1259 &asserts.AtSequence{ 1260 Type: s.seq1_1111r5.Type(), 1261 SequenceKey: []string{"1111"}, 1262 Revision: asserts.RevisionNotKnown, 1263 Sequence: 1, 1264 }}, 1265 }) 1266 1267 toResolve, toResolveSeq, err = pool.ToResolve() 1268 c.Assert(err, IsNil) 1269 c.Check(toResolve, HasLen, 0) 1270 c.Check(toResolveSeq, HasLen, 0) 1271 1272 c.Check(pool.Err("for_one"), Equals, asserts.ErrUnresolved) 1273 } 1274 1275 func (s *poolSuite) TestAddUnresolvedSeqOnce(c *C) { 1276 pool := asserts.NewPool(s.db, 64) 1277 1278 atseq := &asserts.AtSequence{ 1279 Type: s.seq1_1111r5.Type(), 1280 SequenceKey: []string{"1111"}, 1281 Revision: asserts.RevisionNotKnown, 1282 Sequence: 1, 1283 } 1284 err := pool.AddUnresolvedSequence(atseq, "for_one") 1285 c.Assert(err, IsNil) 1286 1287 atseq.Sequence = 2 1288 atseq.Revision = 3 1289 err = pool.AddUnresolvedSequence(atseq, "for_one") 1290 c.Assert(err, ErrorMatches, `internal error: sequence \[1111\] is already being resolved`) 1291 } 1292 1293 func (s *poolSuite) TestAddSeqToUpdateOnce(c *C) { 1294 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5) 1295 pool := asserts.NewPool(s.db, 64) 1296 1297 atseq := &asserts.AtSequence{ 1298 Type: s.seq1_1111r5.Type(), 1299 SequenceKey: []string{"1111"}, 1300 Revision: 2, 1301 Sequence: 1, 1302 } 1303 err := pool.AddSequenceToUpdate(atseq, "for_one") 1304 c.Assert(err, IsNil) 1305 1306 atseq.Sequence = 3 1307 atseq.Revision = 3 1308 err = pool.AddSequenceToUpdate(atseq, "for_one") 1309 c.Assert(err, ErrorMatches, `internal error: sequence \[1111\] is already being resolved`) 1310 } 1311 1312 func (s *poolSuite) TestAddSeqToUpdateNotFound(c *C) { 1313 pool := asserts.NewPool(s.db, 64) 1314 1315 atseq := &asserts.AtSequence{ 1316 Type: s.seq1_1111r5.Type(), 1317 SequenceKey: []string{"1111"}, 1318 Revision: 2, 1319 Sequence: 1, 1320 } 1321 err := pool.AddSequenceToUpdate(atseq, "for_one") 1322 c.Assert(asserts.IsNotFound(err), Equals, true) 1323 } 1324 1325 var errBoom = errors.New("boom") 1326 1327 func (s *poolSuite) TestAddErrorEarly(c *C) { 1328 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1329 1330 pool := asserts.NewPool(s.db, 64) 1331 1332 storeKey := s.hub.StoreAccountKey("") 1333 err := pool.AddToUpdate(storeKey.Ref(), "store_key") 1334 c.Assert(err, IsNil) 1335 1336 at1111 := &asserts.AtRevision{ 1337 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 1338 Revision: asserts.RevisionNotKnown, 1339 } 1340 err = pool.AddUnresolved(at1111, "for_one") 1341 c.Assert(err, IsNil) 1342 1343 seq1111 := &asserts.AtSequence{ 1344 Type: asserts.TestOnlySeqType, 1345 SequenceKey: []string{"1111"}, 1346 Revision: asserts.RevisionNotKnown, 1347 } 1348 err = pool.AddUnresolvedSequence(seq1111, "for_two") 1349 c.Assert(err, IsNil) 1350 1351 toResolve, toResolveSeq, err := pool.ToResolve() 1352 c.Assert(err, IsNil) 1353 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1354 asserts.MakePoolGrouping(0): {storeKey.At()}, 1355 asserts.MakePoolGrouping(1): {at1111}, 1356 }) 1357 c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{ 1358 asserts.MakePoolGrouping(2): {seq1111}, 1359 }) 1360 1361 err = pool.AddError(errBoom, storeKey.Ref()) 1362 c.Assert(err, IsNil) 1363 1364 err = pool.AddSequenceError(errBoom, seq1111) 1365 c.Assert(err, IsNil) 1366 1367 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1)) 1368 c.Assert(err, IsNil) 1369 c.Assert(ok, Equals, true) 1370 1371 toResolve, toResolveSeq, err = pool.ToResolve() 1372 c.Assert(err, IsNil) 1373 c.Check(toResolve, HasLen, 0) 1374 c.Check(toResolveSeq, HasLen, 0) 1375 1376 c.Check(pool.Err("store_key"), Equals, errBoom) 1377 c.Check(pool.Err("for_one"), Equals, errBoom) 1378 c.Check(pool.Err("for_two"), Equals, errBoom) 1379 } 1380 1381 func (s *poolSuite) TestAddErrorLater(c *C) { 1382 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1383 1384 pool := asserts.NewPool(s.db, 64) 1385 1386 storeKey := s.hub.StoreAccountKey("") 1387 err := pool.AddToUpdate(storeKey.Ref(), "store_key") 1388 c.Assert(err, IsNil) 1389 1390 at1111 := &asserts.AtRevision{ 1391 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 1392 Revision: asserts.RevisionNotKnown, 1393 } 1394 err = pool.AddUnresolved(at1111, "for_one") 1395 c.Assert(err, IsNil) 1396 1397 toResolve, toResolveSeq, err := pool.ToResolve() 1398 c.Assert(err, IsNil) 1399 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1400 asserts.MakePoolGrouping(0): {storeKey.At()}, 1401 asserts.MakePoolGrouping(1): {at1111}, 1402 }) 1403 c.Check(toResolveSeq, HasLen, 0) 1404 1405 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1)) 1406 c.Assert(err, IsNil) 1407 c.Assert(ok, Equals, true) 1408 1409 err = pool.AddError(errBoom, storeKey.Ref()) 1410 c.Assert(err, IsNil) 1411 1412 toResolve, toResolveSeq, err = pool.ToResolve() 1413 c.Assert(err, IsNil) 1414 c.Check(toResolve, HasLen, 0) 1415 c.Check(toResolveSeq, HasLen, 0) 1416 1417 c.Check(pool.Err("store_key"), Equals, errBoom) 1418 c.Check(pool.Err("for_one"), Equals, errBoom) 1419 } 1420 1421 func (s *poolSuite) TestNopUpdatePlusFetchOfPushed(c *C) { 1422 storeKey := s.hub.StoreAccountKey("") 1423 assertstest.AddMany(s.db, storeKey) 1424 assertstest.AddMany(s.db, s.dev1Acct) 1425 assertstest.AddMany(s.db, s.decl1) 1426 assertstest.AddMany(s.db, s.rev1_1111) 1427 1428 pool := asserts.NewPool(s.db, 64) 1429 1430 atOne := s.decl1.At() 1431 err := pool.AddToUpdate(&atOne.Ref, "for_one") 1432 c.Assert(err, IsNil) 1433 1434 toResolve, toResolveSeq, err := pool.ToResolve() 1435 c.Assert(err, IsNil) 1436 sortToResolve(toResolve) 1437 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1438 asserts.MakePoolGrouping(0): {storeKey.At(), s.dev1Acct.At(), atOne}, 1439 }) 1440 c.Check(toResolveSeq, HasLen, 0) 1441 1442 // no updates but 1443 // new push suggestion 1444 1445 gSuggestion, err := pool.Singleton("suggestion") 1446 c.Assert(err, IsNil) 1447 1448 ok, err := pool.Add(s.rev1_3333, gSuggestion) 1449 c.Assert(err, IsNil) 1450 c.Assert(ok, Equals, true) 1451 1452 toResolve, toResolveSeq, err = pool.ToResolve() 1453 c.Assert(err, IsNil) 1454 c.Assert(toResolve, HasLen, 0) 1455 c.Check(toResolveSeq, HasLen, 0) 1456 1457 c.Check(pool.Err("for_one"), IsNil) 1458 1459 pool.AddGroupingError(errBoom, gSuggestion) 1460 1461 c.Assert(pool.Err("for_one"), IsNil) 1462 c.Assert(pool.Err("suggestion"), Equals, errBoom) 1463 1464 at3333 := s.rev1_3333.At() 1465 at3333.Revision = asserts.RevisionNotKnown 1466 err = pool.AddUnresolved(at3333, at3333.Unique()) 1467 c.Assert(err, IsNil) 1468 1469 toResolve, toResolveSeq, err = pool.ToResolve() 1470 c.Assert(err, IsNil) 1471 c.Assert(toResolve, HasLen, 0) 1472 c.Check(toResolveSeq, HasLen, 0) 1473 1474 err = pool.CommitTo(s.db) 1475 c.Check(err, IsNil) 1476 1477 c.Assert(pool.Err(at3333.Unique()), IsNil) 1478 1479 a, err := s.rev1_3333.Ref().Resolve(s.db.Find) 1480 c.Assert(err, IsNil) 1481 c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "3333") 1482 } 1483 1484 func (s *poolSuite) TestAddToUpdateThenUnresolved(c *C) { 1485 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1486 1487 pool := asserts.NewPool(s.db, 64) 1488 1489 storeKey := s.hub.StoreAccountKey("") 1490 storeKeyAt := storeKey.At() 1491 storeKeyAt.Revision = asserts.RevisionNotKnown 1492 1493 err := pool.AddToUpdate(storeKey.Ref(), "for_one") 1494 c.Assert(err, IsNil) 1495 err = pool.AddUnresolved(storeKeyAt, "for_one") 1496 c.Assert(err, IsNil) 1497 1498 toResolve, toResolveSeq, err := pool.ToResolve() 1499 c.Assert(err, IsNil) 1500 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1501 asserts.MakePoolGrouping(0): {storeKey.At()}, 1502 }) 1503 c.Check(toResolveSeq, HasLen, 0) 1504 } 1505 1506 func (s *poolSuite) TestAddUnresolvedThenToUpdate(c *C) { 1507 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1508 1509 pool := asserts.NewPool(s.db, 64) 1510 1511 storeKey := s.hub.StoreAccountKey("") 1512 storeKeyAt := storeKey.At() 1513 storeKeyAt.Revision = asserts.RevisionNotKnown 1514 1515 err := pool.AddUnresolved(storeKeyAt, "for_one") 1516 c.Assert(err, IsNil) 1517 err = pool.AddToUpdate(storeKey.Ref(), "for_one") 1518 c.Assert(err, IsNil) 1519 1520 toResolve, toResolveSeq, err := pool.ToResolve() 1521 c.Assert(err, IsNil) 1522 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1523 asserts.MakePoolGrouping(0): {storeKey.At()}, 1524 }) 1525 c.Check(toResolveSeq, HasLen, 0) 1526 } 1527 1528 func (s *poolSuite) TestNopUpdatePlusFetch(c *C) { 1529 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1530 1531 pool := asserts.NewPool(s.db, 64) 1532 1533 storeKey := s.hub.StoreAccountKey("") 1534 err := pool.AddToUpdate(storeKey.Ref(), "store_key") 1535 c.Assert(err, IsNil) 1536 1537 at1111 := &asserts.AtRevision{ 1538 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 1539 Revision: asserts.RevisionNotKnown, 1540 } 1541 err = pool.AddUnresolved(at1111, "for_one") 1542 c.Assert(err, IsNil) 1543 1544 toResolve, toResolveSeq, err := pool.ToResolve() 1545 c.Assert(err, IsNil) 1546 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1547 asserts.MakePoolGrouping(0): {storeKey.At()}, 1548 asserts.MakePoolGrouping(1): {at1111}, 1549 }) 1550 c.Check(toResolveSeq, HasLen, 0) 1551 1552 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1)) 1553 c.Assert(err, IsNil) 1554 c.Assert(ok, Equals, true) 1555 1556 toResolve, toResolveSeq, err = pool.ToResolve() 1557 c.Assert(err, IsNil) 1558 sortToResolve(toResolve) 1559 dev1AcctAt := s.dev1Acct.At() 1560 dev1AcctAt.Revision = asserts.RevisionNotKnown 1561 decl1At := s.decl1.At() 1562 decl1At.Revision = asserts.RevisionNotKnown 1563 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1564 asserts.MakePoolGrouping(1): {dev1AcctAt, decl1At}, 1565 }) 1566 c.Check(toResolveSeq, HasLen, 0) 1567 1568 c.Check(pool.Err("store_key"), IsNil) 1569 c.Check(pool.Err("for_one"), IsNil) 1570 } 1571 1572 func (s *poolSuite) TestParallelPartialResolutionFailure(c *C) { 1573 pool := asserts.NewPool(s.db, 64) 1574 1575 atOne := &asserts.AtRevision{ 1576 Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}}, 1577 Revision: asserts.RevisionNotKnown, 1578 } 1579 err := pool.AddUnresolved(atOne, "one") 1580 c.Assert(err, IsNil) 1581 1582 toResolve, toResolveSeq, err := pool.ToResolve() 1583 c.Assert(err, IsNil) 1584 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1585 asserts.MakePoolGrouping(0): {atOne}, 1586 }) 1587 c.Check(toResolveSeq, HasLen, 0) 1588 1589 ok, err := pool.Add(s.decl1, asserts.MakePoolGrouping(0)) 1590 c.Assert(err, IsNil) 1591 c.Assert(ok, Equals, true) 1592 1593 toResolve, toResolveSeq, err = pool.ToResolve() 1594 c.Assert(err, IsNil) 1595 sortToResolve(toResolve) 1596 dev1AcctAt := s.dev1Acct.At() 1597 dev1AcctAt.Revision = asserts.RevisionNotKnown 1598 decl1At := s.decl1.At() 1599 decl1At.Revision = asserts.RevisionNotKnown 1600 storeKeyAt := s.hub.StoreAccountKey("").At() 1601 storeKeyAt.Revision = asserts.RevisionNotKnown 1602 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1603 asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt}, 1604 }) 1605 c.Check(toResolveSeq, HasLen, 0) 1606 1607 // failed to get prereqs 1608 c.Check(pool.AddGroupingError(errBoom, asserts.MakePoolGrouping(0)), IsNil) 1609 1610 err = pool.AddUnresolved(atOne, "other") 1611 c.Assert(err, IsNil) 1612 1613 toResolve, toResolveSeq, err = pool.ToResolve() 1614 c.Assert(err, IsNil) 1615 c.Check(toResolve, HasLen, 0) 1616 c.Check(toResolveSeq, HasLen, 0) 1617 1618 c.Check(pool.Err("one"), Equals, errBoom) 1619 c.Check(pool.Err("other"), IsNil) 1620 1621 // we fail at commit though 1622 err = pool.CommitTo(s.db) 1623 c.Check(err, IsNil) 1624 c.Check(pool.Err("one"), Equals, errBoom) 1625 c.Check(pool.Err("other"), ErrorMatches, "cannot resolve prerequisite assertion.*") 1626 } 1627 1628 func (s *poolSuite) TestAddErrors(c *C) { 1629 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1630 1631 pool := asserts.NewPool(s.db, 64) 1632 1633 storeKey := s.hub.StoreAccountKey("") 1634 err := pool.AddToUpdate(storeKey.Ref(), "store_key") 1635 c.Assert(err, IsNil) 1636 1637 at1111 := &asserts.AtRevision{ 1638 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 1639 Revision: asserts.RevisionNotKnown, 1640 } 1641 err = pool.AddUnresolved(at1111, "for_one") 1642 c.Assert(err, IsNil) 1643 1644 seq1111 := &asserts.AtSequence{ 1645 Type: asserts.TestOnlySeqType, 1646 SequenceKey: []string{"1111"}, 1647 Revision: asserts.RevisionNotKnown, 1648 } 1649 err = pool.AddUnresolvedSequence(seq1111, "for_two") 1650 c.Assert(err, IsNil) 1651 1652 toResolve, toResolveSeq, err := pool.ToResolve() 1653 c.Assert(err, IsNil) 1654 c.Check(toResolve, HasLen, 2) 1655 c.Check(toResolveSeq, HasLen, 1) 1656 1657 err = pool.AddError(errBoom, storeKey.Ref()) 1658 c.Assert(err, IsNil) 1659 1660 toResolve, toResolveSeq, err = pool.ToResolve() 1661 c.Assert(err, IsNil) 1662 c.Check(toResolve, HasLen, 0) 1663 c.Check(toResolveSeq, HasLen, 0) 1664 1665 c.Check(pool.Errors(), DeepEquals, map[string]error{ 1666 "store_key": errBoom, 1667 "for_one": asserts.ErrUnresolved, 1668 "for_two": asserts.ErrUnresolved, 1669 }) 1670 } 1671 1672 func (s *poolSuite) TestPoolReuseWithClearGroupsAndUnchanged(c *C) { 1673 assertstest.AddMany(s.db, s.hub.StoreAccountKey("")) 1674 assertstest.AddMany(s.db, s.dev1Acct, s.decl1) 1675 assertstest.AddMany(s.db, s.dev2Acct, s.decl2) 1676 1677 pool := asserts.NewPool(s.db, 64) 1678 1679 err := pool.AddToUpdate(s.decl1.Ref(), "for_one") // group num: 0 1680 c.Assert(err, IsNil) 1681 1682 storeKeyAt := s.hub.StoreAccountKey("").At() 1683 1684 toResolve, toResolveSeq, err := pool.ToResolve() 1685 c.Assert(err, IsNil) 1686 sortToResolve(toResolve) 1687 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1688 asserts.MakePoolGrouping(0): {storeKeyAt, s.dev1Acct.At(), s.decl1.At()}, 1689 }) 1690 c.Check(toResolveSeq, HasLen, 0) 1691 1692 ok, err := pool.Add(s.decl1_1, asserts.MakePoolGrouping(0)) 1693 c.Assert(err, IsNil) 1694 c.Assert(ok, Equals, true) 1695 1696 toResolve, toResolveSeq, err = pool.ToResolve() 1697 c.Assert(err, IsNil) 1698 c.Check(toResolve, HasLen, 0) 1699 c.Check(toResolveSeq, HasLen, 0) 1700 1701 // clear the groups as we would do for real reuse when we have 1702 // exhausted allowed groups 1703 err = pool.ClearGroups() 1704 c.Assert(err, IsNil) 1705 1706 err = pool.AddToUpdate(s.decl2.Ref(), "for_two") // group num: 0 again 1707 c.Assert(err, IsNil) 1708 1709 // no reference to store key because it is remebered as unchanged 1710 // across the clearing 1711 toResolve, toResolveSeq, err = pool.ToResolve() 1712 c.Assert(err, IsNil) 1713 sortToResolve(toResolve) 1714 c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{ 1715 asserts.MakePoolGrouping(0): {s.dev2Acct.At(), s.decl2.At()}, 1716 }) 1717 c.Check(toResolveSeq, HasLen, 0) 1718 } 1719 1720 func (s *poolSuite) TestBackstore(c *C) { 1721 assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct) 1722 pool := asserts.NewPool(s.db, 64) 1723 1724 at1111 := &asserts.AtRevision{ 1725 Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}}, 1726 Revision: asserts.RevisionNotKnown, 1727 } 1728 c.Assert(pool.AddUnresolved(at1111, "for_one"), IsNil) 1729 res, _, err := pool.ToResolve() 1730 c.Assert(err, IsNil) 1731 c.Assert(res, HasLen, 1) 1732 1733 // resolve (but do not commit) 1734 ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0)) 1735 c.Assert(err, IsNil) 1736 c.Assert(ok, Equals, true) 1737 1738 // the assertion should be available via pool's backstore 1739 bs := pool.Backstore() 1740 c.Assert(bs, NotNil) 1741 a, err := bs.Get(s.rev1_1111.Type(), s.rev1_1111.At().PrimaryKey, s.rev1_1111.Type().MaxSupportedFormat()) 1742 c.Assert(err, IsNil) 1743 c.Assert(a, NotNil) 1744 }