github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/backups/create_test.go (about)

     1  // Copyright 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  	"strings"
    12  
    13  	"github.com/juju/cmd"
    14  	"github.com/juju/cmd/cmdtesting"
    15  	"github.com/juju/errors"
    16  	jc "github.com/juju/testing/checkers"
    17  	gc "gopkg.in/check.v1"
    18  
    19  	"github.com/juju/juju/cmd/juju/backups"
    20  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    21  )
    22  
    23  type createSuite struct {
    24  	BaseBackupsSuite
    25  	wrappedCommand  cmd.Command
    26  	command         *backups.CreateCommand
    27  	defaultFilename string
    28  }
    29  
    30  var _ = gc.Suite(&createSuite{})
    31  
    32  func (s *createSuite) SetUpTest(c *gc.C) {
    33  	s.BaseBackupsSuite.SetUpTest(c)
    34  	s.wrappedCommand, s.command = backups.NewCreateCommandForTest(jujuclienttesting.MinimalStore())
    35  	s.defaultFilename = "juju-backup-<date>-<time>.tar.gz"
    36  }
    37  
    38  func (s *createSuite) TearDownTest(c *gc.C) {
    39  	// We do not need to cater here for s.BaseBackupsSuite.filename as it will be deleted by the base suite.
    40  	// However, in situations where s.command.Filename is defined, we want to remove it as well.
    41  	if s.command.Filename != backups.NotSet && s.command.Filename != s.filename {
    42  		err := os.Remove(s.command.Filename)
    43  		c.Assert(err, jc.ErrorIsNil)
    44  	}
    45  	s.BaseBackupsSuite.TearDownTest(c)
    46  }
    47  
    48  func (s *createSuite) setSuccess() *fakeAPIClient {
    49  	client := &fakeAPIClient{metaresult: s.metaresult}
    50  	s.patchGetAPI(client)
    51  	return client
    52  }
    53  
    54  func (s *createSuite) setFailure(failure string) *fakeAPIClient {
    55  	client := &fakeAPIClient{err: errors.New(failure)}
    56  	s.patchGetAPI(client)
    57  	return client
    58  }
    59  
    60  func (s *createSuite) setDownload() *fakeAPIClient {
    61  	client := s.setSuccess()
    62  	client.archive = ioutil.NopCloser(bytes.NewBufferString(s.data))
    63  	return client
    64  }
    65  
    66  func (s *createSuite) checkDownloadStd(c *gc.C, ctx *cmd.Context) {
    67  	c.Check(cmdtesting.Stdout(ctx), gc.Equals, MetaResultString)
    68  
    69  	out := cmdtesting.Stderr(ctx)
    70  	parts := strings.Split(out, "\n")
    71  	c.Assert(parts, gc.HasLen, 3)
    72  	if s.command.KeepCopy {
    73  		c.Check(parts[0], gc.Equals, fmt.Sprintf("Remote backup stored on the controller as %v.", s.metaresult.ID))
    74  	} else {
    75  		c.Check(parts[0], gc.Equals, "Remote backup was not created.")
    76  	}
    77  
    78  	// Check the download message.
    79  	parts = strings.Split(parts[1], "Downloaded to ")
    80  	c.Assert(parts, gc.HasLen, 2)
    81  	c.Assert(parts[0], gc.Equals, "")
    82  	s.filename = parts[1][:len(parts[1])-1]
    83  }
    84  
    85  func (s *createSuite) checkDownload(c *gc.C, ctx *cmd.Context) {
    86  	s.checkDownloadStd(c, ctx)
    87  	s.checkArchive(c)
    88  }
    89  
    90  type createBackupArgParsing struct {
    91  	title      string
    92  	args       []string
    93  	errMatch   string
    94  	filename   string
    95  	keepCopy   bool
    96  	noDownload bool
    97  	notes      string
    98  }
    99  
   100  var testCreateBackupArgParsing = []createBackupArgParsing{
   101  	{
   102  		title:      "no args",
   103  		args:       []string{},
   104  		filename:   backups.NotSet,
   105  		keepCopy:   false,
   106  		noDownload: false,
   107  		notes:      "",
   108  	},
   109  	{
   110  		title:      "filename",
   111  		args:       []string{"--filename", "testname"},
   112  		filename:   "testname",
   113  		keepCopy:   false,
   114  		noDownload: false,
   115  		notes:      "",
   116  	},
   117  	{
   118  		title:      "filename flag, no name",
   119  		args:       []string{"--filename"},
   120  		errMatch:   "option needs an argument: --filename",
   121  		filename:   backups.NotSet,
   122  		keepCopy:   false,
   123  		noDownload: false,
   124  		notes:      "",
   125  	},
   126  	{
   127  		title:      "filename && no-download",
   128  		args:       []string{"--filename", "testname", "--no-download"},
   129  		errMatch:   "cannot mix --no-download and --filename",
   130  		filename:   backups.NotSet,
   131  		keepCopy:   false,
   132  		noDownload: false,
   133  		notes:      "",
   134  	},
   135  	{
   136  		title:      "keep-copy",
   137  		args:       []string{"--keep-copy"},
   138  		errMatch:   "",
   139  		filename:   backups.NotSet,
   140  		keepCopy:   true,
   141  		noDownload: false,
   142  		notes:      "",
   143  	},
   144  	{
   145  		title:      "notes",
   146  		args:       []string{"note for the backup"},
   147  		errMatch:   "",
   148  		filename:   backups.NotSet,
   149  		keepCopy:   false,
   150  		noDownload: false,
   151  		notes:      "note for the backup",
   152  	},
   153  }
   154  
   155  func (s *createSuite) TestArgParsing(c *gc.C) {
   156  	for i, test := range testCreateBackupArgParsing {
   157  		c.Logf("%d: %s", i, test.title)
   158  		err := cmdtesting.InitCommand(s.wrappedCommand, test.args)
   159  		if test.errMatch == "" {
   160  			c.Assert(err, jc.ErrorIsNil)
   161  			c.Assert(s.command.Filename, gc.Equals, test.filename)
   162  			c.Assert(s.command.KeepCopy, gc.Equals, test.keepCopy)
   163  			c.Assert(s.command.NoDownload, gc.Equals, test.noDownload)
   164  			c.Assert(s.command.Notes, gc.Equals, test.notes)
   165  		} else {
   166  			c.Assert(err, gc.ErrorMatches, test.errMatch)
   167  		}
   168  	}
   169  }
   170  
   171  func (s *createSuite) TestDefault(c *gc.C) {
   172  	client := s.setDownload()
   173  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  
   176  	client.CheckCalls(c, "Create", "Download")
   177  	client.CheckArgs(c, "", "false", "false", "filename")
   178  	s.checkDownload(c, ctx)
   179  	c.Check(s.command.Filename, gc.Equals, backups.NotSet)
   180  }
   181  
   182  func (s *createSuite) TestDefaultV1(c *gc.C) {
   183  	s.apiVersion = 1
   184  	client := s.setDownload()
   185  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand)
   186  	c.Assert(err, jc.ErrorIsNil)
   187  
   188  	client.CheckCalls(c, "Create", "Download")
   189  	client.CheckArgs(c, "", "true", "false", "spam")
   190  	c.Assert(s.command.KeepCopy, jc.IsTrue)
   191  	s.checkDownload(c, ctx)
   192  	c.Check(s.command.Filename, gc.Equals, backups.NotSet)
   193  }
   194  
   195  func (s *createSuite) TestDefaultQuiet(c *gc.C) {
   196  	client := s.setDownload()
   197  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--quiet")
   198  	c.Assert(err, jc.ErrorIsNil)
   199  
   200  	client.CheckCalls(c, "Create", "Download")
   201  	client.CheckArgs(c, "", "false", "false", "filename")
   202  
   203  	c.Check(ctx.Stderr.(*bytes.Buffer).String(), gc.Equals, "")
   204  	c.Check(ctx.Stdout.(*bytes.Buffer).String(), gc.Equals, "")
   205  }
   206  
   207  func (s *createSuite) TestNotes(c *gc.C) {
   208  	client := s.setDownload()
   209  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand, "test notes")
   210  	c.Assert(err, jc.ErrorIsNil)
   211  
   212  	client.CheckCalls(c, "Create", "Download")
   213  	client.CheckArgs(c, "test notes", "false", "false", "filename")
   214  	s.checkDownload(c, ctx)
   215  }
   216  
   217  func (s *createSuite) TestFilename(c *gc.C) {
   218  	client := s.setDownload()
   219  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--filename", "backup.tgz")
   220  	c.Assert(err, jc.ErrorIsNil)
   221  
   222  	client.CheckCalls(c, "Create", "Download")
   223  	client.CheckArgs(c, "", "false", "false", "filename")
   224  	s.checkDownload(c, ctx)
   225  	c.Check(s.command.Filename, gc.Equals, "backup.tgz")
   226  }
   227  
   228  func (s *createSuite) TestNoDownload(c *gc.C) {
   229  	client := s.setSuccess()
   230  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--no-download")
   231  	c.Assert(err, jc.ErrorIsNil)
   232  
   233  	client.CheckCalls(c, "Create")
   234  	client.CheckArgs(c, "", "true", "true")
   235  	out := MetaResultString
   236  	expectedMsg := fmt.Sprintf("WARNING %v\nRemote backup stored on the controller as %v.\n", backups.DownloadWarning, s.metaresult.ID)
   237  	s.checkStd(c, ctx, out, expectedMsg)
   238  	c.Check(s.command.Filename, gc.Equals, backups.NotSet)
   239  }
   240  
   241  func (s *createSuite) TestKeepCopy(c *gc.C) {
   242  	client := s.setDownload()
   243  	ctx, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--keep-copy")
   244  	c.Assert(err, jc.ErrorIsNil)
   245  
   246  	client.CheckCalls(c, "Create", "Download")
   247  	client.CheckArgs(c, "", "true", "false", "filename")
   248  
   249  	s.checkDownload(c, ctx)
   250  }
   251  
   252  func (s *createSuite) TestFailKeepCopyNoDownload(c *gc.C) {
   253  	s.setDownload()
   254  	_, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--keep-copy", "--no-download")
   255  	c.Check(err, jc.ErrorIsNil)
   256  }
   257  
   258  func (s *createSuite) TestFailKeepCopyFalseNoDownload(c *gc.C) {
   259  	s.setDownload()
   260  	_, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--keep-copy=false", "--no-download")
   261  	c.Check(err, gc.ErrorMatches, "--no-download cannot be set when --keep-copy is not: the backup will not be created")
   262  }
   263  
   264  func (s *createSuite) TestKeepCopyV1Fail(c *gc.C) {
   265  	s.apiVersion = 1
   266  	s.setDownload()
   267  	_, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--keep-copy")
   268  
   269  	c.Assert(err, gc.ErrorMatches, "--keep-copy is not supported by this controller")
   270  }
   271  
   272  func (s *createSuite) TestFilenameAndNoDownload(c *gc.C) {
   273  	s.setSuccess()
   274  	_, err := cmdtesting.RunCommand(c, s.wrappedCommand, "--no-download", "--filename", "backup.tgz")
   275  
   276  	c.Check(err, gc.ErrorMatches, "cannot mix --no-download and --filename")
   277  }
   278  
   279  func (s *createSuite) TestError(c *gc.C) {
   280  	s.setFailure("failed!")
   281  	_, err := cmdtesting.RunCommand(c, s.wrappedCommand)
   282  
   283  	c.Check(errors.Cause(err), gc.ErrorMatches, "failed!")
   284  }