github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/asserts/membackstore_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016-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  	. "gopkg.in/check.v1"
    24  
    25  	"github.com/snapcore/snapd/asserts"
    26  )
    27  
    28  type memBackstoreSuite struct {
    29  	bs asserts.Backstore
    30  	a  asserts.Assertion
    31  }
    32  
    33  var _ = Suite(&memBackstoreSuite{})
    34  
    35  func (mbss *memBackstoreSuite) SetUpTest(c *C) {
    36  	mbss.bs = asserts.NewMemoryBackstore()
    37  
    38  	encoded := "type: test-only\n" +
    39  		"authority-id: auth-id1\n" +
    40  		"primary-key: foo\n" +
    41  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
    42  		"\n\n" +
    43  		"AXNpZw=="
    44  	a, err := asserts.Decode([]byte(encoded))
    45  	c.Assert(err, IsNil)
    46  	mbss.a = a
    47  }
    48  
    49  func (mbss *memBackstoreSuite) TestPutAndGet(c *C) {
    50  	err := mbss.bs.Put(asserts.TestOnlyType, mbss.a)
    51  	c.Assert(err, IsNil)
    52  
    53  	a, err := mbss.bs.Get(asserts.TestOnlyType, []string{"foo"}, 0)
    54  	c.Assert(err, IsNil)
    55  
    56  	c.Check(a, Equals, mbss.a)
    57  }
    58  
    59  func (mbss *memBackstoreSuite) TestGetNotFound(c *C) {
    60  	a, err := mbss.bs.Get(asserts.TestOnlyType, []string{"foo"}, 0)
    61  	c.Assert(err, DeepEquals, &asserts.NotFoundError{
    62  		Type: asserts.TestOnlyType,
    63  		// Headers can be omitted by Backstores
    64  	})
    65  	c.Check(a, IsNil)
    66  
    67  	err = mbss.bs.Put(asserts.TestOnlyType, mbss.a)
    68  	c.Assert(err, IsNil)
    69  
    70  	a, err = mbss.bs.Get(asserts.TestOnlyType, []string{"bar"}, 0)
    71  	c.Assert(err, DeepEquals, &asserts.NotFoundError{
    72  		Type: asserts.TestOnlyType,
    73  	})
    74  	c.Check(a, IsNil)
    75  }
    76  
    77  func (mbss *memBackstoreSuite) TestPutNotNewer(c *C) {
    78  	err := mbss.bs.Put(asserts.TestOnlyType, mbss.a)
    79  	c.Assert(err, IsNil)
    80  
    81  	err = mbss.bs.Put(asserts.TestOnlyType, mbss.a)
    82  	c.Check(err, ErrorMatches, "revision 0 is already the current revision")
    83  }
    84  
    85  func (mbss *memBackstoreSuite) TestSearch(c *C) {
    86  	encoded := "type: test-only\n" +
    87  		"authority-id: auth-id1\n" +
    88  		"primary-key: one\n" +
    89  		"other: other1\n" +
    90  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
    91  		"\n\n" +
    92  		"AXNpZw=="
    93  	a1, err := asserts.Decode([]byte(encoded))
    94  	c.Assert(err, IsNil)
    95  
    96  	encoded = "type: test-only\n" +
    97  		"authority-id: auth-id1\n" +
    98  		"primary-key: two\n" +
    99  		"other: other2\n" +
   100  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   101  		"\n\n" +
   102  		"AXNpZw=="
   103  	a2, err := asserts.Decode([]byte(encoded))
   104  	c.Assert(err, IsNil)
   105  
   106  	err = mbss.bs.Put(asserts.TestOnlyType, a1)
   107  	c.Assert(err, IsNil)
   108  	err = mbss.bs.Put(asserts.TestOnlyType, a2)
   109  	c.Assert(err, IsNil)
   110  
   111  	found := map[string]asserts.Assertion{}
   112  	cb := func(a asserts.Assertion) {
   113  		found[a.HeaderString("primary-key")] = a
   114  	}
   115  	err = mbss.bs.Search(asserts.TestOnlyType, nil, cb, 0)
   116  	c.Assert(err, IsNil)
   117  	c.Check(found, HasLen, 2)
   118  
   119  	found = map[string]asserts.Assertion{}
   120  	err = mbss.bs.Search(asserts.TestOnlyType, map[string]string{
   121  		"primary-key": "one",
   122  	}, cb, 0)
   123  	c.Assert(err, IsNil)
   124  	c.Check(found, DeepEquals, map[string]asserts.Assertion{
   125  		"one": a1,
   126  	})
   127  
   128  	found = map[string]asserts.Assertion{}
   129  	err = mbss.bs.Search(asserts.TestOnlyType, map[string]string{
   130  		"other": "other2",
   131  	}, cb, 0)
   132  	c.Assert(err, IsNil)
   133  	c.Check(found, DeepEquals, map[string]asserts.Assertion{
   134  		"two": a2,
   135  	})
   136  
   137  	found = map[string]asserts.Assertion{}
   138  	err = mbss.bs.Search(asserts.TestOnlyType, map[string]string{
   139  		"primary-key": "two",
   140  		"other":       "other1",
   141  	}, cb, 0)
   142  	c.Assert(err, IsNil)
   143  	c.Check(found, HasLen, 0)
   144  }
   145  
   146  func (mbss *memBackstoreSuite) TestSearch2Levels(c *C) {
   147  	encoded := "type: test-only-2\n" +
   148  		"authority-id: auth-id1\n" +
   149  		"pk1: a\n" +
   150  		"pk2: x\n" +
   151  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   152  		"\n\n" +
   153  		"AXNpZw=="
   154  	aAX, err := asserts.Decode([]byte(encoded))
   155  	c.Assert(err, IsNil)
   156  
   157  	encoded = "type: test-only-2\n" +
   158  		"authority-id: auth-id1\n" +
   159  		"pk1: b\n" +
   160  		"pk2: x\n" +
   161  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   162  		"\n\n" +
   163  		"AXNpZw=="
   164  	aBX, err := asserts.Decode([]byte(encoded))
   165  	c.Assert(err, IsNil)
   166  
   167  	err = mbss.bs.Put(asserts.TestOnly2Type, aAX)
   168  	c.Assert(err, IsNil)
   169  	err = mbss.bs.Put(asserts.TestOnly2Type, aBX)
   170  	c.Assert(err, IsNil)
   171  
   172  	found := map[string]asserts.Assertion{}
   173  	cb := func(a asserts.Assertion) {
   174  		found[a.HeaderString("pk1")+":"+a.HeaderString("pk2")] = a
   175  	}
   176  	err = mbss.bs.Search(asserts.TestOnly2Type, map[string]string{
   177  		"pk2": "x",
   178  	}, cb, 0)
   179  	c.Assert(err, IsNil)
   180  	c.Check(found, HasLen, 2)
   181  }
   182  
   183  func (mbss *memBackstoreSuite) TestPutOldRevision(c *C) {
   184  	bs := asserts.NewMemoryBackstore()
   185  
   186  	// Create two revisions of assertion.
   187  	a0, err := asserts.Decode([]byte("type: test-only\n" +
   188  		"authority-id: auth-id1\n" +
   189  		"primary-key: foo\n" +
   190  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   191  		"\n\n" +
   192  		"AXNpZw=="))
   193  	c.Assert(err, IsNil)
   194  	a1, err := asserts.Decode([]byte("type: test-only\n" +
   195  		"authority-id: auth-id1\n" +
   196  		"primary-key: foo\n" +
   197  		"revision: 1\n" +
   198  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   199  		"\n\n" +
   200  		"AXNpZw=="))
   201  	c.Assert(err, IsNil)
   202  
   203  	// Put newer revision, follwed by old revision.
   204  	err = bs.Put(asserts.TestOnlyType, a1)
   205  	c.Assert(err, IsNil)
   206  	err = bs.Put(asserts.TestOnlyType, a0)
   207  
   208  	c.Check(err, ErrorMatches, `revision 0 is older than current revision 1`)
   209  	c.Check(err, DeepEquals, &asserts.RevisionError{Current: 1, Used: 0})
   210  }
   211  
   212  func (mbss *memBackstoreSuite) TestGetFormat(c *C) {
   213  	bs := asserts.NewMemoryBackstore()
   214  
   215  	af0, err := asserts.Decode([]byte("type: test-only\n" +
   216  		"authority-id: auth-id1\n" +
   217  		"primary-key: foo\n" +
   218  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   219  		"\n\n" +
   220  		"AXNpZw=="))
   221  	c.Assert(err, IsNil)
   222  	af1, err := asserts.Decode([]byte("type: test-only\n" +
   223  		"authority-id: auth-id1\n" +
   224  		"primary-key: foo\n" +
   225  		"format: 1\n" +
   226  		"revision: 1\n" +
   227  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   228  		"\n\n" +
   229  		"AXNpZw=="))
   230  	c.Assert(err, IsNil)
   231  	af2, err := asserts.Decode([]byte("type: test-only\n" +
   232  		"authority-id: auth-id1\n" +
   233  		"primary-key: zoo\n" +
   234  		"format: 2\n" +
   235  		"revision: 22\n" +
   236  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   237  		"\n\n" +
   238  		"AXNpZw=="))
   239  	c.Assert(err, IsNil)
   240  
   241  	err = bs.Put(asserts.TestOnlyType, af0)
   242  	c.Assert(err, IsNil)
   243  	err = bs.Put(asserts.TestOnlyType, af1)
   244  	c.Assert(err, IsNil)
   245  
   246  	a, err := bs.Get(asserts.TestOnlyType, []string{"foo"}, 1)
   247  	c.Assert(err, IsNil)
   248  	c.Check(a.Revision(), Equals, 1)
   249  
   250  	a, err = bs.Get(asserts.TestOnlyType, []string{"foo"}, 0)
   251  	c.Assert(err, IsNil)
   252  	c.Check(a.Revision(), Equals, 0)
   253  
   254  	a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 0)
   255  	c.Assert(err, FitsTypeOf, &asserts.NotFoundError{})
   256  
   257  	err = bs.Put(asserts.TestOnlyType, af2)
   258  	c.Assert(err, IsNil)
   259  
   260  	a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 1)
   261  	c.Assert(err, FitsTypeOf, &asserts.NotFoundError{})
   262  
   263  	a, err = bs.Get(asserts.TestOnlyType, []string{"zoo"}, 2)
   264  	c.Assert(err, IsNil)
   265  	c.Check(a.Revision(), Equals, 22)
   266  }
   267  
   268  func (mbss *memBackstoreSuite) TestSearchFormat(c *C) {
   269  	bs := asserts.NewMemoryBackstore()
   270  
   271  	af0, err := asserts.Decode([]byte("type: test-only-2\n" +
   272  		"authority-id: auth-id1\n" +
   273  		"pk1: foo\n" +
   274  		"pk2: bar\n" +
   275  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   276  		"\n\n" +
   277  		"AXNpZw=="))
   278  	c.Assert(err, IsNil)
   279  	af1, err := asserts.Decode([]byte("type: test-only-2\n" +
   280  		"authority-id: auth-id1\n" +
   281  		"pk1: foo\n" +
   282  		"pk2: bar\n" +
   283  		"format: 1\n" +
   284  		"revision: 1\n" +
   285  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   286  		"\n\n" +
   287  		"AXNpZw=="))
   288  	c.Assert(err, IsNil)
   289  
   290  	af2, err := asserts.Decode([]byte("type: test-only-2\n" +
   291  		"authority-id: auth-id1\n" +
   292  		"pk1: foo\n" +
   293  		"pk2: baz\n" +
   294  		"format: 2\n" +
   295  		"revision: 1\n" +
   296  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   297  		"\n\n" +
   298  		"AXNpZw=="))
   299  	c.Assert(err, IsNil)
   300  
   301  	err = bs.Put(asserts.TestOnly2Type, af0)
   302  	c.Assert(err, IsNil)
   303  
   304  	queries := []map[string]string{
   305  		{"pk1": "foo", "pk2": "bar"},
   306  		{"pk1": "foo"},
   307  		{"pk2": "bar"},
   308  	}
   309  
   310  	for _, q := range queries {
   311  		var a asserts.Assertion
   312  		foundCb := func(a1 asserts.Assertion) {
   313  			a = a1
   314  		}
   315  		err := bs.Search(asserts.TestOnly2Type, q, foundCb, 1)
   316  		c.Assert(err, IsNil)
   317  		c.Check(a.Revision(), Equals, 0)
   318  	}
   319  
   320  	err = bs.Put(asserts.TestOnly2Type, af1)
   321  	c.Assert(err, IsNil)
   322  
   323  	for _, q := range queries {
   324  		var a asserts.Assertion
   325  		foundCb := func(a1 asserts.Assertion) {
   326  			a = a1
   327  		}
   328  		err := bs.Search(asserts.TestOnly2Type, q, foundCb, 1)
   329  		c.Assert(err, IsNil)
   330  		c.Check(a.Revision(), Equals, 1)
   331  
   332  		err = bs.Search(asserts.TestOnly2Type, q, foundCb, 0)
   333  		c.Assert(err, IsNil)
   334  		c.Check(a.Revision(), Equals, 0)
   335  	}
   336  
   337  	err = bs.Put(asserts.TestOnly2Type, af2)
   338  	c.Assert(err, IsNil)
   339  
   340  	var as []asserts.Assertion
   341  	foundCb := func(a1 asserts.Assertion) {
   342  		as = append(as, a1)
   343  	}
   344  	err = bs.Search(asserts.TestOnly2Type, map[string]string{
   345  		"pk1": "foo",
   346  	}, foundCb, 1) // will not find af2
   347  	c.Assert(err, IsNil)
   348  	c.Check(as, HasLen, 1)
   349  	c.Check(as[0].Revision(), Equals, 1)
   350  
   351  }
   352  
   353  func (mbss *memBackstoreSuite) TestPutSequence(c *C) {
   354  	bs := asserts.NewMemoryBackstore()
   355  
   356  	sq1f0, err := asserts.Decode([]byte("type: test-only-seq\n" +
   357  		"authority-id: auth-id1\n" +
   358  		"n: s1\n" +
   359  		"sequence: 1\n" +
   360  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   361  		"\n\n" +
   362  		"AXNpZw=="))
   363  	c.Assert(err, IsNil)
   364  
   365  	sq2f0, err := asserts.Decode([]byte("type: test-only-seq\n" +
   366  		"authority-id: auth-id1\n" +
   367  		"n: s1\n" +
   368  		"sequence: 2\n" +
   369  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   370  		"\n\n" +
   371  		"AXNpZw=="))
   372  	c.Assert(err, IsNil)
   373  
   374  	sq2f1, err := asserts.Decode([]byte("type: test-only-seq\n" +
   375  		"authority-id: auth-id1\n" +
   376  		"format: 1\n" +
   377  		"n: s1\n" +
   378  		"sequence: 2\n" +
   379  		"revision: 1\n" +
   380  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   381  		"\n\n" +
   382  		"AXNpZw=="))
   383  	c.Assert(err, IsNil)
   384  
   385  	sq3f1, err := asserts.Decode([]byte("type: test-only-seq\n" +
   386  		"authority-id: auth-id1\n" +
   387  		"format: 1\n" +
   388  		"n: s1\n" +
   389  		"sequence: 3\n" +
   390  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   391  		"\n\n" +
   392  		"AXNpZw=="))
   393  	c.Assert(err, IsNil)
   394  
   395  	for _, a := range []asserts.Assertion{sq3f1, sq1f0, sq2f0, sq2f1} {
   396  		err = bs.Put(asserts.TestOnlySeqType, a)
   397  		c.Assert(err, IsNil)
   398  	}
   399  
   400  	a, err := bs.Get(asserts.TestOnlySeqType, []string{"s1", "1"}, 0)
   401  	c.Assert(err, IsNil)
   402  	c.Check(a.(asserts.SequenceMember).Sequence(), Equals, 1)
   403  	c.Check(a.Format(), Equals, 0)
   404  
   405  	a, err = bs.Get(asserts.TestOnlySeqType, []string{"s1", "2"}, 0)
   406  	c.Assert(err, IsNil)
   407  	c.Check(a.(asserts.SequenceMember).Sequence(), Equals, 2)
   408  	c.Check(a.Format(), Equals, 0)
   409  
   410  	a, err = bs.Get(asserts.TestOnlySeqType, []string{"s1", "2"}, 1)
   411  	c.Assert(err, IsNil)
   412  	c.Check(a.(asserts.SequenceMember).Sequence(), Equals, 2)
   413  	c.Check(a.Format(), Equals, 1)
   414  
   415  	a, err = bs.Get(asserts.TestOnlySeqType, []string{"s1", "3"}, 0)
   416  	c.Assert(err, DeepEquals, &asserts.NotFoundError{
   417  		Type: asserts.TestOnlySeqType,
   418  	})
   419  
   420  	a, err = bs.Get(asserts.TestOnlySeqType, []string{"s1", "3"}, 1)
   421  	c.Assert(err, IsNil)
   422  	c.Check(a.(asserts.SequenceMember).Sequence(), Equals, 3)
   423  	c.Check(a.Format(), Equals, 1)
   424  
   425  	err = bs.Put(asserts.TestOnlySeqType, sq2f0)
   426  	c.Check(err, DeepEquals, &asserts.RevisionError{Current: 1, Used: 0})
   427  }
   428  
   429  func (mbss *memBackstoreSuite) TestSequenceMemberAfter(c *C) {
   430  	bs := asserts.NewMemoryBackstore()
   431  
   432  	other1, err := asserts.Decode([]byte("type: test-only-seq\n" +
   433  		"authority-id: auth-id1\n" +
   434  		"n: other\n" +
   435  		"sequence: 1\n" +
   436  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   437  		"\n\n" +
   438  		"AXNpZw=="))
   439  	c.Assert(err, IsNil)
   440  
   441  	sq1f0, err := asserts.Decode([]byte("type: test-only-seq\n" +
   442  		"authority-id: auth-id1\n" +
   443  		"n: s1\n" +
   444  		"sequence: 1\n" +
   445  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   446  		"\n\n" +
   447  		"AXNpZw=="))
   448  	c.Assert(err, IsNil)
   449  
   450  	sq2f0, err := asserts.Decode([]byte("type: test-only-seq\n" +
   451  		"authority-id: auth-id1\n" +
   452  		"n: s1\n" +
   453  		"sequence: 2\n" +
   454  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   455  		"\n\n" +
   456  		"AXNpZw=="))
   457  	c.Assert(err, IsNil)
   458  
   459  	sq2f1, err := asserts.Decode([]byte("type: test-only-seq\n" +
   460  		"authority-id: auth-id1\n" +
   461  		"format: 1\n" +
   462  		"n: s1\n" +
   463  		"sequence: 2\n" +
   464  		"revision: 1\n" +
   465  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   466  		"\n\n" +
   467  		"AXNpZw=="))
   468  	c.Assert(err, IsNil)
   469  
   470  	sq3f1, err := asserts.Decode([]byte("type: test-only-seq\n" +
   471  		"authority-id: auth-id1\n" +
   472  		"format: 1\n" +
   473  		"n: s1\n" +
   474  		"sequence: 3\n" +
   475  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   476  		"\n\n" +
   477  		"AXNpZw=="))
   478  	c.Assert(err, IsNil)
   479  
   480  	sq3f2, err := asserts.Decode([]byte("type: test-only-seq\n" +
   481  		"authority-id: auth-id1\n" +
   482  		"format: 2\n" +
   483  		"n: s1\n" +
   484  		"sequence: 3\n" +
   485  		"revision: 1\n" +
   486  		"sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij" +
   487  		"\n\n" +
   488  		"AXNpZw=="))
   489  	c.Assert(err, IsNil)
   490  
   491  	for _, a := range []asserts.Assertion{other1, sq1f0, sq2f0, sq2f1, sq3f1, sq3f2} {
   492  		err = bs.Put(asserts.TestOnlySeqType, a)
   493  		c.Assert(err, IsNil)
   494  	}
   495  
   496  	seqKey := []string{"s1"}
   497  	tests := []struct {
   498  		after     int
   499  		maxFormat int
   500  		sequence  int
   501  		format    int
   502  		revision  int
   503  	}{
   504  		{after: 0, maxFormat: 0, sequence: 1, format: 0, revision: 0},
   505  		{after: 0, maxFormat: 2, sequence: 1, format: 0, revision: 0},
   506  		{after: 1, maxFormat: 0, sequence: 2, format: 0, revision: 0},
   507  		{after: 1, maxFormat: 1, sequence: 2, format: 1, revision: 1},
   508  		{after: 1, maxFormat: 2, sequence: 2, format: 1, revision: 1},
   509  		{after: 2, maxFormat: 0, sequence: -1},
   510  		{after: 2, maxFormat: 1, sequence: 3, format: 1, revision: 0},
   511  		{after: 2, maxFormat: 2, sequence: 3, format: 2, revision: 1},
   512  		{after: 3, maxFormat: 0, sequence: -1},
   513  		{after: 3, maxFormat: 2, sequence: -1},
   514  		{after: 4, maxFormat: 2, sequence: -1},
   515  		{after: -1, maxFormat: 0, sequence: 2, format: 0, revision: 0},
   516  		{after: -1, maxFormat: 1, sequence: 3, format: 1, revision: 0},
   517  		{after: -1, maxFormat: 2, sequence: 3, format: 2, revision: 1},
   518  	}
   519  
   520  	for _, t := range tests {
   521  		a, err := bs.SequenceMemberAfter(asserts.TestOnlySeqType, seqKey, t.after, t.maxFormat)
   522  		if t.sequence == -1 {
   523  			c.Check(err, DeepEquals, &asserts.NotFoundError{
   524  				Type: asserts.TestOnlySeqType,
   525  			})
   526  		} else {
   527  			c.Assert(err, IsNil)
   528  			c.Assert(a.HeaderString("n"), Equals, "s1")
   529  			c.Check(a.Sequence(), Equals, t.sequence)
   530  			c.Check(a.Format(), Equals, t.format)
   531  			c.Check(a.Revision(), Equals, t.revision)
   532  		}
   533  	}
   534  
   535  	_, err = bs.SequenceMemberAfter(asserts.TestOnlySeqType, []string{"s2"}, -1, 2)
   536  	c.Check(err, DeepEquals, &asserts.NotFoundError{
   537  		Type: asserts.TestOnlySeqType,
   538  	})
   539  }