mirror of
https://github.com/token2/snapd.git
synced 2026-03-13 11:15:47 -07:00
1745 lines
49 KiB
Go
1745 lines
49 KiB
Go
// -*- Mode: Go; indent-tabs-mode: t -*-
|
|
|
|
/*
|
|
* Copyright (C) 2020-2022 Canonical Ltd
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
package asserts_test
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
|
|
. "gopkg.in/check.v1"
|
|
|
|
"github.com/snapcore/snapd/asserts"
|
|
"github.com/snapcore/snapd/asserts/assertstest"
|
|
"github.com/snapcore/snapd/testutil"
|
|
)
|
|
|
|
type poolSuite struct {
|
|
testutil.BaseTest
|
|
|
|
hub *assertstest.StoreStack
|
|
dev1Acct *asserts.Account
|
|
dev2Acct *asserts.Account
|
|
|
|
decl1 *asserts.TestOnlyDecl
|
|
decl1_1 *asserts.TestOnlyDecl
|
|
rev1_1111 *asserts.TestOnlyRev
|
|
rev1_3333 *asserts.TestOnlyRev
|
|
|
|
decl2 *asserts.TestOnlyDecl
|
|
rev2_2222 *asserts.TestOnlyRev
|
|
|
|
seq1_1111r5 *asserts.TestOnlySeq
|
|
seq1_1111r6 *asserts.TestOnlySeq
|
|
seq2_1111r7 *asserts.TestOnlySeq
|
|
seq3_1111r5 *asserts.TestOnlySeq
|
|
|
|
db *asserts.Database
|
|
}
|
|
|
|
var _ = Suite(&poolSuite{})
|
|
|
|
func (s *poolSuite) SetUpTest(c *C) {
|
|
s.BaseTest.SetUpTest(c)
|
|
|
|
s.hub = assertstest.NewStoreStack("hub", nil)
|
|
s.dev1Acct = assertstest.NewAccount(s.hub, "developer1", map[string]interface{}{
|
|
"account-id": "developer1",
|
|
}, "")
|
|
s.dev2Acct = assertstest.NewAccount(s.hub, "developer2", map[string]interface{}{
|
|
"account-id": "developer2",
|
|
}, "")
|
|
|
|
a, err := s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.decl1 = a.(*asserts.TestOnlyDecl)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
"revision": "1",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.decl1_1 = a.(*asserts.TestOnlyDecl)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{
|
|
"id": "two",
|
|
"dev-id": "developer2",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.decl2 = a.(*asserts.TestOnlyDecl)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{
|
|
"h": "1111",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.rev1_1111 = a.(*asserts.TestOnlyRev)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{
|
|
"h": "3333",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.rev1_3333 = a.(*asserts.TestOnlyRev)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyRevType, map[string]interface{}{
|
|
"h": "2222",
|
|
"id": "two",
|
|
"dev-id": "developer2",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.rev2_2222 = a.(*asserts.TestOnlyRev)
|
|
|
|
// sequence-forming
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{
|
|
"n": "1111",
|
|
"sequence": "1",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
"revision": "5",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.seq1_1111r5 = a.(*asserts.TestOnlySeq)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{
|
|
"n": "1111",
|
|
"sequence": "1",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
"revision": "6",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.seq1_1111r6 = a.(*asserts.TestOnlySeq)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{
|
|
"n": "1111",
|
|
"sequence": "2",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
"revision": "7",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.seq2_1111r7 = a.(*asserts.TestOnlySeq)
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlySeqType, map[string]interface{}{
|
|
"n": "1111",
|
|
"sequence": "3",
|
|
"id": "one",
|
|
"dev-id": "developer1",
|
|
"revision": "4",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
s.seq3_1111r5 = a.(*asserts.TestOnlySeq)
|
|
|
|
db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{
|
|
Backstore: asserts.NewMemoryBackstore(),
|
|
Trusted: s.hub.Trusted,
|
|
})
|
|
c.Assert(err, IsNil)
|
|
s.db = db
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolved(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(at1, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {at1},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedPredefined(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at := s.hub.TrustedAccount.At()
|
|
at.Revision = asserts.RevisionNotKnown
|
|
err := pool.AddUnresolved(at, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
// nothing to resolve
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedGrouping(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
|
|
pool.AddUnresolved(storeKeyAt, "for_two") // group num: 0
|
|
pool.AddUnresolved(storeKeyAt, "for_one") // group num: 1
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0, 1): {storeKeyAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedDup(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
|
|
pool.AddUnresolved(storeKeyAt, "for_one") // group num: 0
|
|
pool.AddUnresolved(storeKeyAt, "for_one") // group num: 0
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
type byAtRevision []*asserts.AtRevision
|
|
|
|
func (ats byAtRevision) Len() int {
|
|
return len(ats)
|
|
}
|
|
|
|
func (ats byAtRevision) Less(i, j int) bool {
|
|
return ats[i].Ref.Unique() < ats[j].Ref.Unique()
|
|
}
|
|
|
|
func (ats byAtRevision) Swap(i, j int) {
|
|
ats[i], ats[j] = ats[j], ats[i]
|
|
}
|
|
|
|
func sortToResolve(toResolve map[asserts.Grouping][]*asserts.AtRevision) {
|
|
for _, ats := range toResolve {
|
|
sort.Sort(byAtRevision(ats))
|
|
}
|
|
}
|
|
|
|
func (s *poolSuite) TestFetch(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
decl1At := s.decl1.At()
|
|
decl1At.Revision = asserts.RevisionNotKnown
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt, decl1At},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestFetchSequenceForming(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
// revision and sequence not set
|
|
atseq := &asserts.AtSequence{
|
|
Type: asserts.TestOnlySeqType,
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolvedSequence(atseq, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {atseq},
|
|
})
|
|
|
|
// resolve
|
|
ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt},
|
|
})
|
|
|
|
ok, err = pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestCompleteFetch(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
decl1At := s.decl1.At()
|
|
decl1At.Revision = asserts.RevisionNotKnown
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
storeKeyAt := storeKey.At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt, decl1At},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
b := asserts.NewBatch(nil)
|
|
err = b.Add(s.decl1)
|
|
c.Assert(err, IsNil)
|
|
err = b.Add(storeKey)
|
|
c.Assert(err, IsNil)
|
|
err = b.Add(s.dev1Acct)
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err = pool.AddBatch(b, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
a, err := at1111.Ref.Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111")
|
|
}
|
|
|
|
func (s *poolSuite) TestPushSuggestionForPrerequisite(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// push prerequisite suggestion
|
|
ok, err = pool.Add(s.decl1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At(), dev1AcctAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
a, err := at1111.Ref.Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111")
|
|
}
|
|
|
|
func (s *poolSuite) TestPushSuggestionForNew(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atOne := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(atOne, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {atOne},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.decl1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// new push suggestion
|
|
ok, err = pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
a, err := s.rev1_1111.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111")
|
|
}
|
|
|
|
func (s *poolSuite) TestPushSuggestionForNewSeqForming(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atOne := &asserts.AtSequence{
|
|
Type: asserts.TestOnlySeqType,
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolvedSequence(atOne, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {atOne},
|
|
})
|
|
|
|
ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// new push suggestion
|
|
ok, err = pool.Add(s.seq2_1111r7, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
|
|
c.Check(toResolve, HasLen, 1)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
a, err := s.seq2_1111r7.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlySeq).N(), Equals, "1111")
|
|
c.Check(a.Revision(), Equals, 7)
|
|
}
|
|
|
|
func (s *poolSuite) TestPushSuggestionForNewViaBatch(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atOne := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(atOne, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {atOne},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
b := asserts.NewBatch(nil)
|
|
err = b.Add(s.decl1)
|
|
c.Assert(err, IsNil)
|
|
|
|
// new push suggestions
|
|
err = b.Add(s.rev1_1111)
|
|
c.Assert(err, IsNil)
|
|
err = b.Add(s.rev1_3333)
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err := pool.AddBatch(b, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
a, err := s.rev1_1111.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "1111")
|
|
|
|
a, err = s.rev1_3333.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "3333")
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedUnresolved(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(at1, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {at1},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), Equals, asserts.ErrUnresolved)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddFormatTooNew(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
_, _, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
var a asserts.Assertion
|
|
(func() {
|
|
restore := asserts.MockMaxSupportedFormat(asserts.TestOnlyDeclType, 2)
|
|
defer restore()
|
|
|
|
a, err = s.hub.Sign(asserts.TestOnlyDeclType, map[string]interface{}{
|
|
"id": "three",
|
|
"dev-id": "developer1",
|
|
"format": "2",
|
|
}, nil, "")
|
|
c.Assert(err, IsNil)
|
|
})()
|
|
|
|
gSuggestion, err := pool.Singleton("suggestion")
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err := pool.Add(a, gSuggestion)
|
|
c.Check(err, IsNil)
|
|
c.Check(ok, Equals, false)
|
|
c.Assert(pool.Err("suggestion"), ErrorMatches, `proposed "test-only-decl" assertion has format 2 but 0 is latest supported`)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddOlderIgnored(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
_, _, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
gSuggestion, err := pool.Singleton("suggestion")
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err := pool.Add(s.decl1_1, gSuggestion)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
ok, err = pool.Add(s.decl1, gSuggestion)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
gSuggestion: {storeKeyAt, dev1AcctAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestUnknownGroup(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
_, err := pool.Singleton("suggestion")
|
|
c.Assert(err, IsNil)
|
|
// validity
|
|
c.Check(pool.Err("suggestion"), IsNil)
|
|
|
|
c.Check(pool.Err("foo"), Equals, asserts.ErrUnknownPoolGroup)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddCurrentRevision(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct, s.decl1)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atDev1Acct := s.dev1Acct.At()
|
|
atDev1Acct.Revision = asserts.RevisionNotKnown
|
|
err := pool.AddUnresolved(atDev1Acct, "one")
|
|
c.Assert(err, IsNil)
|
|
|
|
atDecl1 := s.decl1.At()
|
|
atDecl1.Revision = asserts.RevisionNotKnown
|
|
err = pool.AddUnresolved(atDecl1, "one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.dev1Acct.At(), s.decl1.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
// re-adding of current revisions, is not what we expect
|
|
// but needs to not produce unnecessary roundtrips
|
|
|
|
ok, err := pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// this will be kept marked as unresolved until the ToResolve
|
|
ok, err = pool.Add(s.dev1Acct, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
ok, err = pool.Add(s.decl1_1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(toResolve, HasLen, 0)
|
|
c.Assert(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("one"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddCurrentRevisionSeqForming(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct, s.decl1)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atSeq := &asserts.AtSequence{
|
|
Type: asserts.TestOnlySeqType,
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolvedSequence(atSeq, "one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}},
|
|
})
|
|
|
|
// re-adding of current revisions, is not what we expect
|
|
// but needs to not produce unnecessary roundtrips
|
|
|
|
ok, err := pool.Add(s.hub.StoreAccountKey(""), asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// this will be kept marked as unresolved until the ToResolve
|
|
ok, err = pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(toResolve, HasLen, 0)
|
|
c.Assert(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("one"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdate(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
assertstest.AddMany(s.db, s.dev1Acct, s.decl1, s.rev1_1111)
|
|
assertstest.AddMany(s.db, s.dev2Acct, s.decl2, s.rev2_2222)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
err := pool.AddToUpdate(s.decl1.Ref(), "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
err = pool.AddToUpdate(s.decl2.Ref(), "for_two") // group num: 1
|
|
c.Assert(err, IsNil)
|
|
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0, 1): {storeKeyAt},
|
|
asserts.MakePoolGrouping(0): {s.dev1Acct.At(), s.decl1.At()},
|
|
asserts.MakePoolGrouping(1): {s.dev2Acct.At(), s.decl2.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.decl1_1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
at2222 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"2222"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolved(at2222, "for_two")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(1): {&asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"2222"}},
|
|
Revision: 0,
|
|
}},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
c.Check(pool.Err("for_two"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingUnpinnedNewerSequence(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// resolve with sequence 3
|
|
ok, err := pool.Add(s.seq3_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 5 is still in the db.
|
|
_, err = s.seq1_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
|
|
// and sequence point 3 revision 5 is in the database.
|
|
_, err = s.seq3_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingUnpinnedSameSequenceNewerRev(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// resolve
|
|
ok, err := pool.Add(s.seq1_1111r6, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 5 is still in the database.
|
|
_, err = s.seq1_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
|
|
// and sequence point 1 revision 6 is in the database.
|
|
_, err = s.seq1_1111r6.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingUnpinnedSameSequenceSameRevNoop(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// update with same assertion
|
|
ok, err := pool.Add(s.seq1_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 5 is still in the database.
|
|
_, err = s.seq1_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingPinnedNewerSequenceSameRevisionNoop(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// resolve
|
|
ok, err := pool.Add(s.seq3_1111r5, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 5 is still the latest.
|
|
_, err = s.seq1_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
|
|
// and sequence point 3 revision 5 wasn't added to asserts database.
|
|
_, err = s.seq3_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(errors.Is(err, &asserts.NotFoundError{}), Equals, true)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingPinnedNewerSequenceNewerRevisionNoop(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// resolve
|
|
ok, err := pool.Add(s.seq2_1111r7, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 5 is still the latest.
|
|
_, err = s.seq1_1111r5.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
|
|
// and sequence point 2 revision 7 wasn't added to asserts database.
|
|
_, err = s.seq2_1111r7.Ref().Resolve(s.db.Find)
|
|
c.Assert(errors.Is(err, &asserts.NotFoundError{}), Equals, true)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingPinnedSameSequenceNewerRevision(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
Pinned: true,
|
|
}},
|
|
})
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
// resolve
|
|
ok, err := pool.Add(s.seq1_1111r6, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
|
|
// sequence point 1, revision 6 is in db.
|
|
_, err = s.seq1_1111r6.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestUpdateSeqFormingUseAssertRevision(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 0, // intentionaly unset
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.hub.StoreAccountKey(s.dev1Acct.SignKeyID()).At()},
|
|
})
|
|
|
|
// verify that revision number from the existing assertion to update was used.
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Sequence: 1,
|
|
Revision: 5,
|
|
}},
|
|
})
|
|
}
|
|
|
|
func (s *poolSuite) TestAddSequenceToUpdateMissingSequenceError(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one")
|
|
c.Assert(err, ErrorMatches, `internal error: sequence to update must have a sequence number set`)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedSeqUnresolved(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
Sequence: 1,
|
|
}
|
|
err := pool.AddUnresolvedSequence(atseq, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(0): {
|
|
&asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
Sequence: 1,
|
|
}},
|
|
})
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), Equals, asserts.ErrUnresolved)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedSeqOnce(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
Sequence: 1,
|
|
}
|
|
err := pool.AddUnresolvedSequence(atseq, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
atseq.Sequence = 2
|
|
atseq.Revision = 3
|
|
err = pool.AddUnresolvedSequence(atseq, "for_one")
|
|
c.Assert(err, ErrorMatches, `internal error: sequence \[1111\] is already being resolved`)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddSeqToUpdateOnce(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.seq1_1111r5)
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: 2,
|
|
Sequence: 1,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
atseq.Sequence = 3
|
|
atseq.Revision = 3
|
|
err = pool.AddSequenceToUpdate(atseq, "for_one")
|
|
c.Assert(err, ErrorMatches, `internal error: sequence \[1111\] is already being resolved`)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddSeqToUpdateNotFound(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atseq := &asserts.AtSequence{
|
|
Type: s.seq1_1111r5.Type(),
|
|
SequenceKey: []string{"1111"},
|
|
Revision: 2,
|
|
Sequence: 1,
|
|
}
|
|
err := pool.AddSequenceToUpdate(atseq, "for_one")
|
|
c.Assert(errors.Is(err, &asserts.NotFoundError{}), Equals, true)
|
|
}
|
|
|
|
var errBoom = errors.New("boom")
|
|
|
|
func (s *poolSuite) TestAddErrorEarly(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
err := pool.AddToUpdate(storeKey.Ref(), "store_key")
|
|
c.Assert(err, IsNil)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
seq1111 := &asserts.AtSequence{
|
|
Type: asserts.TestOnlySeqType,
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolvedSequence(seq1111, "for_two")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At()},
|
|
asserts.MakePoolGrouping(1): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, DeepEquals, map[asserts.Grouping][]*asserts.AtSequence{
|
|
asserts.MakePoolGrouping(2): {seq1111},
|
|
})
|
|
|
|
err = pool.AddError(errBoom, storeKey.Ref())
|
|
c.Assert(err, IsNil)
|
|
|
|
err = pool.AddSequenceError(errBoom, seq1111)
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("store_key"), Equals, errBoom)
|
|
c.Check(pool.Err("for_one"), Equals, errBoom)
|
|
c.Check(pool.Err("for_two"), Equals, errBoom)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddErrorLater(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
err := pool.AddToUpdate(storeKey.Ref(), "store_key")
|
|
c.Assert(err, IsNil)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At()},
|
|
asserts.MakePoolGrouping(1): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
err = pool.AddError(errBoom, storeKey.Ref())
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("store_key"), Equals, errBoom)
|
|
c.Check(pool.Err("for_one"), Equals, errBoom)
|
|
}
|
|
|
|
func (s *poolSuite) TestNopUpdatePlusFetchOfPushed(c *C) {
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
assertstest.AddMany(s.db, storeKey)
|
|
assertstest.AddMany(s.db, s.dev1Acct)
|
|
assertstest.AddMany(s.db, s.decl1)
|
|
assertstest.AddMany(s.db, s.rev1_1111)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atOne := s.decl1.At()
|
|
err := pool.AddToUpdate(&atOne.Ref, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At(), s.dev1Acct.At(), atOne},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
// no updates but
|
|
// new push suggestion
|
|
|
|
gSuggestion, err := pool.Singleton("suggestion")
|
|
c.Assert(err, IsNil)
|
|
|
|
ok, err := pool.Add(s.rev1_3333, gSuggestion)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
|
|
pool.AddGroupingError(errBoom, gSuggestion)
|
|
|
|
c.Assert(pool.Err("for_one"), IsNil)
|
|
c.Assert(pool.Err("suggestion"), Equals, errBoom)
|
|
|
|
at3333 := s.rev1_3333.At()
|
|
at3333.Revision = asserts.RevisionNotKnown
|
|
err = pool.AddUnresolved(at3333, at3333.Unique())
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
|
|
c.Assert(pool.Err(at3333.Unique()), IsNil)
|
|
|
|
a, err := s.rev1_3333.Ref().Resolve(s.db.Find)
|
|
c.Assert(err, IsNil)
|
|
c.Check(a.(*asserts.TestOnlyRev).H(), Equals, "3333")
|
|
}
|
|
|
|
func (s *poolSuite) TestAddToUpdateThenUnresolved(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
storeKeyAt := storeKey.At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
|
|
err := pool.AddToUpdate(storeKey.Ref(), "for_one")
|
|
c.Assert(err, IsNil)
|
|
err = pool.AddUnresolved(storeKeyAt, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestAddUnresolvedThenToUpdate(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
storeKeyAt := storeKey.At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
|
|
err := pool.AddUnresolved(storeKeyAt, "for_one")
|
|
c.Assert(err, IsNil)
|
|
err = pool.AddToUpdate(storeKey.Ref(), "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestNopUpdatePlusFetch(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
err := pool.AddToUpdate(storeKey.Ref(), "store_key")
|
|
c.Assert(err, IsNil)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKey.At()},
|
|
asserts.MakePoolGrouping(1): {at1111},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(1))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
decl1At := s.decl1.At()
|
|
decl1At.Revision = asserts.RevisionNotKnown
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(1): {dev1AcctAt, decl1At},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("store_key"), IsNil)
|
|
c.Check(pool.Err("for_one"), IsNil)
|
|
}
|
|
|
|
func (s *poolSuite) TestParallelPartialResolutionFailure(c *C) {
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
atOne := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyDeclType, PrimaryKey: []string{"one"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err := pool.AddUnresolved(atOne, "one")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {atOne},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.decl1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
dev1AcctAt := s.dev1Acct.At()
|
|
dev1AcctAt.Revision = asserts.RevisionNotKnown
|
|
decl1At := s.decl1.At()
|
|
decl1At.Revision = asserts.RevisionNotKnown
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
storeKeyAt.Revision = asserts.RevisionNotKnown
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, dev1AcctAt},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
// failed to get prereqs
|
|
c.Check(pool.AddGroupingError(errBoom, asserts.MakePoolGrouping(0)), IsNil)
|
|
|
|
err = pool.AddUnresolved(atOne, "other")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Err("one"), Equals, errBoom)
|
|
c.Check(pool.Err("other"), IsNil)
|
|
|
|
// we fail at commit though
|
|
err = pool.CommitTo(s.db)
|
|
c.Check(err, IsNil)
|
|
c.Check(pool.Err("one"), Equals, errBoom)
|
|
c.Check(pool.Err("other"), ErrorMatches, "cannot resolve prerequisite assertion.*")
|
|
}
|
|
|
|
func (s *poolSuite) TestAddErrors(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
storeKey := s.hub.StoreAccountKey("")
|
|
err := pool.AddToUpdate(storeKey.Ref(), "store_key")
|
|
c.Assert(err, IsNil)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolved(at1111, "for_one")
|
|
c.Assert(err, IsNil)
|
|
|
|
seq1111 := &asserts.AtSequence{
|
|
Type: asserts.TestOnlySeqType,
|
|
SequenceKey: []string{"1111"},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
err = pool.AddUnresolvedSequence(seq1111, "for_two")
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 2)
|
|
c.Check(toResolveSeq, HasLen, 1)
|
|
|
|
err = pool.AddError(errBoom, storeKey.Ref())
|
|
c.Assert(err, IsNil)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
c.Check(pool.Errors(), DeepEquals, map[string]error{
|
|
"store_key": errBoom,
|
|
"for_one": asserts.ErrUnresolved,
|
|
"for_two": asserts.ErrUnresolved,
|
|
})
|
|
}
|
|
|
|
func (s *poolSuite) TestPoolReuseWithClearGroupsAndUnchanged(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""))
|
|
assertstest.AddMany(s.db, s.dev1Acct, s.decl1)
|
|
assertstest.AddMany(s.db, s.dev2Acct, s.decl2)
|
|
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
err := pool.AddToUpdate(s.decl1.Ref(), "for_one") // group num: 0
|
|
c.Assert(err, IsNil)
|
|
|
|
storeKeyAt := s.hub.StoreAccountKey("").At()
|
|
|
|
toResolve, toResolveSeq, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {storeKeyAt, s.dev1Acct.At(), s.decl1.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
ok, err := pool.Add(s.decl1_1, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Check(toResolve, HasLen, 0)
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
|
|
// clear the groups as we would do for real reuse when we have
|
|
// exhausted allowed groups
|
|
err = pool.ClearGroups()
|
|
c.Assert(err, IsNil)
|
|
|
|
err = pool.AddToUpdate(s.decl2.Ref(), "for_two") // group num: 0 again
|
|
c.Assert(err, IsNil)
|
|
|
|
// no reference to store key because it is remebered as unchanged
|
|
// across the clearing
|
|
toResolve, toResolveSeq, err = pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
sortToResolve(toResolve)
|
|
c.Check(toResolve, DeepEquals, map[asserts.Grouping][]*asserts.AtRevision{
|
|
asserts.MakePoolGrouping(0): {s.dev2Acct.At(), s.decl2.At()},
|
|
})
|
|
c.Check(toResolveSeq, HasLen, 0)
|
|
}
|
|
|
|
func (s *poolSuite) TestBackstore(c *C) {
|
|
assertstest.AddMany(s.db, s.hub.StoreAccountKey(""), s.dev1Acct)
|
|
pool := asserts.NewPool(s.db, 64)
|
|
|
|
at1111 := &asserts.AtRevision{
|
|
Ref: asserts.Ref{Type: asserts.TestOnlyRevType, PrimaryKey: []string{"1111"}},
|
|
Revision: asserts.RevisionNotKnown,
|
|
}
|
|
c.Assert(pool.AddUnresolved(at1111, "for_one"), IsNil)
|
|
res, _, err := pool.ToResolve()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(res, HasLen, 1)
|
|
|
|
// resolve (but do not commit)
|
|
ok, err := pool.Add(s.rev1_1111, asserts.MakePoolGrouping(0))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(ok, Equals, true)
|
|
|
|
// the assertion should be available via pool's backstore
|
|
bs := pool.Backstore()
|
|
c.Assert(bs, NotNil)
|
|
a, err := bs.Get(s.rev1_1111.Type(), s.rev1_1111.At().PrimaryKey, s.rev1_1111.Type().MaxSupportedFormat())
|
|
c.Assert(err, IsNil)
|
|
c.Assert(a, NotNil)
|
|
}
|