github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/backups/files_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 //go:build !windows 5 6 package backups_test 7 8 import ( 9 "os" 10 "path/filepath" 11 "sort" 12 "syscall" 13 14 "github.com/juju/collections/set" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/state/backups" 19 "github.com/juju/juju/testing" 20 ) 21 22 var _ = gc.Suite(&filesSuite{}) 23 24 type filesSuite struct { 25 testing.BaseSuite 26 root string 27 } 28 29 func (s *filesSuite) SetUpTest(c *gc.C) { 30 s.BaseSuite.SetUpTest(c) 31 32 // Set the process' umask to 0 so tests that check permission bits don't 33 // fail due to the users umask being an unexpected value. 34 oldUmask := syscall.Umask(0) 35 s.AddCleanup(func(_ *gc.C) { 36 syscall.Umask(oldUmask) 37 }) 38 39 s.root = c.MkDir() 40 } 41 42 func (s *filesSuite) TearDownTest(c *gc.C) { 43 s.BaseSuite.TearDownTest(c) 44 } 45 46 // createFiles preps the fake FS. The files are all created relative to 47 // the given root. 48 func (s *filesSuite) createFiles(c *gc.C, paths backups.Paths, root, machineID string, snapPaths bool) { 49 mkdir := func(path string) string { 50 dirname := filepath.Join(root, path) 51 os.MkdirAll(dirname, 0777) 52 return dirname 53 } 54 touch := func(dirname, name string) { 55 path := filepath.Join(dirname, name) 56 file, err := os.Create(path) 57 c.Assert(err, jc.ErrorIsNil) 58 file.Close() 59 } 60 61 dirname := mkdir(paths.DataDir) 62 touch(dirname, "system-identity") 63 touch(dirname, "nonce.txt") 64 touch(dirname, "server.pem") 65 if snapPaths { 66 snapDirname := mkdir("/var/snap/juju-db/common") 67 touch(snapDirname, "shared-secret") 68 } else { 69 touch(dirname, "shared-secret") 70 } 71 mkdir(filepath.Join(paths.DataDir, "tools")) 72 73 dirname = mkdir(filepath.Join(paths.DataDir, "agents")) 74 touch(dirname, "machine-"+machineID+".conf") 75 76 dirname = mkdir("/home/ubuntu/.ssh") 77 touch(dirname, "authorized_keys") 78 79 dirname = mkdir(filepath.Join(paths.DataDir, "init", "juju-db")) 80 touch(dirname, "juju-db.service") 81 } 82 83 func (s *filesSuite) checkSameStrings(c *gc.C, actual, expected []string) { 84 sActual := set.NewStrings(actual...) 85 sExpected := set.NewStrings(expected...) 86 87 sActualOnly := sActual.Difference(sExpected) 88 sExpectedOnly := sExpected.Difference(sActual) 89 90 if !sActualOnly.IsEmpty() || !sExpectedOnly.IsEmpty() { 91 c.Error("strings mismatch") 92 onlyActual := sActualOnly.Values() 93 onlyExpected := sExpectedOnly.Values() 94 sort.Strings(onlyActual) 95 sort.Strings(onlyExpected) 96 97 if !sActualOnly.IsEmpty() { 98 c.Log("...unexpected values:") 99 for _, str := range onlyActual { 100 c.Log(" " + str) 101 } 102 } 103 if !sExpectedOnly.IsEmpty() { 104 c.Log("...missing values:") 105 for _, str := range onlyExpected { 106 c.Log(" " + str) 107 } 108 } 109 } 110 } 111 112 func (s *filesSuite) TestGetFilesToBackUp(c *gc.C) { 113 paths := backups.Paths{ 114 DataDir: "/var/lib/juju", 115 LogsDir: "/var/log/juju", 116 } 117 s.createFiles(c, paths, s.root, "0", false) 118 s.createFiles(c, paths, s.root, "1", false) 119 120 files, err := backups.GetFilesToBackUp(s.root, &paths) 121 c.Assert(err, jc.ErrorIsNil) 122 123 expected := []string{ 124 filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"), 125 filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"), 126 filepath.Join(s.root, "/var/lib/juju/agents/machine-1.conf"), 127 filepath.Join(s.root, "/var/lib/juju/nonce.txt"), 128 filepath.Join(s.root, "/var/lib/juju/server.pem"), 129 filepath.Join(s.root, "/var/lib/juju/shared-secret"), 130 filepath.Join(s.root, "/var/lib/juju/system-identity"), 131 filepath.Join(s.root, "/var/lib/juju/tools"), 132 filepath.Join(s.root, "/var/lib/juju/init/juju-db"), 133 } 134 c.Check(files, jc.SameContents, expected) 135 s.checkSameStrings(c, files, expected) 136 } 137 138 func (s *filesSuite) TestGetFilesToBackUpMissing(c *gc.C) { 139 paths := backups.Paths{ 140 DataDir: "/var/lib/juju", 141 LogsDir: "/var/log/juju", 142 } 143 s.createFiles(c, paths, s.root, "0", false) 144 145 missing := []string{ 146 "/var/lib/juju/nonce.txt", 147 "/home/ubuntu/.ssh/authorized_keys", 148 } 149 for _, filename := range missing { 150 err := os.Remove(filepath.Join(s.root, filename)) 151 c.Assert(err, jc.ErrorIsNil) 152 } 153 154 files, err := backups.GetFilesToBackUp(s.root, &paths) 155 c.Assert(err, jc.ErrorIsNil) 156 157 expected := []string{ 158 filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"), 159 filepath.Join(s.root, "/var/lib/juju/server.pem"), 160 filepath.Join(s.root, "/var/lib/juju/shared-secret"), 161 filepath.Join(s.root, "/var/lib/juju/system-identity"), 162 filepath.Join(s.root, "/var/lib/juju/tools"), 163 filepath.Join(s.root, "/var/lib/juju/init/juju-db"), 164 } 165 // This got re-created. 166 expected = append(expected, filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys")) 167 c.Check(files, jc.SameContents, expected) 168 s.checkSameStrings(c, files, expected) 169 } 170 171 func (s *filesSuite) TestGetFilesToBackUpSnap(c *gc.C) { 172 paths := backups.Paths{ 173 DataDir: "/var/lib/juju", 174 LogsDir: "/var/log/juju", 175 } 176 s.createFiles(c, paths, s.root, "0", true) 177 178 files, err := backups.GetFilesToBackUp(s.root, &paths) 179 c.Assert(err, jc.ErrorIsNil) 180 181 expected := []string{ 182 filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"), 183 filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"), 184 filepath.Join(s.root, "/var/lib/juju/nonce.txt"), 185 filepath.Join(s.root, "/var/lib/juju/server.pem"), 186 filepath.Join(s.root, "/var/snap/juju-db/common/shared-secret"), 187 filepath.Join(s.root, "/var/lib/juju/system-identity"), 188 filepath.Join(s.root, "/var/lib/juju/tools"), 189 filepath.Join(s.root, "/var/lib/juju/init/juju-db"), 190 } 191 c.Check(files, jc.SameContents, expected) 192 s.checkSameStrings(c, files, expected) 193 }