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  }