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