github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/state/backups/files_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // +build !windows 5 6 package backups_test 7 8 import ( 9 "os" 10 "path/filepath" 11 "sort" 12 "syscall" 13 14 "github.com/juju/errors" 15 jc "github.com/juju/testing/checkers" 16 "github.com/juju/utils/set" 17 gc "gopkg.in/check.v1" 18 19 "github.com/juju/juju/state/backups" 20 "github.com/juju/juju/testing" 21 ) 22 23 var _ = gc.Suite(&filesSuite{}) 24 25 type filesSuite struct { 26 testing.BaseSuite 27 root string 28 } 29 30 func (s *filesSuite) SetUpTest(c *gc.C) { 31 s.BaseSuite.SetUpTest(c) 32 33 s.root = c.MkDir() 34 } 35 36 // createFiles preps the fake FS. The files are all created relative to 37 // the given root. 38 func (s *filesSuite) createFiles(c *gc.C, paths backups.Paths, root, machineID string) { 39 mkdir := func(path string) string { 40 dirname := filepath.Join(root, path) 41 os.MkdirAll(dirname, 0777) 42 return dirname 43 } 44 touch := func(dirname, name string) { 45 path := filepath.Join(dirname, name) 46 file, err := os.Create(path) 47 c.Assert(err, jc.ErrorIsNil) 48 file.Close() 49 } 50 51 dirname := mkdir(paths.DataDir) 52 touch(dirname, "system-identity") 53 touch(dirname, "nonce.txt") 54 touch(dirname, "server.pem") 55 touch(dirname, "shared-secret") 56 mkdir(filepath.Join(paths.DataDir, "tools")) 57 58 dirname = mkdir(filepath.Join(paths.DataDir, "agents")) 59 touch(dirname, "machine-"+machineID+".conf") 60 61 dirname = mkdir(paths.LogsDir) 62 touch(dirname, "all-machines.log") 63 touch(dirname, "machine-"+machineID+".log") 64 65 dirname = mkdir("/etc/init") 66 touch(dirname, "jujud-machine-"+machineID+".conf") 67 touch(dirname, "juju-db.conf") 68 69 dirname = mkdir("/etc/rsyslog.d") 70 touch(dirname, "spam-juju.conf") 71 72 dirname = mkdir("/home/ubuntu/.ssh") 73 touch(dirname, "authorized_keys") 74 } 75 76 func (s *filesSuite) checkSameStrings(c *gc.C, actual, expected []string) { 77 sActual := set.NewStrings(actual...) 78 sExpected := set.NewStrings(expected...) 79 80 sActualOnly := sActual.Difference(sExpected) 81 sExpectedOnly := sExpected.Difference(sActual) 82 83 if !sActualOnly.IsEmpty() || !sExpectedOnly.IsEmpty() { 84 c.Error("strings mismatch") 85 onlyActual := sActualOnly.Values() 86 onlyExpected := sExpectedOnly.Values() 87 sort.Strings(onlyActual) 88 sort.Strings(onlyExpected) 89 90 if !sActualOnly.IsEmpty() { 91 c.Log("...unexpected values:") 92 for _, str := range onlyActual { 93 c.Log(" " + str) 94 } 95 } 96 if !sExpectedOnly.IsEmpty() { 97 c.Log("...missing values:") 98 for _, str := range onlyExpected { 99 c.Log(" " + str) 100 } 101 } 102 } 103 } 104 105 func (s *filesSuite) TestGetFilesToBackUpMachine0(c *gc.C) { 106 paths := backups.Paths{ 107 DataDir: "/var/lib/juju", 108 LogsDir: "/var/log/juju", 109 } 110 s.createFiles(c, paths, s.root, "0") 111 112 files, err := backups.GetFilesToBackUp(s.root, &paths, "0") 113 c.Assert(err, jc.ErrorIsNil) 114 115 expected := []string{ 116 filepath.Join(s.root, "/etc/init/juju-db.conf"), 117 filepath.Join(s.root, "/etc/init/jujud-machine-0.conf"), 118 filepath.Join(s.root, "/etc/rsyslog.d/spam-juju.conf"), 119 filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"), 120 filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"), 121 filepath.Join(s.root, "/var/lib/juju/nonce.txt"), 122 filepath.Join(s.root, "/var/lib/juju/server.pem"), 123 filepath.Join(s.root, "/var/lib/juju/shared-secret"), 124 filepath.Join(s.root, "/var/lib/juju/system-identity"), 125 filepath.Join(s.root, "/var/lib/juju/tools"), 126 filepath.Join(s.root, "/var/log/juju/all-machines.log"), 127 filepath.Join(s.root, "/var/log/juju/machine-0.log"), 128 } 129 c.Check(files, jc.SameContents, expected) 130 s.checkSameStrings(c, files, expected) 131 } 132 133 func (s *filesSuite) TestDirectoriesCleaned(c *gc.C) { 134 recreatableFolder := filepath.Join(s.root, "recreate_me") 135 os.MkdirAll(recreatableFolder, os.FileMode(0755)) 136 recreatableFolderInfo, err := os.Stat(recreatableFolder) 137 c.Assert(err, jc.ErrorIsNil) 138 139 recreatableFolder1 := filepath.Join(recreatableFolder, "recreate_me_too") 140 os.MkdirAll(recreatableFolder1, os.FileMode(0755)) 141 recreatableFolder1Info, err := os.Stat(recreatableFolder1) 142 c.Assert(err, jc.ErrorIsNil) 143 144 deletableFolder := filepath.Join(recreatableFolder, "dont_recreate_me") 145 os.MkdirAll(deletableFolder, os.FileMode(0755)) 146 147 deletableFile := filepath.Join(recreatableFolder, "delete_me") 148 fh, err := os.Create(deletableFile) 149 c.Assert(err, jc.ErrorIsNil) 150 defer fh.Close() 151 152 deletableFile1 := filepath.Join(recreatableFolder1, "delete_me.too") 153 fhr, err := os.Create(deletableFile1) 154 c.Assert(err, jc.ErrorIsNil) 155 defer fhr.Close() 156 157 s.PatchValue(backups.ReplaceableFolders, func() (map[string]os.FileMode, error) { 158 replaceables := map[string]os.FileMode{} 159 for _, replaceable := range []string{ 160 recreatableFolder, 161 recreatableFolder1, 162 } { 163 dirStat, err := os.Stat(replaceable) 164 if err != nil { 165 return map[string]os.FileMode{}, errors.Annotatef(err, "cannot stat %q", replaceable) 166 } 167 replaceables[replaceable] = dirStat.Mode() 168 } 169 return replaceables, nil 170 }) 171 172 err = backups.PrepareMachineForRestore() 173 c.Assert(err, jc.ErrorIsNil) 174 175 _, err = os.Stat(deletableFolder) 176 c.Assert(err, gc.Not(gc.IsNil)) 177 c.Assert(os.IsNotExist(err), gc.Equals, true) 178 179 recreatedFolderInfo, err := os.Stat(recreatableFolder) 180 c.Assert(err, jc.ErrorIsNil) 181 c.Assert(recreatableFolderInfo.Mode(), gc.Equals, recreatedFolderInfo.Mode()) 182 c.Assert(recreatableFolderInfo.Sys().(*syscall.Stat_t).Ino, gc.Not(gc.Equals), recreatedFolderInfo.Sys().(*syscall.Stat_t).Ino) 183 184 recreatedFolder1Info, err := os.Stat(recreatableFolder1) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(recreatableFolder1Info.Mode(), gc.Equals, recreatedFolder1Info.Mode()) 187 c.Assert(recreatableFolder1Info.Sys().(*syscall.Stat_t).Ino, gc.Not(gc.Equals), recreatedFolder1Info.Sys().(*syscall.Stat_t).Ino) 188 } 189 190 func (s *filesSuite) TestGetFilesToBackUpMachine10(c *gc.C) { 191 paths := backups.Paths{ 192 DataDir: "/var/lib/juju", 193 LogsDir: "/var/log/juju", 194 } 195 s.createFiles(c, paths, s.root, "10") 196 197 files, err := backups.GetFilesToBackUp(s.root, &paths, "10") 198 c.Assert(err, jc.ErrorIsNil) 199 200 expected := []string{ 201 filepath.Join(s.root, "/etc/init/juju-db.conf"), 202 filepath.Join(s.root, "/etc/init/jujud-machine-10.conf"), 203 filepath.Join(s.root, "/etc/rsyslog.d/spam-juju.conf"), 204 filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys"), 205 filepath.Join(s.root, "/var/lib/juju/agents/machine-10.conf"), 206 filepath.Join(s.root, "/var/lib/juju/nonce.txt"), 207 filepath.Join(s.root, "/var/lib/juju/server.pem"), 208 filepath.Join(s.root, "/var/lib/juju/shared-secret"), 209 filepath.Join(s.root, "/var/lib/juju/system-identity"), 210 filepath.Join(s.root, "/var/lib/juju/tools"), 211 filepath.Join(s.root, "/var/log/juju/all-machines.log"), 212 filepath.Join(s.root, "/var/log/juju/machine-10.log"), 213 } 214 c.Check(files, jc.SameContents, expected) 215 s.checkSameStrings(c, files, expected) 216 } 217 218 func (s *filesSuite) TestGetFilesToBackUpMissing(c *gc.C) { 219 paths := backups.Paths{ 220 DataDir: "/var/lib/juju", 221 LogsDir: "/var/log/juju", 222 } 223 s.createFiles(c, paths, s.root, "0") 224 225 missing := []string{ 226 "/var/lib/juju/nonce.txt", 227 "/home/ubuntu/.ssh/authorized_keys", 228 "/var/log/juju/all-machines.log", 229 "/var/log/juju/machine-0.log", 230 } 231 for _, filename := range missing { 232 err := os.Remove(filepath.Join(s.root, filename)) 233 c.Assert(err, jc.ErrorIsNil) 234 } 235 236 files, err := backups.GetFilesToBackUp(s.root, &paths, "0") 237 c.Assert(err, jc.ErrorIsNil) 238 239 expected := []string{ 240 filepath.Join(s.root, "/etc/init/juju-db.conf"), 241 filepath.Join(s.root, "/etc/init/jujud-machine-0.conf"), 242 filepath.Join(s.root, "/etc/rsyslog.d/spam-juju.conf"), 243 filepath.Join(s.root, "/var/lib/juju/agents/machine-0.conf"), 244 filepath.Join(s.root, "/var/lib/juju/server.pem"), 245 filepath.Join(s.root, "/var/lib/juju/shared-secret"), 246 filepath.Join(s.root, "/var/lib/juju/system-identity"), 247 filepath.Join(s.root, "/var/lib/juju/tools"), 248 } 249 // This got re-created. 250 expected = append(expected, filepath.Join(s.root, "/home/ubuntu/.ssh/authorized_keys")) 251 c.Check(files, jc.SameContents, expected) 252 s.checkSameStrings(c, files, expected) 253 }