github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/bootloader/assets/assets_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package assets_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"github.com/snapcore/snapd/bootloader/assets"
    26  	"github.com/snapcore/snapd/testutil"
    27  )
    28  
    29  type assetsTestSuite struct {
    30  	testutil.BaseTest
    31  }
    32  
    33  var _ = Suite(&assetsTestSuite{})
    34  
    35  func (s *assetsTestSuite) SetUpTest(c *C) {
    36  	s.BaseTest.SetUpTest(c)
    37  	s.AddCleanup(assets.MockCleanState())
    38  }
    39  
    40  func (s *assetsTestSuite) TestRegisterInternalSimple(c *C) {
    41  	assets.RegisterInternal("foo", []byte("bar"))
    42  	data := assets.Internal("foo")
    43  	c.Check(data, DeepEquals, []byte("bar"))
    44  
    45  	complexData := `this is "some
    46  complex binary " data
    47  `
    48  	assets.RegisterInternal("complex-data", []byte(complexData))
    49  	complex := assets.Internal("complex-data")
    50  	c.Check(complex, DeepEquals, []byte(complexData))
    51  
    52  	nodata := assets.Internal("no data")
    53  	c.Check(nodata, IsNil)
    54  }
    55  
    56  func (s *assetsTestSuite) TestRegisterDoublePanics(c *C) {
    57  	assets.RegisterInternal("foo", []byte("foo"))
    58  	// panics with the same key, no matter the data used
    59  	c.Assert(func() { assets.RegisterInternal("foo", []byte("bar")) },
    60  		PanicMatches, `asset "foo" is already registered`)
    61  	c.Assert(func() { assets.RegisterInternal("foo", []byte("foo")) },
    62  		PanicMatches, `asset "foo" is already registered`)
    63  }
    64  
    65  func (s *assetsTestSuite) TestRegisterSnippetPanics(c *C) {
    66  	assets.RegisterSnippetForEditions("foo", []assets.ForEditions{
    67  		{FirstEdition: 1, Snippet: []byte("foo")},
    68  	})
    69  	// panics with the same key
    70  	c.Assert(func() {
    71  		assets.RegisterSnippetForEditions("foo", []assets.ForEditions{
    72  			{FirstEdition: 2, Snippet: []byte("bar")},
    73  		})
    74  	}, PanicMatches, `edition snippets "foo" are already registered`)
    75  	// panics when snippets aren't sorted
    76  	c.Assert(func() {
    77  		assets.RegisterSnippetForEditions("unsorted", []assets.ForEditions{
    78  			{FirstEdition: 2, Snippet: []byte("two")},
    79  			{FirstEdition: 1, Snippet: []byte("one")},
    80  		})
    81  	}, PanicMatches, `cannot validate snippets "unsorted": snippets must be sorted in ascending edition number order`)
    82  	// panics when edition is repeated
    83  	c.Assert(func() {
    84  		assets.RegisterSnippetForEditions("doubled edition", []assets.ForEditions{
    85  			{FirstEdition: 1, Snippet: []byte("one")},
    86  			{FirstEdition: 2, Snippet: []byte("two")},
    87  			{FirstEdition: 3, Snippet: []byte("three")},
    88  			{FirstEdition: 3, Snippet: []byte("more tree")},
    89  			{FirstEdition: 4, Snippet: []byte("four")},
    90  		})
    91  	}, PanicMatches, `cannot validate snippets "doubled edition": first edition 3 repeated`)
    92  	// mix unsorted with duplicate edition
    93  	c.Assert(func() {
    94  		assets.RegisterSnippetForEditions("unsorted and doubled edition", []assets.ForEditions{
    95  			{FirstEdition: 1, Snippet: []byte("one")},
    96  			{FirstEdition: 2, Snippet: []byte("two")},
    97  			{FirstEdition: 1, Snippet: []byte("one again")},
    98  			{FirstEdition: 3, Snippet: []byte("more tree")},
    99  			{FirstEdition: 4, Snippet: []byte("four")},
   100  		})
   101  	}, PanicMatches, `cannot validate snippets "unsorted and doubled edition": snippets must be sorted in ascending edition number order`)
   102  }
   103  
   104  func (s *assetsTestSuite) TestEditionSnippets(c *C) {
   105  	assets.RegisterSnippetForEditions("foo", []assets.ForEditions{
   106  		{FirstEdition: 1, Snippet: []byte("one")},
   107  		{FirstEdition: 2, Snippet: []byte("two")},
   108  		{FirstEdition: 3, Snippet: []byte("three")},
   109  		{FirstEdition: 4, Snippet: []byte("four")},
   110  		{FirstEdition: 10, Snippet: []byte("ten")},
   111  		{FirstEdition: 20, Snippet: []byte("twenty")},
   112  	})
   113  	assets.RegisterSnippetForEditions("bar", []assets.ForEditions{
   114  		{FirstEdition: 1, Snippet: []byte("bar one")},
   115  		{FirstEdition: 3, Snippet: []byte("bar three")},
   116  		// same as 3
   117  		{FirstEdition: 5, Snippet: []byte("bar three")},
   118  	})
   119  	assets.RegisterSnippetForEditions("just-one", []assets.ForEditions{
   120  		{FirstEdition: 2, Snippet: []byte("just one")},
   121  	})
   122  
   123  	for _, tc := range []struct {
   124  		asset   string
   125  		edition uint
   126  		exp     []byte
   127  	}{
   128  		{"foo", 1, []byte("one")},
   129  		{"foo", 4, []byte("four")},
   130  		{"foo", 10, []byte("ten")},
   131  		// still using snipped from edition 4
   132  		{"foo", 9, []byte("four")},
   133  		// still using snipped from edition 10
   134  		{"foo", 11, []byte("ten")},
   135  		{"foo", 30, []byte("twenty")},
   136  		// different asset
   137  		{"bar", 1, []byte("bar one")},
   138  		{"bar", 2, []byte("bar one")},
   139  		{"bar", 3, []byte("bar three")},
   140  		{"bar", 4, []byte("bar three")},
   141  		{"bar", 5, []byte("bar three")},
   142  		{"bar", 6, []byte("bar three")},
   143  		// nothing registered for edition 0
   144  		{"bar", 0, nil},
   145  		// a single snippet under this key
   146  		{"just-one", 2, []byte("just one")},
   147  		{"just-one", 1, nil},
   148  		// asset not registered
   149  		{"no asset", 1, nil},
   150  		{"no asset", 100, nil},
   151  	} {
   152  		c.Logf("%q edition %v", tc.asset, tc.edition)
   153  		snippet := assets.SnippetForEdition(tc.asset, tc.edition)
   154  		c.Check(snippet, DeepEquals, tc.exp)
   155  	}
   156  }