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 }