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 }