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 }