gopkg.in/goose.v2@v2.0.1/testservices/novaservice/service_test.go (about)

     1  // Nova double testing service - internal direct API tests
     2  
     3  package novaservice
     4  
     5  import (
     6  	"fmt"
     7  
     8  	gc "gopkg.in/check.v1"
     9  
    10  	"gopkg.in/goose.v2/nova"
    11  	"gopkg.in/goose.v2/testservices/hook"
    12  	"gopkg.in/goose.v2/testservices/neutronmodel"
    13  )
    14  
    15  type NovaSuite struct {
    16  	service              *Nova
    17  	useNeutronNetworking bool
    18  }
    19  
    20  const (
    21  	versionPath = "v2"
    22  	hostname    = "http://example.com"
    23  	region      = "region"
    24  )
    25  
    26  var _ = gc.Suite(&NovaSuite{useNeutronNetworking: true})
    27  var _ = gc.Suite(&NovaSuite{useNeutronNetworking: false})
    28  
    29  func (s *NovaSuite) SetUpSuite(c *gc.C) {
    30  	s.service = New(hostname, versionPath, "tenant", region, nil, nil)
    31  	if s.useNeutronNetworking {
    32  		c.Logf("Nova Service using Neutron Networking")
    33  		s.service.AddNeutronModel(neutronmodel.New())
    34  	} else {
    35  		c.Logf("Nova Service using Nova Networking")
    36  	}
    37  }
    38  
    39  func (s *NovaSuite) ensureNoFlavor(c *gc.C, flavor nova.FlavorDetail) {
    40  	_, err := s.service.flavor(flavor.Id)
    41  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such flavor %q", flavor.Id))
    42  }
    43  
    44  func (s *NovaSuite) ensureNoServer(c *gc.C, server nova.ServerDetail) {
    45  	_, err := s.service.server(server.Id)
    46  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such server %q", server.Id))
    47  }
    48  
    49  func (s *NovaSuite) ensureNoGroup(c *gc.C, group nova.SecurityGroup) {
    50  	_, err := s.service.securityGroup(group.Id)
    51  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such security group %s", group.Id))
    52  }
    53  
    54  func (s *NovaSuite) ensureNoOSInterface(c *gc.C, serverID string, inter nova.OSInterface) {
    55  	_, err := s.service.serverOSInterface(serverID, inter.IPAddress)
    56  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such os interface %q", inter.IPAddress))
    57  }
    58  
    59  func (s *NovaSuite) ensureNoRule(c *gc.C, rule nova.SecurityGroupRule) {
    60  	_, err := s.service.securityGroupRule(rule.Id)
    61  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such security group rule %s", rule.Id))
    62  }
    63  
    64  func (s *NovaSuite) ensureNoIP(c *gc.C, ip nova.FloatingIP) {
    65  	_, err := s.service.floatingIP(ip.Id)
    66  	c.Assert(err, gc.ErrorMatches, fmt.Sprintf("itemNotFound: No such floating IP %q", ip.Id))
    67  }
    68  
    69  func (s *NovaSuite) createFlavor(c *gc.C, flavor nova.FlavorDetail) {
    70  	s.ensureNoFlavor(c, flavor)
    71  	err := s.service.addFlavor(flavor)
    72  	c.Assert(err, gc.IsNil)
    73  }
    74  
    75  func (s *NovaSuite) createServer(c *gc.C, server nova.ServerDetail) {
    76  	s.ensureNoServer(c, server)
    77  	err := s.service.addServer(server)
    78  	c.Assert(err, gc.IsNil)
    79  }
    80  
    81  func (s *NovaSuite) createGroup(c *gc.C, group nova.SecurityGroup) {
    82  	s.ensureNoGroup(c, group)
    83  	err := s.service.addSecurityGroup(group)
    84  	c.Assert(err, gc.IsNil)
    85  }
    86  
    87  func (s *NovaSuite) createIP(c *gc.C, ip nova.FloatingIP) {
    88  	s.ensureNoIP(c, ip)
    89  	err := s.service.addFloatingIP(ip)
    90  	c.Assert(err, gc.IsNil)
    91  }
    92  
    93  func (s *NovaSuite) createOSInterface(c *gc.C, serverID string, inter nova.OSInterface) {
    94  	s.ensureNoOSInterface(c, serverID, inter)
    95  	err := s.service.AddOSInterface(serverID, inter)
    96  	c.Assert(err, gc.IsNil)
    97  }
    98  
    99  func (s *NovaSuite) deleteFlavor(c *gc.C, flavor nova.FlavorDetail) {
   100  	err := s.service.removeFlavor(flavor.Id)
   101  	c.Assert(err, gc.IsNil)
   102  	s.ensureNoFlavor(c, flavor)
   103  }
   104  
   105  func (s *NovaSuite) deleteServer(c *gc.C, server nova.ServerDetail) {
   106  	err := s.service.removeServer(server.Id)
   107  	c.Assert(err, gc.IsNil)
   108  	s.ensureNoServer(c, server)
   109  }
   110  
   111  func (s *NovaSuite) deleteGroup(c *gc.C, group nova.SecurityGroup) {
   112  	err := s.service.removeSecurityGroup(group.Id)
   113  	c.Assert(err, gc.IsNil)
   114  	s.ensureNoGroup(c, group)
   115  }
   116  
   117  func (s *NovaSuite) deleteRule(c *gc.C, rule nova.SecurityGroupRule) {
   118  	err := s.service.removeSecurityGroupRule(rule.Id)
   119  	c.Assert(err, gc.IsNil)
   120  	s.ensureNoRule(c, rule)
   121  }
   122  
   123  func (s *NovaSuite) deleteIP(c *gc.C, ip nova.FloatingIP) {
   124  	err := s.service.removeFloatingIP(ip.Id)
   125  	c.Assert(err, gc.IsNil)
   126  	s.ensureNoIP(c, ip)
   127  }
   128  
   129  func (s *NovaSuite) deleteOSInterface(c *gc.C, serverID string, inter nova.OSInterface) {
   130  	err := s.service.RemoveOSInterface(serverID, inter.IPAddress)
   131  	c.Assert(err, gc.IsNil)
   132  	s.ensureNoOSInterface(c, serverID, inter)
   133  }
   134  
   135  func (s *NovaSuite) TestAddRemoveFlavor(c *gc.C) {
   136  	flavor := nova.FlavorDetail{Id: "test"}
   137  	s.createFlavor(c, flavor)
   138  	s.deleteFlavor(c, flavor)
   139  }
   140  
   141  func (s *NovaSuite) TestBuildLinksAndAddFlavor(c *gc.C) {
   142  	flavor := nova.FlavorDetail{Id: "test"}
   143  	s.service.buildFlavorLinks(&flavor)
   144  	s.createFlavor(c, flavor)
   145  	defer s.deleteFlavor(c, flavor)
   146  	fl, _ := s.service.flavor(flavor.Id)
   147  	url := "/flavors/" + flavor.Id
   148  	links := []nova.Link{
   149  		{Href: s.service.endpointURL(true, url), Rel: "self"},
   150  		{Href: s.service.endpointURL(false, url), Rel: "bookmark"},
   151  	}
   152  	c.Assert(fl.Links, gc.DeepEquals, links)
   153  }
   154  
   155  func (s *NovaSuite) TestAddFlavorWithLinks(c *gc.C) {
   156  	flavor := nova.FlavorDetail{
   157  		Id: "test",
   158  		Links: []nova.Link{
   159  			{Href: "href", Rel: "rel"},
   160  		},
   161  	}
   162  	s.createFlavor(c, flavor)
   163  	defer s.deleteFlavor(c, flavor)
   164  	fl, _ := s.service.flavor(flavor.Id)
   165  	c.Assert(*fl, gc.DeepEquals, flavor)
   166  }
   167  
   168  func (s *NovaSuite) TestAddFlavorTwiceFails(c *gc.C) {
   169  	flavor := nova.FlavorDetail{Id: "test"}
   170  	s.createFlavor(c, flavor)
   171  	defer s.deleteFlavor(c, flavor)
   172  	err := s.service.addFlavor(flavor)
   173  	c.Assert(err, gc.ErrorMatches, `conflictingRequest: A flavor with id "test" already exists`)
   174  }
   175  
   176  func (s *NovaSuite) TestRemoveFlavorTwiceFails(c *gc.C) {
   177  	flavor := nova.FlavorDetail{Id: "test"}
   178  	s.createFlavor(c, flavor)
   179  	s.deleteFlavor(c, flavor)
   180  	err := s.service.removeFlavor(flavor.Id)
   181  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such flavor "test"`)
   182  }
   183  
   184  func (s *NovaSuite) TestAllFlavors(c *gc.C) {
   185  	// The test service has 2 default flavours.
   186  	flavors := s.service.allFlavors()
   187  	c.Assert(flavors, gc.HasLen, 3)
   188  	for _, fl := range flavors {
   189  		c.Assert(fl.Name == "m1.tiny" || fl.Name == "m1.small" || fl.Name == "m1.medium", gc.Equals, true)
   190  	}
   191  }
   192  
   193  func (s *NovaSuite) TestAllFlavorsAsEntities(c *gc.C) {
   194  	// The test service has 2 default flavours.
   195  	entities := s.service.allFlavorsAsEntities()
   196  	c.Assert(entities, gc.HasLen, 3)
   197  	for _, fl := range entities {
   198  		c.Assert(fl.Name == "m1.tiny" || fl.Name == "m1.small" || fl.Name == "m1.medium", gc.Equals, true)
   199  	}
   200  }
   201  
   202  func (s *NovaSuite) TestGetFlavor(c *gc.C) {
   203  	flavor := nova.FlavorDetail{
   204  		Id:    "test",
   205  		Name:  "flavor",
   206  		RAM:   128,
   207  		VCPUs: 2,
   208  		Disk:  123,
   209  	}
   210  	s.createFlavor(c, flavor)
   211  	defer s.deleteFlavor(c, flavor)
   212  	fl, _ := s.service.flavor(flavor.Id)
   213  	c.Assert(*fl, gc.DeepEquals, flavor)
   214  }
   215  
   216  func (s *NovaSuite) TestGetFlavorAsEntity(c *gc.C) {
   217  	entity := nova.Entity{
   218  		Id:   "test",
   219  		Name: "flavor",
   220  	}
   221  	flavor := nova.FlavorDetail{
   222  		Id:   entity.Id,
   223  		Name: entity.Name,
   224  	}
   225  	s.createFlavor(c, flavor)
   226  	defer s.deleteFlavor(c, flavor)
   227  	ent, _ := s.service.flavorAsEntity(flavor.Id)
   228  	c.Assert(*ent, gc.DeepEquals, entity)
   229  }
   230  
   231  func (s *NovaSuite) TestAddRemoveServer(c *gc.C) {
   232  	server := nova.ServerDetail{Id: "test"}
   233  	s.createServer(c, server)
   234  	s.deleteServer(c, server)
   235  }
   236  
   237  func (s *NovaSuite) TestBuildLinksAndAddServer(c *gc.C) {
   238  	server := nova.ServerDetail{Id: "test"}
   239  	s.service.buildServerLinks(&server)
   240  	s.createServer(c, server)
   241  	defer s.deleteServer(c, server)
   242  	sr, _ := s.service.server(server.Id)
   243  	url := "/servers/" + server.Id
   244  	links := []nova.Link{
   245  		{Href: s.service.endpointURL(true, url), Rel: "self"},
   246  		{Href: s.service.endpointURL(false, url), Rel: "bookmark"},
   247  	}
   248  	c.Assert(sr.Links, gc.DeepEquals, links)
   249  }
   250  
   251  func (s *NovaSuite) TestAddServerWithLinks(c *gc.C) {
   252  	server := nova.ServerDetail{
   253  		Id: "test",
   254  		Links: []nova.Link{
   255  			{Href: "href", Rel: "rel"},
   256  		},
   257  	}
   258  	s.createServer(c, server)
   259  	defer s.deleteServer(c, server)
   260  	sr, _ := s.service.server(server.Id)
   261  	server.Status = nova.StatusActive
   262  	c.Assert(*sr, gc.DeepEquals, server)
   263  }
   264  
   265  func (s *NovaSuite) TestAddServerTwiceFails(c *gc.C) {
   266  	server := nova.ServerDetail{Id: "test"}
   267  	s.createServer(c, server)
   268  	defer s.deleteServer(c, server)
   269  	err := s.service.addServer(server)
   270  	c.Assert(err, gc.ErrorMatches, `conflictingRequest: A server with id "test" already exists`)
   271  }
   272  
   273  // A control point can be used to change the name of the added server.
   274  // Changing the server status is no longer effective, due to changes
   275  // in server()
   276  func (s *NovaSuite) TestAddServerControlPoint(c *gc.C) {
   277  	cleanup := s.service.RegisterControlPoint(
   278  		"addServer",
   279  		func(sc hook.ServiceControl, args ...interface{}) error {
   280  			details := args[0].(*nova.ServerDetail)
   281  			details.Name = "test-name"
   282  			return nil
   283  		},
   284  	)
   285  	defer cleanup()
   286  
   287  	server := &nova.ServerDetail{
   288  		Id:     "test",
   289  		Status: nova.StatusActive,
   290  	}
   291  	s.createServer(c, *server)
   292  	defer s.deleteServer(c, *server)
   293  
   294  	server, _ = s.service.server(server.Id)
   295  	c.Assert(server.Name, gc.Equals, "test-name")
   296  }
   297  
   298  func (s *NovaSuite) TestRemoveServerTwiceFails(c *gc.C) {
   299  	server := nova.ServerDetail{Id: "test"}
   300  	s.createServer(c, server)
   301  	s.deleteServer(c, server)
   302  	err := s.service.removeServer(server.Id)
   303  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server "test"`)
   304  }
   305  
   306  func (s *NovaSuite) TestAllServers(c *gc.C) {
   307  	servers, err := s.service.allServers(nil)
   308  	c.Assert(err, gc.IsNil)
   309  	c.Assert(servers, gc.HasLen, 0)
   310  	servers = []nova.ServerDetail{
   311  		{Id: "sr1"},
   312  		{Id: "sr2"},
   313  	}
   314  	s.createServer(c, servers[0])
   315  	defer s.deleteServer(c, servers[1])
   316  	s.createServer(c, servers[1])
   317  	defer s.deleteServer(c, servers[0])
   318  	sr, err := s.service.allServers(nil)
   319  	c.Assert(err, gc.IsNil)
   320  	c.Assert(sr, gc.HasLen, len(servers))
   321  	if sr[0].Id != servers[0].Id {
   322  		sr[0], sr[1] = sr[1], sr[0]
   323  	}
   324  	c.Assert(sr, gc.DeepEquals, servers)
   325  }
   326  
   327  func (s *NovaSuite) TestAllServersWithFilters(c *gc.C) {
   328  	servers, err := s.service.allServers(nil)
   329  	c.Assert(err, gc.IsNil)
   330  	c.Assert(servers, gc.HasLen, 0)
   331  	servers = []nova.ServerDetail{
   332  		{Id: "sr1", Name: "test", Status: nova.StatusActive},
   333  		{Id: "sr2", Name: "other", Status: nova.StatusBuild},
   334  		{Id: "sr3", Name: "foo", Status: nova.StatusRescue},
   335  	}
   336  	for _, server := range servers {
   337  		s.createServer(c, server)
   338  		defer s.deleteServer(c, server)
   339  		server.Status = nova.StatusActive
   340  	}
   341  	f := filter{
   342  		nova.FilterStatus: nova.StatusRescue,
   343  	}
   344  	sr, err := s.service.allServers(f)
   345  	c.Assert(err, gc.IsNil)
   346  	c.Assert(sr, gc.HasLen, 1)
   347  	c.Assert(sr[0], gc.DeepEquals, servers[2])
   348  	f[nova.FilterStatus] = nova.StatusBuild
   349  	sr, err = s.service.allServers(f)
   350  	c.Assert(err, gc.IsNil)
   351  	c.Assert(sr, gc.HasLen, 1)
   352  	c.Assert(sr[0], gc.DeepEquals, servers[1])
   353  	f = filter{
   354  		nova.FilterServer: "test",
   355  	}
   356  	sr, err = s.service.allServers(f)
   357  	c.Assert(err, gc.IsNil)
   358  	c.Assert(sr, gc.HasLen, 1)
   359  	c.Assert(sr[0], gc.DeepEquals, servers[0])
   360  	f[nova.FilterServer] = "other"
   361  	sr, err = s.service.allServers(f)
   362  	c.Assert(err, gc.IsNil)
   363  	c.Assert(sr, gc.HasLen, 1)
   364  	c.Assert(sr[0], gc.DeepEquals, servers[1])
   365  	f[nova.FilterServer] = "foo"
   366  	f[nova.FilterStatus] = nova.StatusRescue
   367  	sr, err = s.service.allServers(f)
   368  	c.Assert(err, gc.IsNil)
   369  	c.Assert(sr, gc.HasLen, 1)
   370  	c.Assert(sr[0], gc.DeepEquals, servers[2])
   371  }
   372  
   373  func (s *NovaSuite) TestAllServersWithEmptyFilter(c *gc.C) {
   374  	servers, err := s.service.allServers(nil)
   375  	c.Assert(err, gc.IsNil)
   376  	c.Assert(servers, gc.HasLen, 0)
   377  	servers = []nova.ServerDetail{
   378  		{Id: "sr1", Name: "srv1"},
   379  		{Id: "sr2", Name: "srv2"},
   380  	}
   381  	for _, server := range servers {
   382  		s.createServer(c, server)
   383  		defer s.deleteServer(c, server)
   384  		server.Status = nova.StatusActive
   385  	}
   386  	sr, err := s.service.allServers(nil)
   387  	c.Assert(err, gc.IsNil)
   388  	c.Assert(sr, gc.HasLen, 2)
   389  	if sr[0].Id != servers[0].Id {
   390  		sr[0], sr[1] = sr[1], sr[0]
   391  	}
   392  	c.Assert(sr, gc.DeepEquals, servers)
   393  }
   394  
   395  func (s *NovaSuite) TestAllServersWithRegexFilters(c *gc.C) {
   396  	servers, err := s.service.allServers(nil)
   397  	c.Assert(err, gc.IsNil)
   398  	c.Assert(servers, gc.HasLen, 0)
   399  	servers = []nova.ServerDetail{
   400  		{Id: "sr1", Name: "foobarbaz"},
   401  		{Id: "sr2", Name: "foo123baz"},
   402  		{Id: "sr3", Name: "123barbaz"},
   403  		{Id: "sr4", Name: "foobar123"},
   404  	}
   405  	for _, server := range servers {
   406  		s.createServer(c, server)
   407  		defer s.deleteServer(c, server)
   408  		server.Status = nova.StatusActive
   409  	}
   410  	f := filter{
   411  		nova.FilterServer: `foo.*baz`,
   412  	}
   413  	sr, err := s.service.allServers(f)
   414  	c.Assert(err, gc.IsNil)
   415  	c.Assert(sr, gc.HasLen, 2)
   416  	if sr[0].Id != servers[0].Id {
   417  		sr[0], sr[1] = sr[1], sr[0]
   418  	}
   419  	c.Assert(sr, gc.DeepEquals, servers[:2])
   420  	f[nova.FilterServer] = `^[a-z]+[0-9]+`
   421  	sr, err = s.service.allServers(f)
   422  	c.Assert(err, gc.IsNil)
   423  	c.Assert(sr, gc.HasLen, 2)
   424  	if sr[0].Id != servers[1].Id {
   425  		sr[0], sr[1] = sr[1], sr[0]
   426  	}
   427  	c.Assert(sr[0], gc.DeepEquals, servers[1])
   428  	c.Assert(sr[1], gc.DeepEquals, servers[3])
   429  }
   430  
   431  func (s *NovaSuite) TestAllServersWithMultipleFilters(c *gc.C) {
   432  	servers, err := s.service.allServers(nil)
   433  	c.Assert(err, gc.IsNil)
   434  	c.Assert(servers, gc.HasLen, 0)
   435  	servers = []nova.ServerDetail{
   436  		{Id: "sr1", Name: "s1", Status: nova.StatusActive},
   437  		{Id: "sr2", Name: "s2", Status: nova.StatusActive},
   438  		{Id: "sr3", Name: "s3", Status: nova.StatusActive},
   439  	}
   440  	for _, server := range servers {
   441  		s.createServer(c, server)
   442  		defer s.deleteServer(c, server)
   443  	}
   444  	f := filter{
   445  		nova.FilterStatus: nova.StatusActive,
   446  		nova.FilterServer: `.*2.*`,
   447  	}
   448  	sr, err := s.service.allServers(f)
   449  	c.Assert(err, gc.IsNil)
   450  	c.Assert(sr, gc.HasLen, 1)
   451  	c.Assert(sr[0], gc.DeepEquals, servers[1])
   452  	f[nova.FilterStatus] = nova.StatusBuild
   453  	sr, err = s.service.allServers(f)
   454  	c.Assert(err, gc.IsNil)
   455  	c.Assert(sr, gc.HasLen, 0)
   456  	f[nova.FilterStatus] = nova.StatusPassword
   457  	f[nova.FilterServer] = `.*[23].*`
   458  	sr, err = s.service.allServers(f)
   459  	c.Assert(err, gc.IsNil)
   460  	c.Assert(sr, gc.HasLen, 0)
   461  	f[nova.FilterStatus] = nova.StatusActive
   462  	sr, err = s.service.allServers(f)
   463  	c.Assert(err, gc.IsNil)
   464  	c.Assert(sr, gc.HasLen, 2)
   465  	if sr[0].Id != servers[1].Id {
   466  		sr[0], sr[1] = sr[1], sr[0]
   467  	}
   468  	c.Assert(sr, gc.DeepEquals, servers[1:])
   469  }
   470  
   471  func (s *NovaSuite) TestAllServersAsEntities(c *gc.C) {
   472  	entities, err := s.service.allServersAsEntities(nil)
   473  	c.Assert(err, gc.IsNil)
   474  	c.Assert(entities, gc.HasLen, 0)
   475  	entities = []nova.Entity{
   476  		{Id: "sr1"},
   477  		{Id: "sr2"},
   478  	}
   479  	servers := []nova.ServerDetail{
   480  		{Id: entities[0].Id},
   481  		{Id: entities[1].Id},
   482  	}
   483  	s.createServer(c, servers[0])
   484  	defer s.deleteServer(c, servers[0])
   485  	s.createServer(c, servers[1])
   486  	defer s.deleteServer(c, servers[1])
   487  	ent, err := s.service.allServersAsEntities(nil)
   488  	c.Assert(err, gc.IsNil)
   489  	c.Assert(ent, gc.HasLen, len(entities))
   490  	if ent[0].Id != entities[0].Id {
   491  		ent[0], ent[1] = ent[1], ent[0]
   492  	}
   493  	c.Assert(ent, gc.DeepEquals, entities)
   494  }
   495  
   496  func (s *NovaSuite) TestAllServersAsEntitiesWithFilters(c *gc.C) {
   497  	servers, err := s.service.allServers(nil)
   498  	c.Assert(err, gc.IsNil)
   499  	c.Assert(servers, gc.HasLen, 0)
   500  	servers = []nova.ServerDetail{
   501  		{Id: "sr1", Name: "test", Status: nova.StatusActive},
   502  		{Id: "sr2", Name: "other", Status: nova.StatusBuild},
   503  		{Id: "sr3", Name: "foo", Status: nova.StatusRescue},
   504  	}
   505  	entities := []nova.Entity{}
   506  	for _, server := range servers {
   507  		s.createServer(c, server)
   508  		defer s.deleteServer(c, server)
   509  		entities = append(entities, nova.Entity{
   510  			Id:    server.Id,
   511  			Name:  server.Name,
   512  			Links: server.Links,
   513  		})
   514  	}
   515  	f := filter{
   516  		nova.FilterStatus: nova.StatusRescue,
   517  	}
   518  	ent, err := s.service.allServersAsEntities(f)
   519  	c.Assert(err, gc.IsNil)
   520  	c.Assert(ent, gc.HasLen, 1)
   521  	c.Assert(ent[0], gc.DeepEquals, entities[2])
   522  	f[nova.FilterStatus] = nova.StatusBuild
   523  	ent, err = s.service.allServersAsEntities(f)
   524  	c.Assert(err, gc.IsNil)
   525  	c.Assert(ent, gc.HasLen, 1)
   526  	c.Assert(ent[0], gc.DeepEquals, entities[1])
   527  	f = filter{
   528  		nova.FilterServer: "test",
   529  	}
   530  	ent, err = s.service.allServersAsEntities(f)
   531  	c.Assert(err, gc.IsNil)
   532  	c.Assert(ent, gc.HasLen, 1)
   533  	c.Assert(ent[0], gc.DeepEquals, entities[0])
   534  	f[nova.FilterServer] = "other"
   535  	ent, err = s.service.allServersAsEntities(f)
   536  	c.Assert(err, gc.IsNil)
   537  	c.Assert(ent, gc.HasLen, 1)
   538  	c.Assert(ent[0], gc.DeepEquals, entities[1])
   539  	f[nova.FilterServer] = "foo"
   540  	f[nova.FilterStatus] = nova.StatusRescue
   541  	ent, err = s.service.allServersAsEntities(f)
   542  	c.Assert(err, gc.IsNil)
   543  	c.Assert(ent, gc.HasLen, 1)
   544  	c.Assert(ent[0], gc.DeepEquals, entities[2])
   545  }
   546  
   547  func (s *NovaSuite) TestGetServer(c *gc.C) {
   548  	server := nova.ServerDetail{
   549  		Id:          "test",
   550  		Name:        "server",
   551  		AddressIPv4: "1.2.3.4",
   552  		AddressIPv6: "1::fff",
   553  		Created:     "1/1/1",
   554  		Flavor:      nova.Entity{Id: "fl1", Name: "flavor1"},
   555  		Image:       nova.Entity{Id: "im1", Name: "image1"},
   556  		HostId:      "myhost",
   557  		Progress:    123,
   558  		Status:      "st",
   559  		TenantId:    "tenant",
   560  		Updated:     "2/3/4",
   561  		UserId:      "user",
   562  	}
   563  	s.createServer(c, server)
   564  	defer s.deleteServer(c, server)
   565  	server.Status = nova.StatusActive
   566  	sr, _ := s.service.server(server.Id)
   567  	c.Assert(*sr, gc.DeepEquals, server)
   568  }
   569  
   570  func (s *NovaSuite) TestGetServerAsEntity(c *gc.C) {
   571  	entity := nova.Entity{
   572  		Id:   "test",
   573  		Name: "server",
   574  	}
   575  	server := nova.ServerDetail{
   576  		Id:   entity.Id,
   577  		Name: entity.Name,
   578  	}
   579  	s.createServer(c, server)
   580  	defer s.deleteServer(c, server)
   581  	ent, _ := s.service.serverAsEntity(server.Id)
   582  	c.Assert(*ent, gc.DeepEquals, entity)
   583  }
   584  
   585  func (s *NovaSuite) TestGetServerByName(c *gc.C) {
   586  	named, err := s.service.serverByName("test")
   587  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server named "test"`)
   588  	servers := []nova.ServerDetail{
   589  		{Id: "sr1", Name: "test"},
   590  		{Id: "sr2", Name: "test"},
   591  		{Id: "sr3", Name: "not test"},
   592  	}
   593  	for _, server := range servers {
   594  		s.createServer(c, server)
   595  		defer s.deleteServer(c, server)
   596  		server.Status = nova.StatusActive
   597  	}
   598  	named, err = s.service.serverByName("test")
   599  	c.Assert(err, gc.IsNil)
   600  	// order is not guaranteed, so check both possible results
   601  	if named.Id == servers[0].Id {
   602  		c.Assert(*named, gc.DeepEquals, servers[0])
   603  	} else {
   604  		c.Assert(*named, gc.DeepEquals, servers[1])
   605  	}
   606  }
   607  
   608  func (s *NovaSuite) TestAddRemoveSecurityGroup(c *gc.C) {
   609  	if s.service.useNeutronNetworking {
   610  		c.Skip("skipped in novaservice when using Neutron Model")
   611  	}
   612  	group := nova.SecurityGroup{Id: "1"}
   613  	s.createGroup(c, group)
   614  	s.deleteGroup(c, group)
   615  }
   616  
   617  func (s *NovaSuite) TestAddSecurityGroupWithRules(c *gc.C) {
   618  	if s.service.useNeutronNetworking {
   619  		c.Skip("skipped in novaservice when using Neutron Model")
   620  	}
   621  	group := nova.SecurityGroup{
   622  		Id:       "1",
   623  		Name:     "test",
   624  		TenantId: s.service.TenantId,
   625  		Rules: []nova.SecurityGroupRule{
   626  			{Id: "10", ParentGroupId: "1"},
   627  			{Id: "20", ParentGroupId: "1"},
   628  		},
   629  	}
   630  	s.createGroup(c, group)
   631  	defer s.deleteGroup(c, group)
   632  	gr, _ := s.service.securityGroup(group.Id)
   633  	c.Assert(*gr, gc.DeepEquals, group)
   634  }
   635  
   636  func (s *NovaSuite) TestAddSecurityGroupTwiceFails(c *gc.C) {
   637  	if s.service.useNeutronNetworking {
   638  		c.Skip("skipped in novaservice when using Neutron Model")
   639  	}
   640  	group := nova.SecurityGroup{Id: "1", Name: "test"}
   641  	s.createGroup(c, group)
   642  	defer s.deleteGroup(c, group)
   643  	err := s.service.addSecurityGroup(group)
   644  	c.Assert(err, gc.ErrorMatches, "conflictingRequest: A security group with id 1 already exists")
   645  }
   646  
   647  func (s *NovaSuite) TestRemoveSecurityGroupTwiceFails(c *gc.C) {
   648  	if s.service.useNeutronNetworking {
   649  		c.Skip("skipped in novaservice when using Neutron Model")
   650  	}
   651  	group := nova.SecurityGroup{Id: "1", Name: "test"}
   652  	s.createGroup(c, group)
   653  	s.deleteGroup(c, group)
   654  	err := s.service.removeSecurityGroup(group.Id)
   655  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such security group 1")
   656  }
   657  
   658  func (s *NovaSuite) TestAllSecurityGroups(c *gc.C) {
   659  	if s.service.useNeutronNetworking {
   660  		c.Skip("skipped in novaservice when using Neutron Model")
   661  	}
   662  	groups := s.service.allSecurityGroups()
   663  	// There is always a default security group.
   664  	c.Assert(groups, gc.HasLen, 1)
   665  	groups = []nova.SecurityGroup{
   666  		{
   667  			Id:       "1",
   668  			Name:     "one",
   669  			TenantId: s.service.TenantId,
   670  			Rules:    []nova.SecurityGroupRule{},
   671  		},
   672  		{
   673  			Id:       "2",
   674  			Name:     "two",
   675  			TenantId: s.service.TenantId,
   676  			Rules:    []nova.SecurityGroupRule{},
   677  		},
   678  	}
   679  	s.createGroup(c, groups[0])
   680  	defer s.deleteGroup(c, groups[0])
   681  	s.createGroup(c, groups[1])
   682  	defer s.deleteGroup(c, groups[1])
   683  	gr := s.service.allSecurityGroups()
   684  	c.Assert(gr, gc.HasLen, len(groups)+1)
   685  	checkGroupsInList(c, groups, gr)
   686  }
   687  
   688  func (s *NovaSuite) TestGetSecurityGroup(c *gc.C) {
   689  	if s.service.useNeutronNetworking {
   690  		c.Skip("skipped in novaservice when using Neutron Model")
   691  	}
   692  	group := nova.SecurityGroup{
   693  		Id:          "42",
   694  		TenantId:    s.service.TenantId,
   695  		Name:        "group",
   696  		Description: "desc",
   697  		Rules:       []nova.SecurityGroupRule{},
   698  	}
   699  	s.createGroup(c, group)
   700  	defer s.deleteGroup(c, group)
   701  	gr, _ := s.service.securityGroup(group.Id)
   702  	c.Assert(*gr, gc.DeepEquals, group)
   703  }
   704  
   705  func (s *NovaSuite) TestGetSecurityGroupByName(c *gc.C) {
   706  	if s.service.useNeutronNetworking {
   707  		c.Skip("skipped in novaservice when using Neutron Model")
   708  	}
   709  	group := nova.SecurityGroup{
   710  		Id:       "1",
   711  		Name:     "test",
   712  		TenantId: s.service.TenantId,
   713  		Rules:    []nova.SecurityGroupRule{},
   714  	}
   715  	s.ensureNoGroup(c, group)
   716  	gr, err := s.service.securityGroupByName(group.Name)
   717  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such security group named "test"`)
   718  	s.createGroup(c, group)
   719  	defer s.deleteGroup(c, group)
   720  	gr, err = s.service.securityGroupByName(group.Name)
   721  	c.Assert(err, gc.IsNil)
   722  	c.Assert(*gr, gc.DeepEquals, group)
   723  }
   724  
   725  func (s *NovaSuite) TestAddHasRemoveSecurityGroupRule(c *gc.C) {
   726  	if s.service.useNeutronNetworking {
   727  		c.Skip("skipped in novaservice when using Neutron Model")
   728  	}
   729  	group := nova.SecurityGroup{Id: "1"}
   730  	ri := nova.RuleInfo{ParentGroupId: group.Id, GroupId: &group.Id}
   731  	rule := nova.SecurityGroupRule{Id: "10", ParentGroupId: group.Id}
   732  	s.ensureNoGroup(c, group)
   733  	s.ensureNoRule(c, rule)
   734  	ok := s.service.hasSecurityGroupRule(group.Id, rule.Id)
   735  	c.Assert(ok, gc.Equals, false)
   736  	s.createGroup(c, group)
   737  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   738  	c.Assert(err, gc.IsNil)
   739  	ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)
   740  	c.Assert(ok, gc.Equals, true)
   741  	s.deleteGroup(c, group)
   742  	ok = s.service.hasSecurityGroupRule("-1", rule.Id)
   743  	c.Assert(ok, gc.Equals, true)
   744  	ok = s.service.hasSecurityGroupRule(group.Id, rule.Id)
   745  	c.Assert(ok, gc.Equals, false)
   746  	s.deleteRule(c, rule)
   747  	ok = s.service.hasSecurityGroupRule("-1", rule.Id)
   748  	c.Assert(ok, gc.Equals, false)
   749  }
   750  
   751  func (s *NovaSuite) TestAddGetIngressSecurityGroupRule(c *gc.C) {
   752  	if s.service.useNeutronNetworking {
   753  		c.Skip("skipped in novaservice when using Neutron Model")
   754  	}
   755  	group := nova.SecurityGroup{Id: "1"}
   756  	s.createGroup(c, group)
   757  	defer s.deleteGroup(c, group)
   758  	ri := nova.RuleInfo{
   759  		FromPort:      1234,
   760  		ToPort:        4321,
   761  		IPProtocol:    "tcp",
   762  		Cidr:          "1.2.3.4/5",
   763  		ParentGroupId: group.Id,
   764  	}
   765  	rule := nova.SecurityGroupRule{
   766  		Id:            "10",
   767  		ParentGroupId: group.Id,
   768  		FromPort:      &ri.FromPort,
   769  		ToPort:        &ri.ToPort,
   770  		IPProtocol:    &ri.IPProtocol,
   771  		IPRange:       make(map[string]string),
   772  	}
   773  	rule.IPRange["cidr"] = ri.Cidr
   774  	s.ensureNoRule(c, rule)
   775  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   776  	c.Assert(err, gc.IsNil)
   777  	defer s.deleteRule(c, rule)
   778  	ru, err := s.service.securityGroupRule(rule.Id)
   779  	c.Assert(err, gc.IsNil)
   780  	c.Assert(ru.Id, gc.Equals, rule.Id)
   781  	c.Assert(ru.ParentGroupId, gc.Equals, rule.ParentGroupId)
   782  	c.Assert(*ru.FromPort, gc.Equals, *rule.FromPort)
   783  	c.Assert(*ru.ToPort, gc.Equals, *rule.ToPort)
   784  	c.Assert(*ru.IPProtocol, gc.Equals, *rule.IPProtocol)
   785  	c.Assert(ru.IPRange, gc.DeepEquals, rule.IPRange)
   786  }
   787  
   788  func (s *NovaSuite) TestAddGetGroupSecurityGroupRule(c *gc.C) {
   789  	if s.service.useNeutronNetworking {
   790  		c.Skip("skipped in novaservice when using Neutron Model")
   791  	}
   792  	srcGroup := nova.SecurityGroup{Id: "1", Name: "source", TenantId: s.service.TenantId}
   793  	tgtGroup := nova.SecurityGroup{Id: "2", Name: "target"}
   794  	s.createGroup(c, srcGroup)
   795  	defer s.deleteGroup(c, srcGroup)
   796  	s.createGroup(c, tgtGroup)
   797  	defer s.deleteGroup(c, tgtGroup)
   798  	ri := nova.RuleInfo{
   799  		FromPort:      1234,
   800  		ToPort:        4321,
   801  		IPProtocol:    "tcp",
   802  		GroupId:       &srcGroup.Id,
   803  		ParentGroupId: tgtGroup.Id,
   804  	}
   805  	rule := nova.SecurityGroupRule{
   806  		Id:            "10",
   807  		ParentGroupId: tgtGroup.Id,
   808  		FromPort:      &ri.FromPort,
   809  		ToPort:        &ri.ToPort,
   810  		IPProtocol:    &ri.IPProtocol,
   811  		Group: nova.SecurityGroupRef{
   812  			TenantId: srcGroup.TenantId,
   813  			Name:     srcGroup.Name,
   814  		},
   815  	}
   816  	s.ensureNoRule(c, rule)
   817  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   818  	c.Assert(err, gc.IsNil)
   819  	defer s.deleteRule(c, rule)
   820  	ru, err := s.service.securityGroupRule(rule.Id)
   821  	c.Assert(err, gc.IsNil)
   822  	c.Assert(ru.Id, gc.Equals, rule.Id)
   823  	c.Assert(ru.ParentGroupId, gc.Equals, rule.ParentGroupId)
   824  	c.Assert(*ru.FromPort, gc.Equals, *rule.FromPort)
   825  	c.Assert(*ru.ToPort, gc.Equals, *rule.ToPort)
   826  	c.Assert(*ru.IPProtocol, gc.Equals, *rule.IPProtocol)
   827  	c.Assert(ru.Group, gc.DeepEquals, rule.Group)
   828  }
   829  
   830  func (s *NovaSuite) TestAddSecurityGroupRuleTwiceFails(c *gc.C) {
   831  	if s.service.useNeutronNetworking {
   832  		c.Skip("skipped in novaservice when using Neutron Model")
   833  	}
   834  	group := nova.SecurityGroup{Id: "1"}
   835  	s.createGroup(c, group)
   836  	defer s.deleteGroup(c, group)
   837  	ri := nova.RuleInfo{ParentGroupId: group.Id, GroupId: &group.Id}
   838  	rule := nova.SecurityGroupRule{Id: "10"}
   839  	s.ensureNoRule(c, rule)
   840  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   841  	c.Assert(err, gc.IsNil)
   842  	defer s.deleteRule(c, rule)
   843  	err = s.service.addSecurityGroupRule(rule.Id, ri)
   844  	c.Assert(err, gc.ErrorMatches, "conflictingRequest: A security group rule with id 10 already exists")
   845  }
   846  
   847  func (s *NovaSuite) TestAddSecurityGroupRuleToParentTwiceFails(c *gc.C) {
   848  	if s.service.useNeutronNetworking {
   849  		c.Skip("skipped in novaservice when using Neutron Model")
   850  	}
   851  	group := nova.SecurityGroup{
   852  		Id: "1",
   853  		Rules: []nova.SecurityGroupRule{
   854  			{Id: "10"},
   855  		},
   856  	}
   857  	s.createGroup(c, group)
   858  	defer s.deleteGroup(c, group)
   859  	ri := nova.RuleInfo{ParentGroupId: group.Id}
   860  	rule := nova.SecurityGroupRule{Id: "10"}
   861  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   862  	c.Assert(err, gc.ErrorMatches, "conflictingRequest: Cannot add twice rule 10 to security group 1")
   863  }
   864  
   865  func (s *NovaSuite) TestAddSecurityGroupRuleWithInvalidParentFails(c *gc.C) {
   866  	invalidGroup := nova.SecurityGroup{Id: "1"}
   867  	s.ensureNoGroup(c, invalidGroup)
   868  	ri := nova.RuleInfo{ParentGroupId: invalidGroup.Id}
   869  	rule := nova.SecurityGroupRule{Id: "10"}
   870  	s.ensureNoRule(c, rule)
   871  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   872  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such security group 1")
   873  }
   874  
   875  func (s *NovaSuite) TestAddGroupSecurityGroupRuleWithInvalidSourceFails(c *gc.C) {
   876  	if s.service.useNeutronNetworking {
   877  		c.Skip("skipped in novaservice when using Neutron Model")
   878  	}
   879  	group := nova.SecurityGroup{Id: "1"}
   880  	s.createGroup(c, group)
   881  	defer s.deleteGroup(c, group)
   882  	invalidGroupId := "42"
   883  	ri := nova.RuleInfo{
   884  		ParentGroupId: group.Id,
   885  		GroupId:       &invalidGroupId,
   886  	}
   887  	rule := nova.SecurityGroupRule{Id: "10"}
   888  	s.ensureNoRule(c, rule)
   889  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   890  	c.Assert(err, gc.ErrorMatches, "conflictingRequest: Unknown source security group 42")
   891  }
   892  
   893  func (s *NovaSuite) TestAddSecurityGroupRuleUpdatesParent(c *gc.C) {
   894  	if s.service.useNeutronNetworking {
   895  		c.Skip("skipped in novaservice when using Neutron Model")
   896  	}
   897  	group := nova.SecurityGroup{
   898  		Id:       "1",
   899  		Name:     "test",
   900  		TenantId: s.service.TenantId,
   901  	}
   902  	s.createGroup(c, group)
   903  	defer s.deleteGroup(c, group)
   904  	ri := nova.RuleInfo{ParentGroupId: group.Id, GroupId: &group.Id}
   905  	rule := nova.SecurityGroupRule{
   906  		Id:            "10",
   907  		ParentGroupId: group.Id,
   908  		Group:         nova.SecurityGroupRef{TenantId: s.service.TenantId, Name: "test"},
   909  	}
   910  	s.ensureNoRule(c, rule)
   911  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   912  	c.Assert(err, gc.IsNil)
   913  	defer s.deleteRule(c, rule)
   914  	group.Rules = []nova.SecurityGroupRule{rule}
   915  	gr, err := s.service.securityGroup(group.Id)
   916  	c.Assert(err, gc.IsNil)
   917  	c.Assert(*gr, gc.DeepEquals, group)
   918  }
   919  
   920  func (s *NovaSuite) TestAddSecurityGroupRuleKeepsNegativePort(c *gc.C) {
   921  	if s.service.useNeutronNetworking {
   922  		c.Skip("skipped in novaservice when using Neutron Model")
   923  	}
   924  	group := nova.SecurityGroup{
   925  		Id:       "1",
   926  		Name:     "test",
   927  		TenantId: s.service.TenantId,
   928  	}
   929  	s.createGroup(c, group)
   930  	defer s.deleteGroup(c, group)
   931  	ri := nova.RuleInfo{
   932  		IPProtocol:    "icmp",
   933  		FromPort:      -1,
   934  		ToPort:        -1,
   935  		Cidr:          "0.0.0.0/0",
   936  		ParentGroupId: group.Id,
   937  	}
   938  	rule := nova.SecurityGroupRule{
   939  		Id:            "10",
   940  		ParentGroupId: group.Id,
   941  		FromPort:      &ri.FromPort,
   942  		ToPort:        &ri.ToPort,
   943  		IPProtocol:    &ri.IPProtocol,
   944  		IPRange:       map[string]string{"cidr": "0.0.0.0/0"},
   945  	}
   946  	s.ensureNoRule(c, rule)
   947  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   948  	c.Assert(err, gc.IsNil)
   949  	defer s.deleteRule(c, rule)
   950  	returnedGroup, err := s.service.securityGroup(group.Id)
   951  	c.Assert(err, gc.IsNil)
   952  	c.Assert(returnedGroup.Rules, gc.DeepEquals, []nova.SecurityGroupRule{rule})
   953  }
   954  
   955  func (s *NovaSuite) TestRemoveSecurityGroupRuleTwiceFails(c *gc.C) {
   956  	if s.service.useNeutronNetworking {
   957  		c.Skip("skipped in novaservice when using Neutron Model")
   958  	}
   959  	group := nova.SecurityGroup{Id: "1"}
   960  	s.createGroup(c, group)
   961  	defer s.deleteGroup(c, group)
   962  	ri := nova.RuleInfo{ParentGroupId: group.Id, GroupId: &group.Id}
   963  	rule := nova.SecurityGroupRule{Id: "10"}
   964  	s.ensureNoRule(c, rule)
   965  	err := s.service.addSecurityGroupRule(rule.Id, ri)
   966  	c.Assert(err, gc.IsNil)
   967  	s.deleteRule(c, rule)
   968  	err = s.service.removeSecurityGroupRule(rule.Id)
   969  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such security group rule 10")
   970  }
   971  
   972  func (s *NovaSuite) TestAddHasRemoveServerSecurityGroup(c *gc.C) {
   973  	server := nova.ServerDetail{Id: "sr1"}
   974  	group := nova.SecurityGroup{Id: "1"}
   975  	s.ensureNoServer(c, server)
   976  	s.ensureNoGroup(c, group)
   977  	ok := s.service.hasServerSecurityGroup(server.Id, group.Id)
   978  	c.Assert(ok, gc.Equals, false)
   979  	s.createServer(c, server)
   980  	defer s.deleteServer(c, server)
   981  	ok = s.service.hasServerSecurityGroup(server.Id, group.Id)
   982  	c.Assert(ok, gc.Equals, false)
   983  	s.createGroup(c, group)
   984  	defer s.deleteGroup(c, group)
   985  	ok = s.service.hasServerSecurityGroup(server.Id, group.Id)
   986  	c.Assert(ok, gc.Equals, false)
   987  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
   988  	c.Assert(err, gc.IsNil)
   989  	ok = s.service.hasServerSecurityGroup(server.Id, group.Id)
   990  	c.Assert(ok, gc.Equals, true)
   991  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
   992  	c.Assert(err, gc.IsNil)
   993  	ok = s.service.hasServerSecurityGroup(server.Id, group.Id)
   994  	c.Assert(ok, gc.Equals, false)
   995  }
   996  
   997  func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidServerFails(c *gc.C) {
   998  	server := nova.ServerDetail{Id: "sr1"}
   999  	group := nova.SecurityGroup{Id: "1"}
  1000  	s.ensureNoServer(c, server)
  1001  	s.createGroup(c, group)
  1002  	defer s.deleteGroup(c, group)
  1003  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1004  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server "sr1"`)
  1005  }
  1006  
  1007  func (s *NovaSuite) TestAddServerSecurityGroupWithInvalidGroupFails(c *gc.C) {
  1008  	group := nova.SecurityGroup{Id: "1"}
  1009  	server := nova.ServerDetail{Id: "sr1"}
  1010  	s.ensureNoGroup(c, group)
  1011  	s.createServer(c, server)
  1012  	defer s.deleteServer(c, server)
  1013  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1014  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such security group 1")
  1015  }
  1016  
  1017  func (s *NovaSuite) TestAddServerSecurityGroupTwiceFails(c *gc.C) {
  1018  	server := nova.ServerDetail{Id: "sr1"}
  1019  	group := nova.SecurityGroup{Id: "1"}
  1020  	s.createServer(c, server)
  1021  	defer s.deleteServer(c, server)
  1022  	s.createGroup(c, group)
  1023  	defer s.deleteGroup(c, group)
  1024  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1025  	c.Assert(err, gc.IsNil)
  1026  	err = s.service.addServerSecurityGroup(server.Id, group.Id)
  1027  	c.Assert(err, gc.ErrorMatches, `conflictingRequest: Server "sr1" already belongs to group 1`)
  1028  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1029  	c.Assert(err, gc.IsNil)
  1030  }
  1031  
  1032  func (s *NovaSuite) TestAllServerSecurityGroups(c *gc.C) {
  1033  	server := nova.ServerDetail{Id: "sr1"}
  1034  	srvGroups := s.service.allServerSecurityGroups(server.Id)
  1035  	c.Assert(srvGroups, gc.HasLen, 0)
  1036  	s.createServer(c, server)
  1037  	defer s.deleteServer(c, server)
  1038  	groups := []nova.SecurityGroup{
  1039  		{
  1040  			Id:       "1",
  1041  			Name:     "gr1",
  1042  			TenantId: s.service.TenantId,
  1043  			Rules:    []nova.SecurityGroupRule{},
  1044  		},
  1045  		{
  1046  			Id:       "2",
  1047  			Name:     "gr2",
  1048  			TenantId: s.service.TenantId,
  1049  			Rules:    []nova.SecurityGroupRule{},
  1050  		},
  1051  	}
  1052  	for _, group := range groups {
  1053  		s.createGroup(c, group)
  1054  		defer s.deleteGroup(c, group)
  1055  		err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1056  		defer s.service.removeServerSecurityGroup(server.Id, group.Id)
  1057  		c.Assert(err, gc.IsNil)
  1058  	}
  1059  	srvGroups = s.service.allServerSecurityGroups(server.Id)
  1060  	c.Assert(srvGroups, gc.HasLen, len(groups))
  1061  	if srvGroups[0].Id != groups[0].Id {
  1062  		srvGroups[0], srvGroups[1] = srvGroups[1], srvGroups[0]
  1063  	}
  1064  	// nova networking doesn't know about neutron egress direction rules,
  1065  	// created by default with a new security group
  1066  	if s.service.useNeutronNetworking {
  1067  		srvGroups[0].Rules = []nova.SecurityGroupRule{}
  1068  		srvGroups[1].Rules = []nova.SecurityGroupRule{}
  1069  	}
  1070  	c.Assert(srvGroups, gc.DeepEquals, groups)
  1071  }
  1072  
  1073  func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidServerFails(c *gc.C) {
  1074  	server := nova.ServerDetail{Id: "sr1"}
  1075  	group := nova.SecurityGroup{Id: "1"}
  1076  	s.createServer(c, server)
  1077  	s.createGroup(c, group)
  1078  	defer s.deleteGroup(c, group)
  1079  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1080  	c.Assert(err, gc.IsNil)
  1081  	s.deleteServer(c, server)
  1082  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1083  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server "sr1"`)
  1084  	s.createServer(c, server)
  1085  	defer s.deleteServer(c, server)
  1086  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1087  	c.Assert(err, gc.IsNil)
  1088  }
  1089  
  1090  func (s *NovaSuite) TestRemoveServerSecurityGroupWithInvalidGroupFails(c *gc.C) {
  1091  	group := nova.SecurityGroup{Id: "1"}
  1092  	server := nova.ServerDetail{Id: "sr1"}
  1093  	s.createGroup(c, group)
  1094  	s.createServer(c, server)
  1095  	defer s.deleteServer(c, server)
  1096  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1097  	c.Assert(err, gc.IsNil)
  1098  	s.deleteGroup(c, group)
  1099  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1100  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such security group 1")
  1101  	s.createGroup(c, group)
  1102  	defer s.deleteGroup(c, group)
  1103  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1104  	c.Assert(err, gc.IsNil)
  1105  }
  1106  
  1107  func (s *NovaSuite) TestRemoveServerSecurityGroupTwiceFails(c *gc.C) {
  1108  	server := nova.ServerDetail{Id: "sr1"}
  1109  	group := nova.SecurityGroup{Id: "1"}
  1110  	s.createServer(c, server)
  1111  	defer s.deleteServer(c, server)
  1112  	s.createGroup(c, group)
  1113  	defer s.deleteGroup(c, group)
  1114  	err := s.service.addServerSecurityGroup(server.Id, group.Id)
  1115  	c.Assert(err, gc.IsNil)
  1116  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1117  	c.Assert(err, gc.IsNil)
  1118  	err = s.service.removeServerSecurityGroup(server.Id, group.Id)
  1119  	c.Assert(err, gc.ErrorMatches, `badRequest: Server "sr1" does not belong to group 1`)
  1120  }
  1121  
  1122  func (s *NovaSuite) TestAddHasRemoveFloatingIP(c *gc.C) {
  1123  	if s.service.useNeutronNetworking {
  1124  		c.Skip("skipped in novaservice when using Neutron Model")
  1125  	}
  1126  	ip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1127  	s.ensureNoIP(c, ip)
  1128  	ok := s.service.hasFloatingIP(ip.IP)
  1129  	c.Assert(ok, gc.Equals, false)
  1130  	s.createIP(c, ip)
  1131  	ok = s.service.hasFloatingIP("invalid IP")
  1132  	c.Assert(ok, gc.Equals, false)
  1133  	ok = s.service.hasFloatingIP(ip.IP)
  1134  	c.Assert(ok, gc.Equals, true)
  1135  	s.deleteIP(c, ip)
  1136  	ok = s.service.hasFloatingIP(ip.IP)
  1137  	c.Assert(ok, gc.Equals, false)
  1138  }
  1139  
  1140  func (s *NovaSuite) TestAddFloatingIPTwiceFails(c *gc.C) {
  1141  	if s.service.useNeutronNetworking {
  1142  		c.Skip("skipped in novaservice when using Neutron Model")
  1143  	}
  1144  	ip := nova.FloatingIP{Id: "1"}
  1145  	s.createIP(c, ip)
  1146  	defer s.deleteIP(c, ip)
  1147  	err := s.service.addFloatingIP(ip)
  1148  	c.Assert(err, gc.ErrorMatches, "conflictingRequest: A floating IP with id 1 already exists")
  1149  }
  1150  
  1151  func (s *NovaSuite) TestRemoveFloatingIPTwiceFails(c *gc.C) {
  1152  	if s.service.useNeutronNetworking {
  1153  		c.Skip("skipped in novaservice when using Neutron Model")
  1154  	}
  1155  	ip := nova.FloatingIP{Id: "1"}
  1156  	s.createIP(c, ip)
  1157  	s.deleteIP(c, ip)
  1158  	err := s.service.removeFloatingIP(ip.Id)
  1159  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such floating IP \"1\"")
  1160  }
  1161  
  1162  func (s *NovaSuite) TestAllFloatingIPs(c *gc.C) {
  1163  	if s.service.useNeutronNetworking {
  1164  		c.Skip("skipped in novaservice when using Neutron Model")
  1165  	}
  1166  	fips := s.service.allFloatingIPs()
  1167  	c.Assert(fips, gc.HasLen, 0)
  1168  	fips = []nova.FloatingIP{
  1169  		{Id: "1"},
  1170  		{Id: "2"},
  1171  	}
  1172  	s.createIP(c, fips[0])
  1173  	defer s.deleteIP(c, fips[0])
  1174  	s.createIP(c, fips[1])
  1175  	defer s.deleteIP(c, fips[1])
  1176  	ips := s.service.allFloatingIPs()
  1177  	c.Assert(ips, gc.HasLen, len(fips))
  1178  	if ips[0].Id != fips[0].Id {
  1179  		ips[0], ips[1] = ips[1], ips[0]
  1180  	}
  1181  	c.Assert(ips, gc.DeepEquals, fips)
  1182  }
  1183  
  1184  func (s *NovaSuite) TestGetFloatingIP(c *gc.C) {
  1185  	if s.service.useNeutronNetworking {
  1186  		c.Skip("skipped in novaservice when using Neutron Model")
  1187  	}
  1188  	inst := "sr1"
  1189  	fixedIP := "4.3.2.1"
  1190  	fip := nova.FloatingIP{
  1191  		Id:         "1",
  1192  		IP:         "1.2.3.4",
  1193  		Pool:       "pool",
  1194  		InstanceId: &inst,
  1195  		FixedIP:    &fixedIP,
  1196  	}
  1197  	s.createIP(c, fip)
  1198  	defer s.deleteIP(c, fip)
  1199  	ip, _ := s.service.floatingIP(fip.Id)
  1200  	c.Assert(*ip, gc.DeepEquals, fip)
  1201  }
  1202  
  1203  func (s *NovaSuite) TestGetFloatingIPByAddr(c *gc.C) {
  1204  	if s.service.useNeutronNetworking {
  1205  		c.Skip("skipped in novaservice when using Neutron Model")
  1206  	}
  1207  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1208  	s.ensureNoIP(c, fip)
  1209  	ip, err := s.service.floatingIPByAddr(fip.IP)
  1210  	c.Assert(err, gc.NotNil)
  1211  	s.createIP(c, fip)
  1212  	defer s.deleteIP(c, fip)
  1213  	ip, err = s.service.floatingIPByAddr(fip.IP)
  1214  	c.Assert(err, gc.IsNil)
  1215  	c.Assert(*ip, gc.DeepEquals, fip)
  1216  	_, err = s.service.floatingIPByAddr("invalid")
  1217  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such floating IP "invalid"`)
  1218  }
  1219  
  1220  func (s *NovaSuite) TestAddHasRemoveServerFloatingIP(c *gc.C) {
  1221  	server := nova.ServerDetail{
  1222  		Id:        "sr1",
  1223  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1224  	}
  1225  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1226  	s.ensureNoServer(c, server)
  1227  	s.ensureNoIP(c, fip)
  1228  	ok := s.service.hasServerFloatingIP(server.Id, fip.IP)
  1229  	c.Assert(ok, gc.Equals, false)
  1230  	s.createServer(c, server)
  1231  	defer s.deleteServer(c, server)
  1232  	ok = s.service.hasServerFloatingIP(server.Id, fip.IP)
  1233  	c.Assert(ok, gc.Equals, false)
  1234  	s.createIP(c, fip)
  1235  	defer s.deleteIP(c, fip)
  1236  	ok = s.service.hasServerFloatingIP(server.Id, fip.IP)
  1237  	c.Assert(ok, gc.Equals, false)
  1238  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1239  	c.Assert(err, gc.IsNil)
  1240  	ok = s.service.hasServerFloatingIP(server.Id, fip.IP)
  1241  	c.Assert(ok, gc.Equals, true)
  1242  
  1243  	// Is the fip now listed with the server addresses?
  1244  	serverCopy, err := s.service.server(server.Id)
  1245  	c.Assert(err, gc.IsNil)
  1246  	var found bool
  1247  	for _, address := range serverCopy.Addresses["private"] {
  1248  		if address.Address == fip.IP {
  1249  			found = true
  1250  		}
  1251  	}
  1252  	if !found {
  1253  		c.Errorf("expected to find added fip in server addresses")
  1254  	}
  1255  
  1256  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1257  	c.Assert(err, gc.IsNil)
  1258  
  1259  	// Has the fip been removed from the listed server addresses?
  1260  	serverCopy, err = s.service.server(server.Id)
  1261  	c.Assert(err, gc.IsNil)
  1262  	found = false
  1263  	for _, address := range serverCopy.Addresses["private"] {
  1264  		if address.Address == fip.IP {
  1265  			found = true
  1266  		}
  1267  	}
  1268  	if found {
  1269  		c.Errorf("didn't expected to find removed fip in server addresses")
  1270  	}
  1271  
  1272  	ok = s.service.hasServerFloatingIP(server.Id, fip.IP)
  1273  	c.Assert(ok, gc.Equals, false)
  1274  }
  1275  
  1276  func (s *NovaSuite) TestAddServerFloatingIPWithInvalidServerFails(c *gc.C) {
  1277  	server := nova.ServerDetail{Id: "sr1"}
  1278  	fip := nova.FloatingIP{Id: "1"}
  1279  	s.ensureNoServer(c, server)
  1280  	s.createIP(c, fip)
  1281  	defer s.deleteIP(c, fip)
  1282  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1283  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server "sr1"`)
  1284  }
  1285  
  1286  func (s *NovaSuite) TestAddServerFloatingIPWithInvalidIPFails(c *gc.C) {
  1287  	fip := nova.FloatingIP{Id: "1"}
  1288  	server := nova.ServerDetail{Id: "sr1"}
  1289  	s.ensureNoIP(c, fip)
  1290  	s.createServer(c, server)
  1291  	defer s.deleteServer(c, server)
  1292  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1293  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such floating IP \"1\"")
  1294  }
  1295  
  1296  func (s *NovaSuite) TestAddServerFloatingIPTwiceFails(c *gc.C) {
  1297  	server := nova.ServerDetail{
  1298  		Id:        "sr1",
  1299  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1300  	}
  1301  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1302  	s.createServer(c, server)
  1303  	defer s.deleteServer(c, server)
  1304  	s.createIP(c, fip)
  1305  	defer s.deleteIP(c, fip)
  1306  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1307  	c.Assert(err, gc.IsNil)
  1308  	err = s.service.addServerFloatingIP(server.Id, fip.Id)
  1309  	c.Assert(err, gc.ErrorMatches, `conflictingRequest: Server "sr1" already has floating IP 1`)
  1310  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1311  	c.Assert(err, gc.IsNil)
  1312  }
  1313  
  1314  func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidServerFails(c *gc.C) {
  1315  	server := nova.ServerDetail{
  1316  		Id:        "sr1",
  1317  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1318  	}
  1319  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1320  	s.createServer(c, server)
  1321  	s.createIP(c, fip)
  1322  	defer s.deleteIP(c, fip)
  1323  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1324  	c.Assert(err, gc.IsNil)
  1325  	s.deleteServer(c, server)
  1326  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1327  	c.Assert(err, gc.ErrorMatches, `itemNotFound: No such server "sr1"`)
  1328  	s.createServer(c, server)
  1329  	defer s.deleteServer(c, server)
  1330  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1331  	c.Assert(err, gc.IsNil)
  1332  }
  1333  
  1334  func (s *NovaSuite) TestRemoveServerFloatingIPWithInvalidIPFails(c *gc.C) {
  1335  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1336  	server := nova.ServerDetail{
  1337  		Id:        "sr1",
  1338  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1339  	}
  1340  	s.createIP(c, fip)
  1341  	s.createServer(c, server)
  1342  	defer s.deleteServer(c, server)
  1343  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1344  	c.Assert(err, gc.IsNil)
  1345  	s.deleteIP(c, fip)
  1346  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1347  	c.Assert(err, gc.ErrorMatches, "itemNotFound: No such floating IP \"1\"")
  1348  	s.createIP(c, fip)
  1349  	defer s.deleteIP(c, fip)
  1350  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1351  	c.Assert(err, gc.IsNil)
  1352  }
  1353  
  1354  func (s *NovaSuite) TestRemoveServerFloatingIPTwiceFails(c *gc.C) {
  1355  	fip := nova.FloatingIP{Id: "1", IP: "1.2.3.4"}
  1356  	server := nova.ServerDetail{
  1357  		Id:        "sr1",
  1358  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1359  	}
  1360  	s.createServer(c, server)
  1361  	defer s.deleteServer(c, server)
  1362  	s.createIP(c, fip)
  1363  	defer s.deleteIP(c, fip)
  1364  	err := s.service.addServerFloatingIP(server.Id, fip.Id)
  1365  	c.Assert(err, gc.IsNil)
  1366  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1367  	c.Assert(err, gc.IsNil)
  1368  	err = s.service.removeServerFloatingIP(server.Id, fip.Id)
  1369  	c.Assert(err, gc.ErrorMatches, `itemNotFound: Server "sr1" does not have floating IP 1`)
  1370  }
  1371  
  1372  func (s *NovaSuite) TestAllOSInterfaces(c *gc.C) {
  1373  	if s.service.useNeutronNetworking {
  1374  		c.Skip("skipped in novaservice when using Neutron Model")
  1375  	}
  1376  
  1377  	serverID := "sr1"
  1378  	server := nova.ServerDetail{
  1379  		Id:        serverID,
  1380  		Addresses: map[string][]nova.IPAddress{"private": []nova.IPAddress{}},
  1381  	}
  1382  	s.createServer(c, server)
  1383  	defer s.deleteServer(c, server)
  1384  
  1385  	interfaces := s.service.serverOSInterfaces(serverID)
  1386  	// There shouldn't be any interfaces associated with a server.
  1387  	c.Assert(interfaces, gc.HasLen, 0)
  1388  	interfaces = []nova.OSInterface{
  1389  		{
  1390  			FixedIPs: []nova.PortFixedIP{
  1391  				{
  1392  					IPAddress: "10.0.0.1",
  1393  					SubnetID:  "aaa-bbb-ccc",
  1394  				},
  1395  			},
  1396  			IPAddress: "10.0.0.1",
  1397  		},
  1398  		{
  1399  			FixedIPs: []nova.PortFixedIP{
  1400  				{
  1401  					IPAddress: "10.0.0.2",
  1402  					SubnetID:  "xxx-yyy-zzz",
  1403  				},
  1404  			},
  1405  			IPAddress: "10.0.0.2",
  1406  		},
  1407  	}
  1408  	s.createOSInterface(c, serverID, interfaces[0])
  1409  	defer s.deleteOSInterface(c, serverID, interfaces[0])
  1410  	s.createOSInterface(c, serverID, interfaces[1])
  1411  	defer s.deleteOSInterface(c, serverID, interfaces[1])
  1412  
  1413  	newInterfaces := s.service.serverOSInterfaces(serverID)
  1414  	c.Assert(newInterfaces, gc.HasLen, len(interfaces))
  1415  }