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