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  }