github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/overlord/state/copy_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 state_test
    21  
    22  import (
    23  	"io/ioutil"
    24  	"path/filepath"
    25  
    26  	. "gopkg.in/check.v1"
    27  
    28  	"github.com/snapcore/snapd/overlord/state"
    29  )
    30  
    31  func (ss *stateSuite) TestCopyStateAlreadyExists(c *C) {
    32  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
    33  
    34  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
    35  	err := ioutil.WriteFile(dstStateFile, nil, 0644)
    36  	c.Assert(err, IsNil)
    37  
    38  	err = state.CopyState(srcStateFile, dstStateFile, []string{"some-data"})
    39  	c.Assert(err, ErrorMatches, `cannot copy state: "/.*/dst-state.json" already exists`)
    40  }
    41  func (ss *stateSuite) TestCopyStateNoDataEntriesToCopy(c *C) {
    42  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
    43  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
    44  
    45  	err := state.CopyState(srcStateFile, dstStateFile, nil)
    46  	c.Assert(err, ErrorMatches, `cannot copy state: must provide at least one data entry to copy`)
    47  }
    48  
    49  var srcStateContent = []byte(`
    50  {
    51      "data": {
    52          "api-download-tokens-secret": "123",
    53          "api-download-tokens-secret-time": "2020-02-21T10:32:37.916147296Z",
    54          "auth": {
    55              "last-id": 1,
    56              "users": [
    57                  {
    58                      "id": 1,
    59                      "email": "some@user.com",
    60                      "macaroon": "1234",
    61                      "store-macaroon": "5678",
    62                      "store-discharges": [
    63                          "9012345"
    64                      ]
    65                  }
    66              ],
    67              "device": {
    68                  "brand": "generic",
    69                  "model": "generic-classic",
    70                  "serial": "xxxxx-yyyyy-",
    71                  "key-id": "xxxxxx",
    72                  "session-macaroon": "xxxx"
    73              },
    74              "macaroon-key": "xxxx="
    75          },
    76          "config": {
    77          }
    78      }
    79  }
    80  `)
    81  
    82  const stateSuffix = `,"changes":{},"tasks":{},"last-change-id":0,"last-task-id":0,"last-lane-id":0}`
    83  
    84  func (ss *stateSuite) TestCopyStateIntegration(c *C) {
    85  	// create a mock srcState
    86  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
    87  	err := ioutil.WriteFile(srcStateFile, srcStateContent, 0644)
    88  	c.Assert(err, IsNil)
    89  
    90  	// copy
    91  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
    92  	err = state.CopyState(srcStateFile, dstStateFile, []string{"auth.users", "no-existing-does-not-error", "auth.last-id"})
    93  	c.Assert(err, IsNil)
    94  
    95  	// and check that the right bits got copied
    96  	dstContent, err := ioutil.ReadFile(dstStateFile)
    97  	c.Assert(err, IsNil)
    98  	c.Check(string(dstContent), Equals, `{"data":{"auth":{"last-id":1,"users":[{"id":1,"email":"some@user.com","macaroon":"1234","store-macaroon":"5678","store-discharges":["9012345"]}]}}`+stateSuffix)
    99  }
   100  
   101  var srcStateContent1 = []byte(`{
   102      "data": {
   103          "A": {"B": [{"C": 1}, {"D": 2}]},
   104          "E": {"F": 2, "G": 3},
   105          "H": 4,
   106          "I": null
   107      }
   108  }`)
   109  
   110  func (ss *stateSuite) TestCopyState(c *C) {
   111  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
   112  	err := ioutil.WriteFile(srcStateFile, srcStateContent1, 0644)
   113  	c.Assert(err, IsNil)
   114  
   115  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
   116  	err = state.CopyState(srcStateFile, dstStateFile, []string{"A.B", "no-existing-does-not-error", "E.F", "E", "I", "E.non-existing"})
   117  	c.Assert(err, IsNil)
   118  
   119  	dstContent, err := ioutil.ReadFile(dstStateFile)
   120  	c.Assert(err, IsNil)
   121  	c.Check(string(dstContent), Equals, `{"data":{"A":{"B":[{"C":1},{"D":2}]},"E":{"F":2,"G":3},"I":null}`+stateSuffix)
   122  }
   123  
   124  func (ss *stateSuite) TestCopyStateUnmarshalNotMap(c *C) {
   125  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
   126  	err := ioutil.WriteFile(srcStateFile, srcStateContent1, 0644)
   127  	c.Assert(err, IsNil)
   128  
   129  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
   130  	err = state.CopyState(srcStateFile, dstStateFile, []string{"E.F.subkey-not-in-a-map"})
   131  	c.Assert(err, ErrorMatches, `cannot unmarshal state entry "E.F" with value "2" as a map while trying to copy over "E.F.subkey-not-in-a-map"`)
   132  }
   133  
   134  func (ss *stateSuite) TestCopyStateDuplicatesInDataEntriesAreFine(c *C) {
   135  	srcStateFile := filepath.Join(c.MkDir(), "src-state.json")
   136  	err := ioutil.WriteFile(srcStateFile, srcStateContent1, 0644)
   137  	c.Assert(err, IsNil)
   138  
   139  	dstStateFile := filepath.Join(c.MkDir(), "dst-state.json")
   140  	err = state.CopyState(srcStateFile, dstStateFile, []string{"E", "E"})
   141  	c.Assert(err, IsNil)
   142  
   143  	dstContent, err := ioutil.ReadFile(dstStateFile)
   144  	c.Assert(err, IsNil)
   145  	c.Check(string(dstContent), Equals, `{"data":{"E":{"F":2,"G":3}}`+stateSuffix)
   146  }