github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/backups/restore_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
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	"net"
    12  	"os"
    13  	"path"
    14  	"strconv"
    15  	"strings"
    16  
    17  	"github.com/juju/replicaset"
    18  	gitjujutesting "github.com/juju/testing"
    19  	jc "github.com/juju/testing/checkers"
    20  	"github.com/juju/utils/ssh"
    21  	gc "gopkg.in/check.v1"
    22  	"gopkg.in/juju/names.v2"
    23  	"gopkg.in/mgo.v2/bson"
    24  
    25  	"github.com/juju/juju/agent"
    26  	"github.com/juju/juju/apiserver/params"
    27  	"github.com/juju/juju/environs"
    28  	"github.com/juju/juju/mongo/mongotest"
    29  	"github.com/juju/juju/state"
    30  	statetesting "github.com/juju/juju/state/testing"
    31  	coretesting "github.com/juju/juju/testing"
    32  	jujuversion "github.com/juju/juju/version"
    33  )
    34  
    35  var _ = gc.Suite(&RestoreSuite{})
    36  
    37  type RestoreSuite struct {
    38  	coretesting.BaseSuite
    39  	cwd       string
    40  	testFiles []string
    41  }
    42  
    43  func (r *RestoreSuite) SetUpSuite(c *gc.C) {
    44  	r.BaseSuite.SetUpSuite(c)
    45  }
    46  
    47  func (r *RestoreSuite) SetUpTest(c *gc.C) {
    48  	r.cwd = c.MkDir()
    49  	r.BaseSuite.SetUpTest(c)
    50  }
    51  
    52  func (r *RestoreSuite) createTestFiles(c *gc.C) {
    53  	tarDirE := path.Join(r.cwd, "TarDirectoryEmpty")
    54  	err := os.Mkdir(tarDirE, os.FileMode(0755))
    55  	c.Check(err, jc.ErrorIsNil)
    56  
    57  	tarDirP := path.Join(r.cwd, "TarDirectoryPopulated")
    58  	err = os.Mkdir(tarDirP, os.FileMode(0755))
    59  	c.Check(err, jc.ErrorIsNil)
    60  
    61  	tarSubFile1 := path.Join(tarDirP, "TarSubFile1")
    62  	tarSubFile1Handle, err := os.Create(tarSubFile1)
    63  	c.Check(err, jc.ErrorIsNil)
    64  	tarSubFile1Handle.WriteString("TarSubFile1")
    65  	tarSubFile1Handle.Close()
    66  
    67  	tarSubDir := path.Join(tarDirP, "TarDirectoryPopulatedSubDirectory")
    68  	err = os.Mkdir(tarSubDir, os.FileMode(0755))
    69  	c.Check(err, jc.ErrorIsNil)
    70  
    71  	tarFile1 := path.Join(r.cwd, "TarFile1")
    72  	tarFile1Handle, err := os.Create(tarFile1)
    73  	c.Check(err, jc.ErrorIsNil)
    74  	tarFile1Handle.WriteString("TarFile1")
    75  	tarFile1Handle.Close()
    76  
    77  	tarFile2 := path.Join(r.cwd, "TarFile2")
    78  	tarFile2Handle, err := os.Create(tarFile2)
    79  	c.Check(err, jc.ErrorIsNil)
    80  	tarFile2Handle.WriteString("TarFile2")
    81  	tarFile2Handle.Close()
    82  	r.testFiles = []string{tarDirE, tarDirP, tarFile1, tarFile2}
    83  }
    84  
    85  func (r *RestoreSuite) TestReplicasetIsReset(c *gc.C) {
    86  	server := &gitjujutesting.MgoInstance{Params: []string{"--replSet", "juju"}}
    87  	err := server.Start(coretesting.Certs)
    88  	c.Assert(err, jc.ErrorIsNil)
    89  	defer server.DestroyWithLog()
    90  	mgoAddr := server.Addr()
    91  	dialInfo := server.DialInfo()
    92  
    93  	var cfg *replicaset.Config
    94  	dialInfo = server.DialInfo()
    95  	dialInfo.Addrs = []string{mgoAddr}
    96  	err = resetReplicaSet(dialInfo, mgoAddr)
    97  
    98  	session, err := server.Dial()
    99  	c.Assert(err, jc.ErrorIsNil)
   100  	defer session.Close()
   101  	cfg, err = replicaset.CurrentConfig(session)
   102  	c.Assert(err, jc.ErrorIsNil)
   103  	c.Assert(cfg.Members, gc.HasLen, 1)
   104  	c.Assert(cfg.Members[0].Address, gc.Equals, mgoAddr)
   105  }
   106  
   107  type backupConfigTests struct {
   108  	yamlFile      io.Reader
   109  	expectedError error
   110  	message       string
   111  }
   112  
   113  func (r *RestoreSuite) TestSetAgentAddressScript(c *gc.C) {
   114  	testServerAddresses := []string{
   115  		"FirstNewControllerAddress:30303",
   116  		"SecondNewControllerAddress:30304",
   117  		"ThirdNewControllerAddress:30305",
   118  		"FourthNewControllerAddress:30306",
   119  		"FiftNewControllerAddress:30307",
   120  		"SixtNewControllerAddress:30308",
   121  	}
   122  	for _, address := range testServerAddresses {
   123  		template := setAgentAddressScript(address, address)
   124  		expectedString := fmt.Sprintf("\t\ts/- .*(:[0-9]+)/- %s\\1/\n", address)
   125  		logger.Infof(fmt.Sprintf("Testing with address %q", address))
   126  		c.Assert(strings.Contains(template, expectedString), gc.Equals, true)
   127  	}
   128  }
   129  
   130  func (r *RestoreSuite) TestNewDialInfo(c *gc.C) {
   131  
   132  	cases := []struct {
   133  		machineTag       string
   134  		apiPassword      string
   135  		oldPassword      string
   136  		expectedPassword string
   137  		expectedUser     string
   138  		expectedError    string
   139  	}{
   140  		{"machine-0",
   141  			"",
   142  			"123456",
   143  			"123456",
   144  			"admin",
   145  			"",
   146  		},
   147  		{"machine-1",
   148  			"123123",
   149  			"",
   150  			"123123",
   151  			"machine-1",
   152  			"",
   153  		},
   154  	}
   155  
   156  	dataDir := path.Join(r.cwd, "dataDir")
   157  	err := os.Mkdir(dataDir, os.FileMode(0755))
   158  	c.Assert(err, jc.ErrorIsNil)
   159  
   160  	logDir := path.Join(r.cwd, "logDir")
   161  	err = os.Mkdir(logDir, os.FileMode(0755))
   162  	c.Assert(err, jc.ErrorIsNil)
   163  	for _, testCase := range cases {
   164  		machineTag, err := names.ParseTag(testCase.machineTag)
   165  		c.Assert(err, jc.ErrorIsNil)
   166  
   167  		configParams := agent.AgentConfigParams{
   168  			Paths: agent.Paths{
   169  				DataDir: dataDir,
   170  				LogDir:  logDir,
   171  			},
   172  			UpgradedToVersion: jujuversion.Current,
   173  			Tag:               machineTag,
   174  			Controller:        coretesting.ControllerTag,
   175  			Model:             coretesting.ModelTag,
   176  			Password:          "placeholder",
   177  			Nonce:             "dummyNonce",
   178  			StateAddresses:    []string{"fakeStateAddress:1234"},
   179  			APIAddresses:      []string{"fakeAPIAddress:12345"},
   180  			CACert:            coretesting.CACert,
   181  		}
   182  		statePort := 12345
   183  		privateAddress := "dummyPrivateAddress"
   184  		servingInfo := params.StateServingInfo{
   185  			APIPort:        1234,
   186  			StatePort:      statePort,
   187  			Cert:           coretesting.CACert,
   188  			CAPrivateKey:   "a ca key",
   189  			PrivateKey:     "a key",
   190  			SharedSecret:   "a secret",
   191  			SystemIdentity: "an identity",
   192  		}
   193  
   194  		conf, err := agent.NewStateMachineConfig(configParams, servingInfo)
   195  		c.Assert(err, jc.ErrorIsNil)
   196  		conf.SetOldPassword(testCase.oldPassword)
   197  		conf.SetPassword(testCase.apiPassword)
   198  
   199  		dialInfo, err := newDialInfo(privateAddress, conf)
   200  		if testCase.expectedError != "" {
   201  			c.Assert(err, gc.ErrorMatches, testCase.expectedError)
   202  		} else {
   203  			c.Assert(err, jc.ErrorIsNil)
   204  			c.Assert(dialInfo.Username, gc.Equals, testCase.expectedUser)
   205  			c.Assert(dialInfo.Password, gc.Equals, testCase.expectedPassword)
   206  			c.Assert(dialInfo.Direct, gc.Equals, true)
   207  			c.Assert(dialInfo.Addrs, gc.DeepEquals, []string{net.JoinHostPort(privateAddress, strconv.Itoa(statePort))})
   208  		}
   209  	}
   210  }
   211  
   212  // TestUpdateMongoEntries has all the testing for this function to avoid creating multiple
   213  // mongo instances.
   214  func (r *RestoreSuite) TestUpdateMongoEntries(c *gc.C) {
   215  	server := &gitjujutesting.MgoInstance{}
   216  	err := server.Start(coretesting.Certs)
   217  	c.Assert(err, jc.ErrorIsNil)
   218  	defer server.DestroyWithLog()
   219  	dialInfo := server.DialInfo()
   220  	mgoAddr := server.Addr()
   221  	dialInfo.Addrs = []string{mgoAddr}
   222  	err = updateMongoEntries("1234", "0", "0", dialInfo)
   223  	c.Assert(err, gc.ErrorMatches, "cannot update machine 0 instance information: not found")
   224  
   225  	session, err := server.Dial()
   226  	c.Assert(err, jc.ErrorIsNil)
   227  	defer session.Close()
   228  
   229  	err = session.DB("juju").C("machines").Insert(bson.M{"machineid": "0", "instanceid": "0"})
   230  	c.Assert(err, jc.ErrorIsNil)
   231  
   232  	query := session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"})
   233  	n, err := query.Count()
   234  	c.Assert(err, jc.ErrorIsNil)
   235  	c.Assert(n, gc.Equals, 0)
   236  
   237  	err = updateMongoEntries("1234", "0", "0", dialInfo)
   238  	c.Assert(err, jc.ErrorIsNil)
   239  
   240  	query = session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"})
   241  	n, err = query.Count()
   242  	c.Assert(err, jc.ErrorIsNil)
   243  	c.Assert(n, gc.Equals, 1)
   244  }
   245  
   246  func (r *RestoreSuite) TestNewConnection(c *gc.C) {
   247  	server := &gitjujutesting.MgoInstance{}
   248  	err := server.Start(coretesting.Certs)
   249  	c.Assert(err, jc.ErrorIsNil)
   250  	defer server.DestroyWithLog()
   251  
   252  	st := statetesting.InitializeWithArgs(c,
   253  		statetesting.InitializeArgs{
   254  			Owner: names.NewLocalUserTag("test-admin"),
   255  			Clock: gitjujutesting.NewClock(coretesting.NonZeroTime()),
   256  		})
   257  	c.Assert(st.Close(), jc.ErrorIsNil)
   258  
   259  	r.PatchValue(&mongoDefaultDialOpts, mongotest.DialOpts)
   260  	r.PatchValue(&environsGetNewPolicyFunc, func(
   261  		func(*state.State) (environs.Environ, error),
   262  	) state.NewPolicyFunc {
   263  		return nil
   264  	})
   265  	st, err = newStateConnection(st.ControllerTag(), st.ModelTag(), statetesting.NewMongoInfo())
   266  	c.Assert(err, jc.ErrorIsNil)
   267  	c.Assert(st.Close(), jc.ErrorIsNil)
   268  }
   269  
   270  func (r *RestoreSuite) TestRunViaSSH(c *gc.C) {
   271  	var (
   272  		passedAddress string
   273  		passedArgs    []string
   274  	)
   275  	fakeSSHCommand := func(address string, args []string, options *ssh.Options) *ssh.Cmd {
   276  		passedAddress = address
   277  		passedArgs = args
   278  		return ssh.Command("", []string{"ls"}, &ssh.Options{})
   279  	}
   280  
   281  	r.PatchValue(&sshCommand, fakeSSHCommand)
   282  	runViaSSH("invalidAddress", "invalidScript")
   283  	c.Assert(passedAddress, gc.Equals, "ubuntu@invalidAddress")
   284  	c.Assert(passedArgs, gc.DeepEquals, []string{"sudo", "-n", "bash", "-c 'invalidScript'"})
   285  }