github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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 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/state" 29 statetesting "github.com/juju/juju/state/testing" 30 coretesting "github.com/juju/juju/testing" 31 "github.com/juju/juju/utils/ssh" 32 "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) ensureAdminUser(c *gc.C, dialInfo *mgo.DialInfo, user, password string) (added bool, err error) { 86 _, portString, err := net.SplitHostPort(dialInfo.Addrs[0]) 87 c.Assert(err, jc.ErrorIsNil) 88 port, err := strconv.Atoi(portString) 89 c.Assert(err, jc.ErrorIsNil) 90 return mongo.EnsureAdminUser(mongo.EnsureAdminUserParams{ 91 DialInfo: dialInfo, 92 Port: port, 93 User: user, 94 Password: password, 95 }) 96 } 97 98 func (r *RestoreSuite) TestReplicasetIsReset(c *gc.C) { 99 server := &gitjujutesting.MgoInstance{Params: []string{"--replSet", "juju"}} 100 err := server.Start(coretesting.Certs) 101 c.Assert(err, jc.ErrorIsNil) 102 defer server.DestroyWithLog() 103 mgoAddr := server.Addr() 104 dialInfo := server.DialInfo() 105 106 var cfg *replicaset.Config 107 dialInfo = server.DialInfo() 108 dialInfo.Addrs = []string{mgoAddr} 109 err = resetReplicaSet(dialInfo, mgoAddr) 110 111 session := server.MustDial() 112 defer session.Close() 113 cfg, err = replicaset.CurrentConfig(session) 114 c.Assert(err, jc.ErrorIsNil) 115 c.Assert(cfg.Members, gc.HasLen, 1) 116 c.Assert(cfg.Members[0].Address, gc.Equals, mgoAddr) 117 } 118 119 type backupConfigTests struct { 120 yamlFile io.Reader 121 expectedError error 122 message string 123 } 124 125 var yamlLines = []string{ 126 "# format 1.18", 127 "bogus: aBogusValue", 128 "tag: aTag", 129 "statepassword: aStatePassword", 130 "oldpassword: anOldPassword", 131 "stateport: 1", 132 "apiport: 2", 133 "cacert: aLengthyCACert", 134 } 135 136 func (r *RestoreSuite) TestSetAgentAddressScript(c *gc.C) { 137 testServerAddresses := []string{ 138 "FirstNewStateServerAddress:30303", 139 "SecondNewStateServerAddress:30304", 140 "ThirdNewStateServerAddress:30305", 141 "FourthNewStateServerAddress:30306", 142 "FiftNewStateServerAddress:30307", 143 "SixtNewStateServerAddress:30308", 144 } 145 for _, address := range testServerAddresses { 146 template := setAgentAddressScript(address) 147 expectedString := fmt.Sprintf("\t\ts/- .*(:[0-9]+)/- %s\\1/\n", address) 148 logger.Infof(fmt.Sprintf("Testing with address %q", address)) 149 c.Assert(strings.Contains(template, expectedString), gc.Equals, true) 150 } 151 } 152 153 var caCertPEM = ` 154 -----BEGIN CERTIFICATE----- 155 MIIBnTCCAUmgAwIBAgIBADALBgkqhkiG9w0BAQUwJjENMAsGA1UEChMEanVqdTEV 156 MBMGA1UEAxMManVqdSB0ZXN0aW5nMB4XDTEyMTExNDE0Mzg1NFoXDTIyMTExNDE0 157 NDM1NFowJjENMAsGA1UEChMEanVqdTEVMBMGA1UEAxMManVqdSB0ZXN0aW5nMFow 158 CwYJKoZIhvcNAQEBA0sAMEgCQQCCOOpn9aWKcKr2GQGtygwD7PdfNe1I9BYiPAqa 159 2I33F5+6PqFdfujUKvoyTJI6XG4Qo/CECaaN9smhyq9DxzMhAgMBAAGjZjBkMA4G 160 A1UdDwEB/wQEAwIABDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQQDswP 161 FQGeGMeTzPbHW62EZbbTJzAfBgNVHSMEGDAWgBQQDswPFQGeGMeTzPbHW62EZbbT 162 JzALBgkqhkiG9w0BAQUDQQAqZzN0DqUyEfR8zIanozyD2pp10m9le+ODaKZDDNfH 163 8cB2x26F1iZ8ccq5IC2LtQf1IKJnpTcYlLuDvW6yB96g 164 -----END CERTIFICATE----- 165 ` 166 167 func (r *RestoreSuite) TestNewDialInfo(c *gc.C) { 168 machineTag, err := names.ParseTag("machine-0") 169 c.Assert(err, jc.ErrorIsNil) 170 171 dataDir := path.Join(r.cwd, "dataDir") 172 err = os.Mkdir(dataDir, os.FileMode(0755)) 173 c.Assert(err, jc.ErrorIsNil) 174 175 logDir := path.Join(r.cwd, "logDir") 176 err = os.Mkdir(logDir, os.FileMode(0755)) 177 c.Assert(err, jc.ErrorIsNil) 178 179 configParams := agent.AgentConfigParams{ 180 Paths: agent.Paths{ 181 DataDir: dataDir, 182 LogDir: logDir, 183 }, 184 UpgradedToVersion: version.Current.Number, 185 Tag: machineTag, 186 Environment: coretesting.EnvironmentTag, 187 Password: "dummyPassword", 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 208 dialInfo, err := newDialInfo(privateAddress, conf) 209 c.Assert(err, jc.ErrorIsNil) 210 c.Assert(dialInfo.Username, gc.Equals, "admin") 211 c.Assert(dialInfo.Password, gc.Equals, "dummyPassword") 212 c.Assert(dialInfo.Direct, gc.Equals, true) 213 c.Assert(dialInfo.Addrs, gc.DeepEquals, []string{fmt.Sprintf("%s:%d", privateAddress, statePort)}) 214 } 215 216 // TestUpdateMongoEntries has all the testing for this function to avoid creating multiple 217 // mongo instances. 218 func (r *RestoreSuite) TestUpdateMongoEntries(c *gc.C) { 219 server := &gitjujutesting.MgoInstance{} 220 err := server.Start(coretesting.Certs) 221 c.Assert(err, jc.ErrorIsNil) 222 defer server.DestroyWithLog() 223 dialInfo := server.DialInfo() 224 mgoAddr := server.Addr() 225 dialInfo.Addrs = []string{mgoAddr} 226 err = updateMongoEntries("1234", "0", "0", dialInfo) 227 c.Assert(err, gc.ErrorMatches, "cannot update machine 0 instance information: not found") 228 229 session := server.MustDial() 230 defer session.Close() 231 232 err = session.DB("juju").C("machines").Insert(bson.M{"machineid": "0", "instanceid": "0"}) 233 c.Assert(err, jc.ErrorIsNil) 234 235 query := session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"}) 236 n, err := query.Count() 237 c.Assert(err, jc.ErrorIsNil) 238 c.Assert(n, gc.Equals, 0) 239 240 err = updateMongoEntries("1234", "0", "0", dialInfo) 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, 1) 247 } 248 249 func (r *RestoreSuite) TestNewConnection(c *gc.C) { 250 server := &gitjujutesting.MgoInstance{} 251 err := server.Start(coretesting.Certs) 252 c.Assert(err, jc.ErrorIsNil) 253 defer server.DestroyWithLog() 254 255 st := statetesting.Initialize(c, names.NewLocalUserTag("test-admin"), nil, nil) 256 c.Assert(st.Close(), jc.ErrorIsNil) 257 258 r.PatchValue(&mongoDefaultDialOpts, statetesting.NewDialOpts) 259 r.PatchValue(&environsNewStatePolicy, func() state.Policy { return nil }) 260 st, err = newStateConnection(st.EnvironTag(), statetesting.NewMongoInfo()) 261 c.Assert(err, jc.ErrorIsNil) 262 c.Assert(st.Close(), jc.ErrorIsNil) 263 } 264 265 func (r *RestoreSuite) TestRunViaSSH(c *gc.C) { 266 var ( 267 passedAddress string 268 passedArgs []string 269 ) 270 fakeSSHCommand := func(address string, args []string, options *ssh.Options) *ssh.Cmd { 271 passedAddress = address 272 passedArgs = args 273 return ssh.Command("", []string{"ls"}, &ssh.Options{}) 274 } 275 276 r.PatchValue(&sshCommand, fakeSSHCommand) 277 runViaSSH("invalidAddress", "invalidScript") 278 c.Assert(passedAddress, gc.Equals, "ubuntu@invalidAddress") 279 c.Assert(passedArgs, gc.DeepEquals, []string{"sudo", "-n", "bash", "-c 'invalidScript'"}) 280 }