github.com/rigado/snapd@v2.42.5-go-mod+incompatible/overlord/patch/patch6_2_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2019 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  	"bytes"
    24  
    25  	. "gopkg.in/check.v1"
    26  
    27  	"github.com/snapcore/snapd/dirs"
    28  	"github.com/snapcore/snapd/overlord/patch"
    29  	"github.com/snapcore/snapd/overlord/snapstate"
    30  	"github.com/snapcore/snapd/overlord/state"
    31  	"github.com/snapcore/snapd/snap"
    32  )
    33  
    34  type patch62Suite struct{}
    35  
    36  var _ = Suite(&patch62Suite{})
    37  
    38  // State with snapd snap marked as 'app' (to be converted to 'snapd' type) and a regular 'other' snap,
    39  // plus three tasks - two of them need to have their SnapSetup migrated to 'snapd' type.
    40  var statePatch6_2JSON = []byte(`
    41  {
    42  	"data": {
    43  		"patch-level": 6,
    44  		"snaps": {
    45  		  "snapd": {
    46  			"type": "app",
    47  			"sequence": [
    48  			  {
    49  				"name": "snapd",
    50  				"snap-id": "snapd-snap-id",
    51  				"revision": "2"
    52  			  }
    53  			],
    54  			"active": true,
    55  			"current": "2",
    56  			"channel": "stable"
    57  		  },
    58  		  "other": {
    59  			"type": "app",
    60  			"sequence": [
    61  			  {
    62  				"name": "snapd",
    63  				"snap-id": "foo",
    64  				"revision": "2"
    65  			  }
    66  			],
    67  			"active": true,
    68  			"current": "2",
    69  			"channel": "stable"
    70  		  }
    71  		}
    72  	  },
    73  	  "changes": {
    74  			"6": {
    75  				"id": "6",
    76  				"kind": "auto-refresh",
    77  				"summary": "...",
    78  				"status": 0,
    79  				"clean": true,
    80  				"data": {
    81  				"api-data": {
    82  					"snap-names": ["snapd"]
    83  				},
    84  				"snap-names": ["snapd"]
    85  				},
    86  				"task-ids": ["1", "8"]
    87  			},
    88  			"9": {
    89  				"id": "9",
    90  				"kind": "auto-refresh",
    91  				"summary": "...",
    92  				"status": 4,
    93  				"clean": true,
    94  				"data": {
    95  				"api-data": {
    96  					"snap-names": ["snapd"]
    97  				},
    98  				"snap-names": ["snapd"]
    99  				},
   100  				"task-ids": ["10"]
   101  			}
   102  	  },
   103  	  "tasks": {
   104  		"1": {
   105  			"id": "1",
   106  			"kind": "download-snap",
   107  			"summary": "...",
   108  			"status": 2,
   109  			"clean": true,
   110  			"data": {
   111  			  "snap-setup": {
   112  				"channel": "stable",
   113  				"type": "app",
   114  				"is-auto-refresh": true,
   115  				"snap-path": "/path",
   116  				"download-info": {
   117  				  "download-url": "foo",
   118  				  "size": 1234,
   119  				  "sha3-384": "123456",
   120  				  "deltas": [
   121  					{
   122  					  "from-revision": 10934,
   123  					  "to-revision": 10972,
   124  					  "format": "xdelta3",
   125  					  "download-url": "foo",
   126  					  "size": 16431136,
   127  					  "sha3-384": "1"
   128  					}
   129  				  ]
   130  				},
   131  				"side-info": {
   132  				  "name": "snapd",
   133  				  "snap-id": "snapd-snap-id",
   134  				  "revision": "1",
   135  				  "channel": "stable",
   136  				  "title": "snapd"
   137  				},
   138  				"media": [
   139  				  {
   140  					"type": "icon",
   141  					"url": "a"
   142  				  },
   143  				  {
   144  					"type": "screenshot",
   145  					"url": "2"
   146  				  },
   147  				  {
   148  					"type": "screenshot",
   149  					"url": "3"
   150  				  },
   151  				  {
   152  					"type": "screenshot",
   153  					"url": "4"
   154  				  },
   155  				  {
   156  					"type": "video",
   157  					"url": "5"
   158  				  }
   159  				]
   160  			  }
   161  			},
   162  			"change": "6"
   163  		  },
   164  		  "8": {
   165  			"id": "8",
   166  			"kind": "other",
   167  			"summary": "",
   168  			"status": 4,
   169  			"data": {
   170  			  "snap-setup": {
   171  				"channel": "stable",
   172  				"type": "app",
   173  				"snap-path": "/path",
   174  				"side-info": {
   175  				  "name": "snapd",
   176  				  "snap-id": "snapd-snap-id",
   177  				  "revision": "1",
   178  				  "channel": "stable",
   179  				  "title": "snapd"
   180  				}
   181  			  }
   182  			},
   183  			"change": "6"
   184  		  },
   185  		  "10": {
   186  			"id": "10",
   187  			"kind": "other",
   188  			"summary": "",
   189  			"status": 4,
   190  			"data": {
   191  			  "snap-setup": {
   192  				"channel": "stable",
   193  				"type": "app",
   194  				"snap-path": "/path",
   195  				"side-info": {
   196  				  "name": "snapd",
   197  				  "snap-id": "snapd-snap-id",
   198  				  "revision": "1",
   199  				  "channel": "stable",
   200  				  "title": "snapd"
   201  				}
   202  			  }
   203  			},
   204  			"change": "9"
   205  		  }
   206  		}
   207  	  }
   208  	}
   209  }`)
   210  
   211  // State with 'snapd' snap with proper snap type, and an extra 'other' snap
   212  // with snapd-snap-id but improper 'app' type.
   213  var statePatch6_2JSONWithSnapd = []byte(`
   214  {
   215  	"data": {
   216  		"patch-level": 6,
   217  		"snaps": {
   218  		  "snapd": {
   219  			"type": "snapd",
   220  			"sequence": [
   221  			  {
   222  				"name": "snapd",
   223  				"snap-id": "snapd-snap-id",
   224  				"revision": "2"
   225  			  }
   226  			],
   227  			"active": true,
   228  			"current": "2",
   229  			"channel": "stable"
   230  		  },
   231  		  "other": {
   232  			"type": "app",
   233  			"sequence": [
   234  			  {
   235  				"name": "other",
   236  				"snap-id": "snapd-snap-id",
   237  				"revision": "1"
   238  			  }
   239  			],
   240  			"active": true,
   241  			"current": "1",
   242  			"channel": "stable"
   243  		  }
   244  		}
   245  	  },
   246  	  "changes": {}
   247  	  },
   248  	  "tasks": {}
   249  	}
   250  }`)
   251  
   252  // State with two snaps with snapd-snap-id and improper snap types
   253  var statePatch6_2JSONWithSnapd2 = []byte(`
   254  {
   255  	"data": {
   256  		"patch-level": 6,
   257  		"snaps": {
   258  		  "snapd": {
   259  			"type": "app",
   260  			"sequence": [
   261  			  {
   262  				"name": "snapd",
   263  				"snap-id": "snapd-snap-id",
   264  				"revision": "2"
   265  			  }
   266  			],
   267  			"active": true,
   268  			"current": "2",
   269  			"channel": "stable"
   270  		  },
   271  		  "other": {
   272  			"type": "app",
   273  			"sequence": [
   274  			  {
   275  				"name": "other",
   276  				"snap-id": "snapd-snap-id",
   277  				"revision": "1"
   278  			  }
   279  			],
   280  			"active": true,
   281  			"current": "1",
   282  			"channel": "stable"
   283  		  }
   284  		}
   285  	  },
   286  	  "changes": {}
   287  	  },
   288  	  "tasks": {}
   289  	}
   290  }`)
   291  
   292  func (s *patch62Suite) SetUpTest(c *C) {
   293  	dirs.SetRootDir(c.MkDir())
   294  	snap.MockSanitizePlugsSlots(func(*snap.Info) {})
   295  }
   296  
   297  func (s *patch62Suite) TestPatch62(c *C) {
   298  	restore1 := patch.MockLevel(6, 2)
   299  	defer restore1()
   300  
   301  	restore2 := snap.MockSnapdSnapID("snapd-snap-id")
   302  	defer restore2()
   303  
   304  	r := bytes.NewReader(statePatch6_2JSON)
   305  	st, err := state.ReadState(nil, r)
   306  	c.Assert(err, IsNil)
   307  
   308  	c.Assert(patch.Apply(st), IsNil)
   309  	st.Lock()
   310  	defer st.Unlock()
   311  
   312  	// our mocks are correct
   313  	c.Assert(st.Changes(), HasLen, 2)
   314  	c.Assert(st.Tasks(), HasLen, 3)
   315  
   316  	var snapst snapstate.SnapState
   317  	c.Assert(snapstate.Get(st, "snapd", &snapst), IsNil)
   318  	c.Check(snapst.SnapType, Equals, "snapd")
   319  
   320  	// sanity check - "other" is untouched
   321  	c.Assert(snapstate.Get(st, "other", &snapst), IsNil)
   322  	c.Check(snapst.SnapType, Equals, "app")
   323  
   324  	// check tasks
   325  	task := st.Task("1")
   326  	c.Assert(task, NotNil)
   327  
   328  	var snapsup snapstate.SnapSetup
   329  	err = task.Get("snap-setup", &snapsup)
   330  	c.Assert(err, IsNil)
   331  	c.Check(snapsup.Type, Equals, snap.TypeSnapd)
   332  
   333  	// sanity check, structures not defined explicitly via patch62* are preserved
   334  	c.Check(snapsup.Flags.IsAutoRefresh, Equals, true)
   335  	c.Assert(snapsup.Media, HasLen, 5)
   336  	c.Check(snapsup.Media[0].URL, Equals, "a")
   337  	c.Assert(snapsup.DownloadInfo, NotNil)
   338  	c.Check(snapsup.DownloadInfo.DownloadURL, Equals, "foo")
   339  	c.Check(snapsup.DownloadInfo.Deltas, HasLen, 1)
   340  
   341  	task = st.Task("8")
   342  	c.Assert(task, NotNil)
   343  	c.Assert(task.Get("snap-setup", &snapsup), IsNil)
   344  	c.Check(snapsup.Type, Equals, snap.TypeSnapd)
   345  
   346  	// task 10 not updated because the change is ready
   347  	task = st.Task("10")
   348  	c.Assert(task, NotNil)
   349  	c.Assert(task.Get("snap-setup", &snapsup), IsNil)
   350  	c.Check(snapsup.Type, Equals, snap.TypeApp)
   351  }
   352  
   353  func (s *patch62Suite) TestPatch62StopsAfterFirstSnapd(c *C) {
   354  	restore1 := patch.MockLevel(6, 2)
   355  	defer restore1()
   356  
   357  	restore2 := snap.MockSnapdSnapID("snapd-snap-id")
   358  	defer restore2()
   359  
   360  	r := bytes.NewReader(statePatch6_2JSONWithSnapd2)
   361  	st, err := state.ReadState(nil, r)
   362  	c.Assert(err, IsNil)
   363  
   364  	c.Assert(patch.Apply(st), IsNil)
   365  	st.Lock()
   366  	defer st.Unlock()
   367  
   368  	var snapdCount int
   369  	for _, name := range []string{"snapd", "other"} {
   370  		var snapst snapstate.SnapState
   371  		c.Assert(snapstate.Get(st, name, &snapst), IsNil)
   372  		if snapst.SnapType == "snapd" {
   373  			snapdCount++
   374  		}
   375  	}
   376  	c.Check(snapdCount, Equals, 1)
   377  }