github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/api/state_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package api_test 5 6 import ( 7 stdtesting "testing" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/api" 13 jujutesting "github.com/juju/juju/juju/testing" 14 "github.com/juju/juju/network" 15 coretesting "github.com/juju/juju/testing" 16 ) 17 18 func TestAll(t *stdtesting.T) { 19 coretesting.MgoTestPackage(t) 20 } 21 22 type stateSuite struct { 23 jujutesting.JujuConnSuite 24 } 25 26 var _ = gc.Suite(&stateSuite{}) 27 28 type slideSuite struct { 29 coretesting.BaseSuite 30 } 31 32 var _ = gc.Suite(&slideSuite{}) 33 34 func (s *stateSuite) TestCloseMultipleOk(c *gc.C) { 35 c.Assert(s.APIState.Close(), gc.IsNil) 36 c.Assert(s.APIState.Close(), gc.IsNil) 37 c.Assert(s.APIState.Close(), gc.IsNil) 38 } 39 40 // OpenAPIWithoutLogin connects to the API and returns an api.State without 41 // actually calling st.Login already. The returned strings are the "tag" and 42 // "password" that we would have used to login. 43 func (s *stateSuite) OpenAPIWithoutLogin(c *gc.C) (*api.State, string, string) { 44 info := s.APIInfo(c) 45 tag := info.Tag 46 password := info.Password 47 info.Tag = nil 48 info.Password = "" 49 apistate, err := api.Open(info, api.DialOpts{}) 50 c.Assert(err, jc.ErrorIsNil) 51 return apistate, tag.String(), password 52 } 53 54 func (s *stateSuite) TestAPIHostPortsAlwaysIncludesTheConnection(c *gc.C) { 55 hostportslist := s.APIState.APIHostPorts() 56 c.Check(hostportslist, gc.HasLen, 1) 57 serverhostports := hostportslist[0] 58 c.Check(serverhostports, gc.HasLen, 1) 59 // the other addresses, but always see this one as well. 60 info := s.APIInfo(c) 61 // We intentionally set this to invalid values 62 badValue := network.HostPort{network.Address{ 63 Value: "0.1.2.3", 64 Type: network.IPv4Address, 65 NetworkName: "", 66 Scope: network.ScopeMachineLocal, 67 }, 1234} 68 badServer := []network.HostPort{badValue} 69 s.State.SetAPIHostPorts([][]network.HostPort{badServer}) 70 apistate, err := api.Open(info, api.DialOpts{}) 71 c.Assert(err, jc.ErrorIsNil) 72 defer apistate.Close() 73 hostports := apistate.APIHostPorts() 74 c.Check(hostports, gc.DeepEquals, [][]network.HostPort{serverhostports, badServer}) 75 } 76 77 func (s *stateSuite) TestLoginSetsEnvironTag(c *gc.C) { 78 env, err := s.State.Environment() 79 c.Assert(err, jc.ErrorIsNil) 80 apistate, tag, password := s.OpenAPIWithoutLogin(c) 81 defer apistate.Close() 82 // We haven't called Login yet, so the EnvironTag shouldn't be set. 83 envTag, err := apistate.EnvironTag() 84 c.Check(err, gc.ErrorMatches, `"" is not a valid tag`) 85 c.Check(envTag.String(), gc.Equals, "environment-") 86 err = apistate.Login(tag, password, "") 87 c.Assert(err, jc.ErrorIsNil) 88 // Now that we've logged in, EnvironTag should be updated correctly. 89 envTag, err = apistate.EnvironTag() 90 c.Check(err, jc.ErrorIsNil) 91 c.Check(envTag, gc.Equals, env.EnvironTag()) 92 } 93 94 func (s *stateSuite) TestLoginTracksFacadeVersions(c *gc.C) { 95 apistate, tag, password := s.OpenAPIWithoutLogin(c) 96 defer apistate.Close() 97 // We haven't called Login yet, so the Facade Versions should be empty 98 c.Check(apistate.AllFacadeVersions(), gc.HasLen, 0) 99 err := apistate.Login(tag, password, "") 100 c.Assert(err, jc.ErrorIsNil) 101 // Now that we've logged in, AllFacadeVersions should be updated. 102 allVersions := apistate.AllFacadeVersions() 103 c.Check(allVersions, gc.Not(gc.HasLen), 0) 104 // For sanity checking, ensure that we have a v0 of the Client facade 105 c.Assert(allVersions["Client"], gc.Not(gc.HasLen), 0) 106 c.Check(allVersions["Client"][0], gc.Equals, 0) 107 } 108 109 func (s *stateSuite) TestAllFacadeVersionsSafeFromMutation(c *gc.C) { 110 allVersions := s.APIState.AllFacadeVersions() 111 clients := allVersions["Client"] 112 origClients := make([]int, len(clients)) 113 copy(origClients, clients) 114 // Mutating the dict should not affect the cached versions 115 allVersions["Client"] = append(allVersions["Client"], 2597) 116 newVersions := s.APIState.AllFacadeVersions() 117 newClientVers := newVersions["Client"] 118 c.Check(newClientVers, gc.DeepEquals, origClients) 119 c.Check(newClientVers[len(newClientVers)-1], gc.Not(gc.Equals), 2597) 120 } 121 122 func (s *stateSuite) TestBestFacadeVersion(c *gc.C) { 123 c.Check(s.APIState.BestFacadeVersion("Client"), gc.Equals, 0) 124 } 125 126 func (s *stateSuite) TestAPIHostPortsMovesConnectedValueFirst(c *gc.C) { 127 hostportslist := s.APIState.APIHostPorts() 128 c.Check(hostportslist, gc.HasLen, 1) 129 serverhostports := hostportslist[0] 130 c.Check(serverhostports, gc.HasLen, 1) 131 goodAddress := serverhostports[0] 132 // the other addresses, but always see this one as well. 133 info := s.APIInfo(c) 134 // We intentionally set this to invalid values 135 badValue := network.HostPort{network.Address{ 136 Value: "0.1.2.3", 137 Type: network.IPv4Address, 138 NetworkName: "", 139 Scope: network.ScopeMachineLocal, 140 }, 1234} 141 badServer := []network.HostPort{badValue} 142 extraAddress := network.HostPort{network.Address{ 143 Value: "0.1.2.4", 144 Type: network.IPv4Address, 145 NetworkName: "", 146 Scope: network.ScopeMachineLocal, 147 }, 5678} 148 extraAddress2 := network.HostPort{network.Address{ 149 Value: "0.1.2.1", 150 Type: network.IPv4Address, 151 NetworkName: "", 152 Scope: network.ScopeMachineLocal, 153 }, 9012} 154 serverExtra := []network.HostPort{extraAddress, goodAddress, extraAddress2} 155 current := [][]network.HostPort{badServer, serverExtra} 156 s.State.SetAPIHostPorts(current) 157 apistate, err := api.Open(info, api.DialOpts{}) 158 c.Assert(err, jc.ErrorIsNil) 159 defer apistate.Close() 160 hostports := apistate.APIHostPorts() 161 // We should have rotate the server we connected to as the first item, 162 // and the address of that server as the first address 163 sortedServer := []network.HostPort{goodAddress, extraAddress, extraAddress2} 164 expected := [][]network.HostPort{sortedServer, badServer} 165 c.Check(hostports, gc.DeepEquals, expected) 166 } 167 168 var exampleHostPorts = []network.HostPort{ 169 { 170 Address: network.Address{ 171 Value: "0.1.2.3", 172 Type: network.IPv4Address, 173 NetworkName: "", 174 Scope: network.ScopeUnknown, 175 }, Port: 1234, 176 }, { 177 Address: network.Address{ 178 Value: "0.1.2.4", 179 Type: network.IPv4Address, 180 NetworkName: "", 181 Scope: network.ScopeUnknown, 182 }, Port: 5678, 183 }, { 184 Address: network.Address{ 185 Value: "0.1.2.1", 186 Type: network.IPv4Address, 187 NetworkName: "", 188 Scope: network.ScopeUnknown, 189 }, Port: 9012, 190 }, { 191 Address: network.Address{ 192 Value: "0.1.9.1", 193 Type: network.IPv4Address, 194 NetworkName: "", 195 Scope: network.ScopeUnknown, 196 }, Port: 8888, 197 }, 198 } 199 200 func (s *slideSuite) TestSlideToFrontNoOp(c *gc.C) { 201 servers := [][]network.HostPort{ 202 {exampleHostPorts[0]}, 203 {exampleHostPorts[1]}, 204 } 205 // order should not have changed 206 expected := [][]network.HostPort{ 207 {exampleHostPorts[0]}, 208 {exampleHostPorts[1]}, 209 } 210 api.SlideAddressToFront(servers, 0, 0) 211 c.Check(servers, gc.DeepEquals, expected) 212 } 213 214 func (s *slideSuite) TestSlideToFrontAddress(c *gc.C) { 215 servers := [][]network.HostPort{ 216 {exampleHostPorts[0], exampleHostPorts[1], exampleHostPorts[2]}, 217 {exampleHostPorts[3]}, 218 } 219 // server order should not change, but ports should be switched 220 expected := [][]network.HostPort{ 221 {exampleHostPorts[1], exampleHostPorts[0], exampleHostPorts[2]}, 222 {exampleHostPorts[3]}, 223 } 224 api.SlideAddressToFront(servers, 0, 1) 225 c.Check(servers, gc.DeepEquals, expected) 226 } 227 228 func (s *slideSuite) TestSlideToFrontServer(c *gc.C) { 229 servers := [][]network.HostPort{ 230 {exampleHostPorts[0], exampleHostPorts[1]}, 231 {exampleHostPorts[2]}, 232 {exampleHostPorts[3]}, 233 } 234 // server 1 should be slid to the front 235 expected := [][]network.HostPort{ 236 {exampleHostPorts[2]}, 237 {exampleHostPorts[0], exampleHostPorts[1]}, 238 {exampleHostPorts[3]}, 239 } 240 api.SlideAddressToFront(servers, 1, 0) 241 c.Check(servers, gc.DeepEquals, expected) 242 } 243 244 func (s *slideSuite) TestSlideToFrontBoth(c *gc.C) { 245 servers := [][]network.HostPort{ 246 {exampleHostPorts[0]}, 247 {exampleHostPorts[1], exampleHostPorts[2]}, 248 {exampleHostPorts[3]}, 249 } 250 // server 1 should be slid to the front 251 expected := [][]network.HostPort{ 252 {exampleHostPorts[2], exampleHostPorts[1]}, 253 {exampleHostPorts[0]}, 254 {exampleHostPorts[3]}, 255 } 256 api.SlideAddressToFront(servers, 1, 1) 257 c.Check(servers, gc.DeepEquals, expected) 258 }