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