github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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/replicaset" 18 gitjujutesting "github.com/juju/testing" 19 jc "github.com/juju/testing/checkers" 20 "github.com/juju/utils/ssh" 21 gc "gopkg.in/check.v1" 22 "gopkg.in/juju/names.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/environs" 28 "github.com/juju/juju/mongo/mongotest" 29 "github.com/juju/juju/state" 30 statetesting "github.com/juju/juju/state/testing" 31 coretesting "github.com/juju/juju/testing" 32 jujuversion "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) TestReplicasetIsReset(c *gc.C) { 86 server := &gitjujutesting.MgoInstance{Params: []string{"--replSet", "juju"}} 87 err := server.Start(coretesting.Certs) 88 c.Assert(err, jc.ErrorIsNil) 89 defer server.DestroyWithLog() 90 mgoAddr := server.Addr() 91 dialInfo := server.DialInfo() 92 93 var cfg *replicaset.Config 94 dialInfo = server.DialInfo() 95 dialInfo.Addrs = []string{mgoAddr} 96 err = resetReplicaSet(dialInfo, mgoAddr) 97 98 session, err := server.Dial() 99 c.Assert(err, jc.ErrorIsNil) 100 defer session.Close() 101 cfg, err = replicaset.CurrentConfig(session) 102 c.Assert(err, jc.ErrorIsNil) 103 c.Assert(cfg.Members, gc.HasLen, 1) 104 c.Assert(cfg.Members[0].Address, gc.Equals, mgoAddr) 105 } 106 107 type backupConfigTests struct { 108 yamlFile io.Reader 109 expectedError error 110 message string 111 } 112 113 func (r *RestoreSuite) TestSetAgentAddressScript(c *gc.C) { 114 testServerAddresses := []string{ 115 "FirstNewControllerAddress:30303", 116 "SecondNewControllerAddress:30304", 117 "ThirdNewControllerAddress:30305", 118 "FourthNewControllerAddress:30306", 119 "FiftNewControllerAddress:30307", 120 "SixtNewControllerAddress:30308", 121 } 122 for _, address := range testServerAddresses { 123 template := setAgentAddressScript(address, address) 124 expectedString := fmt.Sprintf("\t\ts/- .*(:[0-9]+)/- %s\\1/\n", address) 125 logger.Infof(fmt.Sprintf("Testing with address %q", address)) 126 c.Assert(strings.Contains(template, expectedString), gc.Equals, true) 127 } 128 } 129 130 func (r *RestoreSuite) TestNewDialInfo(c *gc.C) { 131 132 cases := []struct { 133 machineTag string 134 apiPassword string 135 oldPassword string 136 expectedPassword string 137 expectedUser string 138 expectedError string 139 }{ 140 {"machine-0", 141 "", 142 "123456", 143 "123456", 144 "admin", 145 "", 146 }, 147 {"machine-1", 148 "123123", 149 "", 150 "123123", 151 "machine-1", 152 "", 153 }, 154 } 155 156 dataDir := path.Join(r.cwd, "dataDir") 157 err := os.Mkdir(dataDir, os.FileMode(0755)) 158 c.Assert(err, jc.ErrorIsNil) 159 160 logDir := path.Join(r.cwd, "logDir") 161 err = os.Mkdir(logDir, os.FileMode(0755)) 162 c.Assert(err, jc.ErrorIsNil) 163 for _, testCase := range cases { 164 machineTag, err := names.ParseTag(testCase.machineTag) 165 c.Assert(err, jc.ErrorIsNil) 166 167 configParams := agent.AgentConfigParams{ 168 Paths: agent.Paths{ 169 DataDir: dataDir, 170 LogDir: logDir, 171 }, 172 UpgradedToVersion: jujuversion.Current, 173 Tag: machineTag, 174 Controller: coretesting.ControllerTag, 175 Model: coretesting.ModelTag, 176 Password: "placeholder", 177 Nonce: "dummyNonce", 178 StateAddresses: []string{"fakeStateAddress:1234"}, 179 APIAddresses: []string{"fakeAPIAddress:12345"}, 180 CACert: coretesting.CACert, 181 } 182 statePort := 12345 183 privateAddress := "dummyPrivateAddress" 184 servingInfo := params.StateServingInfo{ 185 APIPort: 1234, 186 StatePort: statePort, 187 Cert: coretesting.CACert, 188 CAPrivateKey: "a ca key", 189 PrivateKey: "a key", 190 SharedSecret: "a secret", 191 SystemIdentity: "an identity", 192 } 193 194 conf, err := agent.NewStateMachineConfig(configParams, servingInfo) 195 c.Assert(err, jc.ErrorIsNil) 196 conf.SetOldPassword(testCase.oldPassword) 197 conf.SetPassword(testCase.apiPassword) 198 199 dialInfo, err := newDialInfo(privateAddress, conf) 200 if testCase.expectedError != "" { 201 c.Assert(err, gc.ErrorMatches, testCase.expectedError) 202 } else { 203 c.Assert(err, jc.ErrorIsNil) 204 c.Assert(dialInfo.Username, gc.Equals, testCase.expectedUser) 205 c.Assert(dialInfo.Password, gc.Equals, testCase.expectedPassword) 206 c.Assert(dialInfo.Direct, gc.Equals, true) 207 c.Assert(dialInfo.Addrs, gc.DeepEquals, []string{net.JoinHostPort(privateAddress, strconv.Itoa(statePort))}) 208 } 209 } 210 } 211 212 // TestUpdateMongoEntries has all the testing for this function to avoid creating multiple 213 // mongo instances. 214 func (r *RestoreSuite) TestUpdateMongoEntries(c *gc.C) { 215 server := &gitjujutesting.MgoInstance{} 216 err := server.Start(coretesting.Certs) 217 c.Assert(err, jc.ErrorIsNil) 218 defer server.DestroyWithLog() 219 dialInfo := server.DialInfo() 220 mgoAddr := server.Addr() 221 dialInfo.Addrs = []string{mgoAddr} 222 err = updateMongoEntries("1234", "0", "0", dialInfo) 223 c.Assert(err, gc.ErrorMatches, "cannot update machine 0 instance information: not found") 224 225 session, err := server.Dial() 226 c.Assert(err, jc.ErrorIsNil) 227 defer session.Close() 228 229 err = session.DB("juju").C("machines").Insert(bson.M{"machineid": "0", "instanceid": "0"}) 230 c.Assert(err, jc.ErrorIsNil) 231 232 query := session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"}) 233 n, err := query.Count() 234 c.Assert(err, jc.ErrorIsNil) 235 c.Assert(n, gc.Equals, 0) 236 237 err = updateMongoEntries("1234", "0", "0", dialInfo) 238 c.Assert(err, jc.ErrorIsNil) 239 240 query = session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"}) 241 n, err = query.Count() 242 c.Assert(err, jc.ErrorIsNil) 243 c.Assert(n, gc.Equals, 1) 244 } 245 246 func (r *RestoreSuite) TestNewConnection(c *gc.C) { 247 server := &gitjujutesting.MgoInstance{} 248 err := server.Start(coretesting.Certs) 249 c.Assert(err, jc.ErrorIsNil) 250 defer server.DestroyWithLog() 251 252 st := statetesting.InitializeWithArgs(c, 253 statetesting.InitializeArgs{ 254 Owner: names.NewLocalUserTag("test-admin"), 255 Clock: gitjujutesting.NewClock(coretesting.NonZeroTime()), 256 }) 257 c.Assert(st.Close(), jc.ErrorIsNil) 258 259 r.PatchValue(&mongoDefaultDialOpts, mongotest.DialOpts) 260 r.PatchValue(&environsGetNewPolicyFunc, func( 261 func(*state.State) (environs.Environ, error), 262 ) state.NewPolicyFunc { 263 return nil 264 }) 265 st, err = newStateConnection(st.ControllerTag(), st.ModelTag(), statetesting.NewMongoInfo()) 266 c.Assert(err, jc.ErrorIsNil) 267 c.Assert(st.Close(), jc.ErrorIsNil) 268 } 269 270 func (r *RestoreSuite) TestRunViaSSH(c *gc.C) { 271 var ( 272 passedAddress string 273 passedArgs []string 274 ) 275 fakeSSHCommand := func(address string, args []string, options *ssh.Options) *ssh.Cmd { 276 passedAddress = address 277 passedArgs = args 278 return ssh.Command("", []string{"ls"}, &ssh.Options{}) 279 } 280 281 r.PatchValue(&sshCommand, fakeSSHCommand) 282 runViaSSH("invalidAddress", "invalidScript") 283 c.Assert(passedAddress, gc.Equals, "ubuntu@invalidAddress") 284 c.Assert(passedArgs, gc.DeepEquals, []string{"sudo", "-n", "bash", "-c 'invalidScript'"}) 285 }