func (s *Store) collectAssertions() (asserts.Backstore, error) { bs := asserts.NewMemoryBackstore() add := func(a asserts.Assertion) { bs.Put(a.Type(), a) } for _, t := range sysdb.Trusted() { add(t) } add(systestkeys.TestRootAccount) add(systestkeys.TestRootAccountKey) add(systestkeys.TestStoreAccountKey) aFiles, err := filepath.Glob(filepath.Join(s.assertDir, "*")) if err != nil { return nil, err } for _, fn := range aFiles { b, err := ioutil.ReadFile(fn) if err != nil { return nil, err } a, err := asserts.Decode(b) if err != nil { return nil, err } add(a) } return bs, nil }
func (s *fetcherSuite) TestFetch(c *C) { s.prereqSnapAssertions(c, 10) db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: s.storeSigning.Trusted, }) c.Assert(err, IsNil) ref := &asserts.Ref{ Type: asserts.SnapRevisionType, PrimaryKey: []string{makeDigest(10)}, } retrieve := func(ref *asserts.Ref) (asserts.Assertion, error) { return ref.Resolve(s.storeSigning.Find) } f := asserts.NewFetcher(db, retrieve, db.Add) err = f.Fetch(ref) c.Assert(err, IsNil) snapRev, err := ref.Resolve(db.Find) c.Assert(err, IsNil) c.Check(snapRev.(*asserts.SnapRevision).SnapRevision(), Equals, 10) snapDecl, err := db.Find(asserts.SnapDeclarationType, map[string]string{ "series": "16", "snap-id": "snap-id-1", }) c.Assert(err, IsNil) c.Check(snapDecl.(*asserts.SnapDeclaration).SnapName(), Equals, "foo") }
func (mbss *memBackstoreSuite) TestPutOldRevision(c *C) { bs := asserts.NewMemoryBackstore() // Create two revisions of assertion. a0, err := asserts.Decode([]byte("type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: foo\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) a1, err := asserts.Decode([]byte("type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: foo\n" + "revision: 1\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) // Put newer revision, follwed by old revision. err = bs.Put(asserts.TestOnlyType, a1) c.Assert(err, IsNil) err = bs.Put(asserts.TestOnlyType, a0) c.Check(err, ErrorMatches, `revision 0 is older than current revision 1`) c.Check(err, DeepEquals, &asserts.RevisionError{Current: 1, Used: 0}) }
func (opens *openSuite) TestOpenDatabaseTrustedAccount(c *C) { headers := map[string]interface{}{ "authority-id": "canonical", "account-id": "trusted", "display-name": "Trusted", "validation": "certified", "timestamp": "2015-01-01T14:00:00Z", } acct, err := asserts.AssembleAndSignInTest(asserts.AccountType, headers, nil, testPrivKey0) c.Assert(err, IsNil) cfg := &asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: []asserts.Assertion{acct}, } db, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) a, err := db.Find(asserts.AccountType, map[string]string{ "account-id": "trusted", }) c.Assert(err, IsNil) acct1 := a.(*asserts.Account) c.Check(acct1.AccountID(), Equals, "trusted") c.Check(acct1.DisplayName(), Equals, "Trusted") c.Check(db.IsTrustedAccount("trusted"), Equals, true) // empty account id (invalid) is not trusted c.Check(db.IsTrustedAccount(""), Equals, false) }
func (s *snapassertsSuite) SetUpTest(c *C) { rootPrivKey, _ := assertstest.GenerateKey(1024) storePrivKey, _ := assertstest.GenerateKey(752) s.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) s.dev1Acct = assertstest.NewAccount(s.storeSigning, "developer1", nil, "") localDB, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: s.storeSigning.Trusted, }) c.Assert(err, IsNil) s.localDB = localDB // add in prereqs assertions err = s.localDB.Add(s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = s.localDB.Add(s.dev1Acct) c.Assert(err, IsNil) headers := map[string]interface{}{ "series": "16", "snap-id": "snap-id-1", "snap-name": "foo", "publisher-id": s.dev1Acct.AccountID(), "timestamp": time.Now().Format(time.RFC3339), } snapDecl, err := s.storeSigning.Sign(asserts.SnapDeclarationType, headers, nil, "") c.Assert(err, IsNil) err = s.localDB.Add(snapDecl) c.Assert(err, IsNil) }
func (s *deviceMgrSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) rootPrivKey, _ := assertstest.GenerateKey(1024) storePrivKey, _ := assertstest.GenerateKey(752) s.storeSigning = assertstest.NewStoreStack("canonical", rootPrivKey, storePrivKey) s.state = state.New(nil) db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: s.storeSigning.Trusted, }) c.Assert(err, IsNil) s.state.Lock() assertstate.ReplaceDB(s.state, db) s.state.Unlock() err = db.Add(s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) mgr, err := devicestate.Manager(s.state) c.Assert(err, IsNil) s.db = db s.mgr = mgr s.state.Lock() snapstate.ReplaceStore(s.state, &fakeStore{ state: s.state, db: s.storeSigning, }) s.state.Unlock() }
func (opens *openSuite) TestOpenDatabaseOK(c *C) { cfg := &asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), } db, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) c.Assert(db, NotNil) }
func (mbss *memBackstoreSuite) TestGetFormat(c *C) { bs := asserts.NewMemoryBackstore() af0, err := asserts.Decode([]byte("type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: foo\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) af1, err := asserts.Decode([]byte("type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: foo\n" + "format: 1\n" + "revision: 1\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) af2, err := asserts.Decode([]byte("type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: zoo\n" + "format: 2\n" + "revision: 22\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) err = bs.Put(asserts.TestOnlyType, af0) c.Assert(err, IsNil) err = bs.Put(asserts.TestOnlyType, af1) c.Assert(err, IsNil) a, err := bs.Get(asserts.TestOnlyType, []string{"foo"}, 1) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 1) a, err = bs.Get(asserts.TestOnlyType, []string{"foo"}, 0) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 0) a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 0) c.Assert(err, Equals, asserts.ErrNotFound) err = bs.Put(asserts.TestOnlyType, af2) c.Assert(err, IsNil) a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 1) c.Assert(err, Equals, asserts.ErrNotFound) a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 2) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 22) }
func MakeFakeRefreshForSnaps(snaps []string, blobDir string) error { storePrivKey, _ := assertstest.ReadPrivKey(systestkeys.TestStorePrivKey) db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: asserts.NewMemoryKeypairManager(), Backstore: asserts.NewMemoryBackstore(), Trusted: sysdb.Trusted(), }) if err != nil { return err } // for signing db.ImportKey(storePrivKey) var cliConfig client.Config cli := client.New(&cliConfig) retrieve := func(ref *asserts.Ref) (asserts.Assertion, error) { headers := make(map[string]string) for i, k := range ref.Type.PrimaryKey { headers[k] = ref.PrimaryKey[i] } as, err := cli.Known(ref.Type.Name, headers) if err != nil { return nil, err } switch len(as) { case 1: return as[0], nil case 0: return nil, asserts.ErrNotFound default: panic(fmt.Sprintf("multiple assertions when retrieving by primary key: %v", ref)) } } save := func(a asserts.Assertion) error { err := db.Add(a) if err != nil { if _, ok := err.(*asserts.RevisionError); !ok { return err } } return writeAssert(a, blobDir) } f := asserts.NewFetcher(db, retrieve, save) for _, snap := range snaps { if err := makeFakeRefreshForSnap(snap, blobDir, db, f); err != nil { return err } } return nil }
func (mbss *memBackstoreSuite) SetUpTest(c *C) { mbss.bs = asserts.NewMemoryBackstore() encoded := "type: test-only\n" + "authority-id: auth-id1\n" + "primary-key: foo\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==" a, err := asserts.Decode([]byte(encoded)) c.Assert(err, IsNil) mbss.a = a }
// NewStoreStack creates a new store assertion stack. It panics on error. func NewStoreStack(authorityID string, rootPrivKey, storePrivKey asserts.PrivateKey) *StoreStack { rootSigning := NewSigningDB(authorityID, rootPrivKey) ts := time.Now().Format(time.RFC3339) trustedAcct := NewAccount(rootSigning, authorityID, map[string]interface{}{ "account-id": authorityID, "validation": "certified", "timestamp": ts, }, "") trustedKey := NewAccountKey(rootSigning, trustedAcct, map[string]interface{}{ "name": "root", "since": ts, }, rootPrivKey.PublicKey(), "") trusted := []asserts.Assertion{trustedAcct, trustedKey} db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: trusted, }) if err != nil { panic(err) } err = db.ImportKey(storePrivKey) if err != nil { panic(err) } storeKey := NewAccountKey(rootSigning, trustedAcct, map[string]interface{}{ "name": "store", }, storePrivKey.PublicKey(), "") err = db.Add(storeKey) if err != nil { panic(err) } return &StoreStack{ TrustedAccount: trustedAcct, TrustedKey: trustedKey, Trusted: trusted, RootSigning: rootSigning, SigningDB: &SigningDB{ AuthorityID: authorityID, KeyID: storeKey.PublicKeyID(), Database: db, }, } }
func makeStoreAndCheckDB(c *C) (storeDB *assertstest.SigningDB, checkDB *asserts.Database) { trustedPrivKey := testPrivKey0 storePrivKey := testPrivKey1 store := assertstest.NewStoreStack("canonical", trustedPrivKey, storePrivKey) cfg := &asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: store.Trusted, } checkDB, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) // add store key err = checkDB.Add(store.StoreAccountKey("")) c.Assert(err, IsNil) return store.SigningDB, checkDB }
func (gkms *gpgKeypairMgrSuite) TestUseInSigning(c *C) { store := assertstest.NewStoreStack("trusted", testPrivKey0, testPrivKey1) devKey, err := gkms.keypairMgr.Get(assertstest.DevKeyID) c.Assert(err, IsNil) devAcct := assertstest.NewAccount(store, "devel1", map[string]interface{}{ "account-id": "dev1-id", }, "") devAccKey := assertstest.NewAccountKey(store, devAcct, nil, devKey.PublicKey(), "") signDB, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: gkms.keypairMgr, }) c.Assert(err, IsNil) checkDB, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: store.Trusted, }) c.Assert(err, IsNil) // add store key err = checkDB.Add(store.StoreAccountKey("")) c.Assert(err, IsNil) // enable devel key err = checkDB.Add(devAcct) c.Assert(err, IsNil) err = checkDB.Add(devAccKey) c.Assert(err, IsNil) headers := map[string]interface{}{ "authority-id": "dev1-id", "snap-sha3-384": blobSHA3_384, "snap-id": "snap-id-1", "grade": "devel", "snap-size": "1025", "timestamp": time.Now().Format(time.RFC3339), } snapBuild, err := signDB.Sign(asserts.SnapBuildType, headers, nil, assertstest.DevKeyID) c.Assert(err, IsNil) err = checkDB.Check(snapBuild) c.Check(err, IsNil) }
func MakeFakeRefreshForSnaps(snaps []string, blobDir string) error { storePrivKey, _ := assertstest.ReadPrivKey(systestkeys.TestStorePrivKey) db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: asserts.NewMemoryKeypairManager(), Backstore: asserts.NewMemoryBackstore(), Trusted: sysdb.Trusted(), }) if err != nil { return err } // for signing db.ImportKey(storePrivKey) // XXX: ideally for consistency we should talk to the local snapd // but this allows us to go working until snapd itself // start being fully assertion using sto := store.New(nil, nil) retrieve := func(ref *asserts.Ref) (asserts.Assertion, error) { return sto.Assertion(ref.Type, ref.PrimaryKey, nil) } save := func(a asserts.Assertion) error { err := db.Add(a) if err != nil { if _, ok := err.(*asserts.RevisionError); !ok { return err } } return writeAssert(a, blobDir) } f := asserts.NewFetcher(db, retrieve, save) for _, snap := range snaps { if err := makeFakeRefreshForSnap(snap, blobDir, db, f); err != nil { return err } } return nil }
func fetchSnapAssertions(sto *store.Store, snapPath string, snapInfo *snap.Info, dlOpts *image.DownloadOptions) error { db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: sysdb.Trusted(), }) if err != nil { return err } w, err := os.Create(snapPath + ".assertions") if err != nil { return fmt.Errorf(i18n.G("cannot create assertions file: %v"), err) } defer w.Close() encoder := asserts.NewEncoder(w) save := func(a asserts.Assertion) error { return encoder.Encode(a) } f := image.StoreAssertionFetcher(sto, dlOpts, db, save) return image.FetchAndCheckSnapAssertions(snapPath, snapInfo, f, db) }
func (s *interfaceManagerSuite) SetUpTest(c *C) { s.storeSigning = assertstest.NewStoreStack("canonical", rootKey, storeKey) dirs.SetRootDir(c.MkDir()) state := state.New(nil) s.state = state db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: s.storeSigning.Trusted, }) c.Assert(err, IsNil) s.db = db err = db.Add(s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) s.state.Lock() assertstate.ReplaceDB(state, s.db) s.state.Unlock() s.privateMgr = nil s.extraIfaces = nil s.secBackend = &interfaces.TestSecurityBackend{} s.restoreBackends = ifacestate.MockSecurityBackends([]interfaces.SecurityBackend{s.secBackend}) }
func bootstrapToRootDir(sto Store, model *asserts.Model, opts *Options, local *localInfos) error { // FIXME: try to avoid doing this if opts.RootDir != "" { dirs.SetRootDir(opts.RootDir) defer dirs.SetRootDir("/") } // sanity check target if osutil.FileExists(dirs.SnapStateFile) { return fmt.Errorf("cannot bootstrap over existing system") } // TODO: developer database in home or use snapd (but need // a bit more API there, potential issues when crossing stores/series) db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ Backstore: asserts.NewMemoryBackstore(), Trusted: sysdb.Trusted(), }) if err != nil { return err } f := makeFetcher(sto, &DownloadOptions{}, db) if err := f.Save(model); err != nil { if !osutil.GetenvBool("UBUNTU_IMAGE_SKIP_COPY_UNVERIFIED_MODEL") { return fmt.Errorf("cannot fetch and check prerequisites for the model assertion: %v", err) } else { logger.Noticef("Cannot fetch and check prerequisites for the model assertion, it will not be copied into the image: %v", err) f.addedRefs = nil } } // put snaps in place if err := os.MkdirAll(dirs.SnapBlobDir, 0755); err != nil { return err } snapSeedDir := filepath.Join(dirs.SnapSeedDir, "snaps") assertSeedDir := filepath.Join(dirs.SnapSeedDir, "assertions") dlOpts := &DownloadOptions{ TargetDir: snapSeedDir, Channel: opts.Channel, DevMode: false, // XXX: should this be true? } for _, d := range []string{snapSeedDir, assertSeedDir} { if err := os.MkdirAll(d, 0755); err != nil { return err } } snaps := []string{} // core,kernel,gadget first snaps = append(snaps, local.PreferLocal(defaultCore)) snaps = append(snaps, local.PreferLocal(model.Kernel())) snaps = append(snaps, local.PreferLocal(model.Gadget())) // then required and the user requested stuff for _, snapName := range model.RequiredSnaps() { snaps = append(snaps, local.PreferLocal(snapName)) } snaps = append(snaps, opts.Snaps...) seen := make(map[string]bool) downloadedSnapsInfo := map[string]*snap.Info{} var seedYaml snap.Seed for _, snapName := range snaps { name := local.Name(snapName) if seen[name] { fmt.Fprintf(Stdout, "%s already prepared, skipping\n", name) continue } if name != snapName { fmt.Fprintf(Stdout, "Copying %q (%s)\n", snapName, name) } else { fmt.Fprintf(Stdout, "Fetching %s\n", snapName) } fn, info, err := acquireSnap(sto, name, dlOpts, local) if err != nil { return err } seen[name] = true // if it comes from the store fetch the snap assertions too // TODO: support somehow including available assertions // also for local snaps if info.SnapID != "" { err = FetchAndCheckSnapAssertions(fn, info, f, db) if err != nil { return err } } typ := info.Type // kernel/os are required for booting if typ == snap.TypeKernel || typ == snap.TypeOS { dst := filepath.Join(dirs.SnapBlobDir, filepath.Base(fn)) if err := osutil.CopyFile(fn, dst, 0); err != nil { return err } // store the snap.Info for kernel/os so // that the bootload can DTRT downloadedSnapsInfo[dst] = info } // set seed.yaml seedYaml.Snaps = append(seedYaml.Snaps, &snap.SeedSnap{ Name: info.Name(), SnapID: info.SnapID, // cross-ref Channel: info.Channel, File: filepath.Base(fn), DevMode: info.NeedsDevMode(), // no assertions for this snap were put in the seed Unasserted: info.SnapID == "", }) } for _, aRef := range f.addedRefs { var afn string // the names don't matter in practice as long as they don't conflict if aRef.Type == asserts.ModelType { afn = "model" } else { afn = fmt.Sprintf("%s.%s", strings.Join(aRef.PrimaryKey, ","), aRef.Type.Name) } a, err := aRef.Resolve(db.Find) if err != nil { return fmt.Errorf("internal error: lost saved assertion") } err = ioutil.WriteFile(filepath.Join(assertSeedDir, afn), asserts.Encode(a), 0644) if err != nil { return err } } // TODO: add the refs as an assertions list of maps section to seed.yaml seedFn := filepath.Join(dirs.SnapSeedDir, "seed.yaml") if err := seedYaml.Write(seedFn); err != nil { return fmt.Errorf("cannot write seed.yaml: %s", err) } // now do the bootloader stuff if err := partition.InstallBootConfig(opts.GadgetUnpackDir); err != nil { return err } if err := setBootvars(downloadedSnapsInfo); err != nil { return err } // and the cloud-init things if err := installCloudConfig(opts.GadgetUnpackDir); err != nil { return err } return nil }
// NewBatch creates a new Batch to accumulate assertions to add in one go to the system assertion database. func NewBatch() *Batch { return &Batch{ bs: asserts.NewMemoryBackstore(), refs: nil, } }
func (mbss *memBackstoreSuite) TestSearchFormat(c *C) { bs := asserts.NewMemoryBackstore() af0, err := asserts.Decode([]byte("type: test-only-2\n" + "authority-id: auth-id1\n" + "pk1: foo\n" + "pk2: bar\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) af1, err := asserts.Decode([]byte("type: test-only-2\n" + "authority-id: auth-id1\n" + "pk1: foo\n" + "pk2: bar\n" + "format: 1\n" + "revision: 1\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) af2, err := asserts.Decode([]byte("type: test-only-2\n" + "authority-id: auth-id1\n" + "pk1: foo\n" + "pk2: baz\n" + "format: 2\n" + "revision: 1\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" + "\n\n" + "AXNpZw==")) c.Assert(err, IsNil) err = bs.Put(asserts.TestOnly2Type, af0) c.Assert(err, IsNil) queries := []map[string]string{ {"pk1": "foo", "pk2": "bar"}, {"pk1": "foo"}, {"pk2": "bar"}, } for _, q := range queries { var a asserts.Assertion foundCb := func(a1 asserts.Assertion) { a = a1 } err := bs.Search(asserts.TestOnly2Type, q, foundCb, 1) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 0) } err = bs.Put(asserts.TestOnly2Type, af1) c.Assert(err, IsNil) for _, q := range queries { var a asserts.Assertion foundCb := func(a1 asserts.Assertion) { a = a1 } err := bs.Search(asserts.TestOnly2Type, q, foundCb, 1) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 1) err = bs.Search(asserts.TestOnly2Type, q, foundCb, 0) c.Assert(err, IsNil) c.Check(a.Revision(), Equals, 0) } err = bs.Put(asserts.TestOnly2Type, af2) c.Assert(err, IsNil) var as []asserts.Assertion foundCb := func(a1 asserts.Assertion) { as = append(as, a1) } err = bs.Search(asserts.TestOnly2Type, map[string]string{ "pk1": "foo", }, foundCb, 1) // will not find af2 c.Assert(err, IsNil) c.Check(as, HasLen, 1) c.Check(as[0].Revision(), Equals, 1) }