github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/state/backups/backups_test.go (about) 1 // Copyright 2013,2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package backups_test 5 6 import ( 7 "bytes" 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path" 12 "time" // Only used for time types. 13 14 "github.com/juju/collections/set" 15 "github.com/juju/errors" 16 jc "github.com/juju/testing/checkers" 17 gc "gopkg.in/check.v1" 18 19 "github.com/juju/juju/mongo" 20 "github.com/juju/juju/state/backups" 21 backupstesting "github.com/juju/juju/state/backups/testing" 22 "github.com/juju/juju/testing" 23 ) 24 25 type backupsSuite struct { 26 backupstesting.BaseSuite 27 28 api backups.Backups 29 } 30 31 var _ = gc.Suite(&backupsSuite{}) // Register the suite. 32 33 func (s *backupsSuite) SetUpTest(c *gc.C) { 34 s.BaseSuite.SetUpTest(c) 35 36 s.api = backups.NewBackups(s.Storage) 37 } 38 39 func (s *backupsSuite) setStored(id string) *time.Time { 40 s.Storage.ID = id 41 s.Storage.Meta = backupstesting.NewMetadataStarted() 42 s.Storage.Meta.SetID(id) 43 stored := testing.NonZeroTime().UTC() 44 s.Storage.Meta.SetStored(&stored) 45 return &stored 46 } 47 48 type fakeDumper struct{} 49 50 func (*fakeDumper) Dump(dumpDir string) error { 51 return nil 52 } 53 54 func (s *backupsSuite) checkFailure(c *gc.C, expected string) { 55 s.PatchValue(backups.GetDBDumper, func(*backups.DBInfo) (backups.DBDumper, error) { 56 return &fakeDumper{}, nil 57 }) 58 59 paths := backups.Paths{DataDir: "/var/lib/juju"} 60 targets := set.NewStrings("juju", "admin") 61 dbInfo := backups.DBInfo{"a", "b", "c", targets, mongo.Mongo32wt} 62 meta := backupstesting.NewMetadataStarted() 63 meta.Notes = "some notes" 64 65 _, err := s.api.Create(meta, &paths, &dbInfo, true, true) 66 c.Check(err, gc.ErrorMatches, expected) 67 } 68 69 func (s *backupsSuite) TestNewBackups(c *gc.C) { 70 api := backups.NewBackups(s.Storage) 71 72 c.Check(api, gc.NotNil) 73 } 74 75 func (s *backupsSuite) TestCreateOkayKeepCopyNoDownload(c *gc.C) { 76 s.testCreateOkay(c, true, true) 77 } 78 79 func (s *backupsSuite) TestCreateOkayKeepCopyFalse(c *gc.C) { 80 s.testCreateOkay(c, false, true) 81 } 82 83 func (s *backupsSuite) TestCreateOkayNoDownloadFalse(c *gc.C) { 84 s.testCreateOkay(c, true, false) 85 } 86 87 func (s *backupsSuite) testCreateOkay(c *gc.C, keepCopy, noDownload bool) { 88 dataDir := c.MkDir() 89 backupDir := c.MkDir() 90 // Patch the internals. 91 archiveFile := ioutil.NopCloser(bytes.NewBufferString("<compressed tarball>")) 92 result := backups.NewTestCreateResult( 93 archiveFile, 94 10, 95 "<checksum>", 96 path.Join(backupDir, backups.TempFilename)) 97 received, testCreate := backups.NewTestCreate(result) 98 s.PatchValue(backups.RunCreate, testCreate) 99 100 rootDir := "<was never set>" 101 s.PatchValue(backups.TestGetFilesToBackUp, func(root string, paths *backups.Paths, oldmachine string) ([]string, error) { 102 rootDir = root 103 return []string{"<some file>"}, nil 104 }) 105 106 var receivedDBInfo *backups.DBInfo 107 s.PatchValue(backups.GetDBDumper, func(info *backups.DBInfo) (backups.DBDumper, error) { 108 receivedDBInfo = info 109 return nil, nil 110 }) 111 112 stored := s.setStored("spam") 113 114 // Run the backup. 115 paths := backups.Paths{BackupDir: backupDir, DataDir: dataDir} 116 targets := set.NewStrings("juju", "admin") 117 dbInfo := backups.DBInfo{"a", "b", "c", targets, mongo.Mongo32wt} 118 meta := backupstesting.NewMetadataStarted() 119 backupstesting.SetOrigin(meta, "<model ID>", "<machine ID>", "<hostname>") 120 meta.Notes = "some notes" 121 resultFilename, err := s.api.Create(meta, &paths, &dbInfo, keepCopy, noDownload) 122 c.Assert(err, jc.ErrorIsNil) 123 c.Assert(resultFilename, gc.Equals, path.Join(backupDir, backups.TempFilename)) 124 125 // Test the call values. 126 if keepCopy { 127 s.Storage.CheckCalled(c, "spam", meta, archiveFile, "Add", "Metadata") 128 } else { 129 c.Assert(s.Storage.Calls, jc.SameContents, []string{}) 130 } 131 resultBackupDir, filesToBackUp, _ := backups.ExposeCreateArgs(received) 132 c.Check(resultBackupDir, gc.Equals, backupDir) 133 c.Check(filesToBackUp, jc.SameContents, []string{"<some file>"}) 134 135 c.Check(receivedDBInfo.Address, gc.Equals, "a") 136 c.Check(receivedDBInfo.Username, gc.Equals, "b") 137 c.Check(receivedDBInfo.Password, gc.Equals, "c") 138 c.Check(receivedDBInfo.Targets, gc.DeepEquals, targets) 139 140 c.Check(rootDir, gc.Equals, "") 141 142 // Check the resulting metadata. 143 if keepCopy { 144 c.Check(meta, gc.Equals, s.Storage.MetaArg) 145 c.Check(meta.ID(), gc.Equals, "spam") 146 c.Check(meta.Stored().Unix(), gc.Equals, stored.Unix()) 147 } 148 c.Check(meta.Size(), gc.Equals, int64(10)) 149 c.Check(meta.Checksum(), gc.Equals, "<checksum>") 150 c.Check(meta.Origin.Model, gc.Equals, "<model ID>") 151 c.Check(meta.Origin.Machine, gc.Equals, "<machine ID>") 152 c.Check(meta.Origin.Hostname, gc.Equals, "<hostname>") 153 c.Check(meta.Notes, gc.Equals, "some notes") 154 155 // Check the file storage. 156 if keepCopy { 157 s.Storage.Meta = meta 158 s.Storage.File = archiveFile 159 storedMeta, storedFile, err := s.Storage.Get(meta.ID()) 160 c.Check(err, jc.ErrorIsNil) 161 c.Check(storedMeta, gc.DeepEquals, meta) 162 data, err := ioutil.ReadAll(storedFile) 163 c.Assert(err, jc.ErrorIsNil) 164 c.Check(string(data), gc.Equals, "<compressed tarball>") 165 } 166 } 167 168 func (s *backupsSuite) TestCreateFailToListFiles(c *gc.C) { 169 s.PatchValue(backups.TestGetFilesToBackUp, func(root string, paths *backups.Paths, oldmachine string) ([]string, error) { 170 return nil, errors.New("failed!") 171 }) 172 173 s.checkFailure(c, "while listing files to back up: failed!") 174 } 175 176 func (s *backupsSuite) TestCreateFailToCreate(c *gc.C) { 177 s.PatchValue(backups.TestGetFilesToBackUp, func(root string, paths *backups.Paths, oldmachine string) ([]string, error) { 178 return []string{}, nil 179 }) 180 s.PatchValue(backups.RunCreate, backups.NewTestCreateFailure("failed!")) 181 182 s.checkFailure(c, "while creating backup archive: failed!") 183 } 184 185 func (s *backupsSuite) TestCreateFailToFinishMeta(c *gc.C) { 186 s.PatchValue(backups.TestGetFilesToBackUp, func(root string, paths *backups.Paths, oldmachine string) ([]string, error) { 187 return []string{}, nil 188 }) 189 _, testCreate := backups.NewTestCreate(nil) 190 s.PatchValue(backups.RunCreate, testCreate) 191 s.PatchValue(backups.FinishMeta, backups.NewTestMetaFinisher("failed!")) 192 193 s.checkFailure(c, "while updating metadata: failed!") 194 } 195 196 func (s *backupsSuite) TestCreateFailToStoreArchive(c *gc.C) { 197 s.PatchValue(backups.TestGetFilesToBackUp, func(root string, paths *backups.Paths, oldmachine string) ([]string, error) { 198 return []string{}, nil 199 }) 200 _, testCreate := backups.NewTestCreate(nil) 201 s.PatchValue(backups.RunCreate, testCreate) 202 s.PatchValue(backups.FinishMeta, backups.NewTestMetaFinisher("")) 203 s.PatchValue(backups.StoreArchiveRef, backups.NewTestArchiveStorer("failed!")) 204 205 s.checkFailure(c, "while storing backup archive: failed!") 206 } 207 208 func (s *backupsSuite) TestStoreArchive(c *gc.C) { 209 stored := s.setStored("spam") 210 211 meta := backupstesting.NewMetadataStarted() 212 c.Assert(meta.ID(), gc.Equals, "") 213 c.Assert(meta.Stored(), gc.IsNil) 214 archive := &bytes.Buffer{} 215 err := backups.StoreArchive(s.Storage, meta, archive) 216 c.Assert(err, jc.ErrorIsNil) 217 218 s.Storage.CheckCalled(c, "spam", meta, archive, "Add", "Metadata") 219 c.Assert(meta.ID(), gc.Equals, "spam") 220 c.Assert(meta.Stored(), jc.DeepEquals, stored) 221 } 222 223 func (s *backupsSuite) TestGetFileName(c *gc.C) { 224 backupDir := c.MkDir() 225 os.MkdirAll(backupDir, 0644) 226 backupFilename := path.Join(backupDir, backups.TempFilename) 227 backupFile, err := os.Create(backupFilename) 228 c.Assert(err, jc.ErrorIsNil) 229 backupFile.Write([]byte("archive file testing")) 230 231 resultMeta, resultArchive, err := s.api.Get(backupFilename) 232 c.Assert(err, jc.ErrorIsNil) 233 defer resultArchive.Close() 234 resultMeta.FileMetadata.Checksum() 235 236 // Purpose for metadata here is for the checksum to be used by the 237 // caller, so check it here. 238 c.Assert(resultMeta.FileMetadata.Checksum(), gc.NotNil) 239 b, err := ioutil.ReadAll(resultArchive) 240 c.Assert(err, jc.ErrorIsNil) 241 c.Assert(string(b), gc.Equals, "archive file testing") 242 243 _, err = ioutil.ReadDir(backupDir) 244 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("open %s: no such file or directory", backupDir)) 245 }