github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/patch/patch1_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016 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 patch_test
    21  
    22  import (
    23  	"errors"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  
    28  	. "gopkg.in/check.v1"
    29  
    30  	"github.com/snapcore/snapd/dirs"
    31  	"github.com/snapcore/snapd/overlord/patch"
    32  	"github.com/snapcore/snapd/overlord/snapstate"
    33  	"github.com/snapcore/snapd/overlord/state"
    34  	"github.com/snapcore/snapd/snap"
    35  )
    36  
    37  type patch1Suite struct{}
    38  
    39  var _ = Suite(&patch1Suite{})
    40  
    41  var statePatch1JSON = []byte(`
    42  {
    43  	"data": {
    44                  "patch-level": 0,
    45  		"snaps": {
    46  			"foo": {
    47  				"sequence": [{
    48  					"name": "foo1",
    49  					"revision": "2"
    50  				}, {
    51  					"name": "foo1",
    52  					"revision": "22"
    53  				}]
    54  			},
    55  
    56  			"core": {
    57  				"sequence": [{
    58  					"name": "core",
    59  					"revision": "1"
    60  				}, {
    61  					"name": "core",
    62  					"revision": "11"
    63  				}, {
    64  					"name": "core",
    65  					"revision": "111"
    66  				}]
    67  			},
    68  
    69  			"borken": {
    70  				"sequence": [{
    71  					"name": "borken",
    72  					"revision": "x1"
    73  				}, {
    74  					"name": "borken",
    75  					"revision": "x2"
    76  				}]
    77  			},
    78  
    79  			"wip": {
    80  				"candidate": {
    81  					"name": "wip",
    82  					"revision": "11"
    83  				}
    84  			}
    85  		}
    86  	}
    87  }
    88  `)
    89  
    90  func (s *patch1Suite) SetUpTest(c *C) {
    91  	dirs.SetRootDir(c.MkDir())
    92  
    93  	err := os.MkdirAll(filepath.Dir(dirs.SnapStateFile), 0755)
    94  	c.Assert(err, IsNil)
    95  	err = ioutil.WriteFile(dirs.SnapStateFile, statePatch1JSON, 0644)
    96  	c.Assert(err, IsNil)
    97  }
    98  
    99  func (s *patch1Suite) TestPatch1(c *C) {
   100  	restore := patch.MockPatch1ReadType(s.readType)
   101  	defer restore()
   102  
   103  	r, err := os.Open(dirs.SnapStateFile)
   104  	c.Assert(err, IsNil)
   105  	defer r.Close()
   106  	st, err := state.ReadState(nil, r)
   107  	c.Assert(err, IsNil)
   108  
   109  	// go from patch-level 0 to patch-level 1
   110  	restorer := patch.MockLevel(1, 1)
   111  	defer restorer()
   112  
   113  	err = patch.Apply(st)
   114  	c.Assert(err, IsNil)
   115  
   116  	st.Lock()
   117  	defer st.Unlock()
   118  
   119  	expected := []struct {
   120  		name string
   121  		typ  snap.Type
   122  		cur  snap.Revision
   123  	}{
   124  		{"foo", snap.TypeApp, snap.R(22)},
   125  		{"core", snap.TypeOS, snap.R(111)},
   126  		{"borken", snap.TypeApp, snap.R(-2)},
   127  		{"wip", "", snap.R(0)},
   128  	}
   129  
   130  	for _, exp := range expected {
   131  		var snapst snapstate.SnapState
   132  		err := snapstate.Get(st, exp.name, &snapst)
   133  		c.Assert(err, IsNil)
   134  		c.Check(snap.Type(snapst.SnapType), Equals, exp.typ)
   135  		c.Check(snapst.Current, Equals, exp.cur)
   136  	}
   137  
   138  	// ensure we only moved forward to patch-level 1
   139  	var patchLevel int
   140  	err = st.Get("patch-level", &patchLevel)
   141  	c.Assert(err, IsNil)
   142  	c.Assert(patchLevel, Equals, 1)
   143  }
   144  
   145  func (s *patch1Suite) readType(name string, rev snap.Revision) (snap.Type, error) {
   146  	if name == "borken" {
   147  		return snap.TypeApp, errors.New(`cannot read info for "borken" snap`)
   148  	}
   149  	// naive emulation for now, always works
   150  	if name == "gadget" {
   151  		return snap.TypeGadget, nil
   152  	}
   153  	if name == "core" {
   154  		return snap.TypeOS, nil
   155  	}
   156  
   157  	return snap.TypeApp, nil
   158  }