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