github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/openstack/provider_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package openstack_test
     5  
     6  import (
     7  	jc "github.com/juju/testing/checkers"
     8  	gc "gopkg.in/check.v1"
     9  	"gopkg.in/goose.v1/nova"
    10  
    11  	"github.com/juju/juju/environs/config"
    12  	"github.com/juju/juju/network"
    13  	"github.com/juju/juju/provider/openstack"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  // localTests contains tests which do not require a live service or test double to run.
    18  type localTests struct{}
    19  
    20  var _ = gc.Suite(&localTests{})
    21  
    22  // ported from lp:juju/juju/providers/openstack/tests/test_machine.py
    23  var addressTests = []struct {
    24  	summary    string
    25  	floatingIP string
    26  	private    []nova.IPAddress
    27  	public     []nova.IPAddress
    28  	networks   []string
    29  	expected   string
    30  	failure    error
    31  }{{
    32  	summary:  "missing",
    33  	expected: "",
    34  }, {
    35  	summary:  "empty",
    36  	private:  []nova.IPAddress{},
    37  	networks: []string{"private"},
    38  	expected: "",
    39  }, {
    40  	summary:  "private IPv4 only",
    41  	private:  []nova.IPAddress{{4, "192.168.0.1"}},
    42  	networks: []string{"private"},
    43  	expected: "192.168.0.1",
    44  }, {
    45  	summary:  "private IPv6 only",
    46  	private:  []nova.IPAddress{{6, "fc00::1"}},
    47  	networks: []string{"private"},
    48  	expected: "fc00::1",
    49  }, {
    50  	summary:  "private only, both IPv4 and IPv6",
    51  	private:  []nova.IPAddress{{4, "192.168.0.1"}, {6, "fc00::1"}},
    52  	networks: []string{"private"},
    53  	expected: "192.168.0.1",
    54  }, {
    55  	summary:  "private only, both IPv6 and IPv4",
    56  	private:  []nova.IPAddress{{6, "fc00::1"}, {4, "192.168.0.1"}},
    57  	networks: []string{"private"},
    58  	expected: "fc00::1",
    59  }, {
    60  	summary:  "private IPv4 plus (HP cloud)",
    61  	private:  []nova.IPAddress{{4, "10.0.0.1"}, {4, "8.8.4.4"}},
    62  	networks: []string{"private"},
    63  	expected: "8.8.4.4",
    64  }, {
    65  	summary:  "public IPv4 only",
    66  	public:   []nova.IPAddress{{4, "8.8.8.8"}},
    67  	networks: []string{"", "public"},
    68  	expected: "8.8.8.8",
    69  }, {
    70  	summary:  "public IPv6 only",
    71  	public:   []nova.IPAddress{{6, "2001:db8::1"}},
    72  	networks: []string{"", "public"},
    73  	expected: "2001:db8::1",
    74  }, {
    75  	summary:  "public only, both IPv4 and IPv6",
    76  	public:   []nova.IPAddress{{4, "8.8.8.8"}, {6, "2001:db8::1"}},
    77  	networks: []string{"", "public"},
    78  	expected: "8.8.8.8",
    79  }, {
    80  	summary:  "public only, both IPv6 and IPv4",
    81  	public:   []nova.IPAddress{{6, "2001:db8::1"}, {4, "8.8.8.8"}},
    82  	networks: []string{"", "public"},
    83  	expected: "2001:db8::1",
    84  }, {
    85  	summary:  "public and private both IPv4",
    86  	private:  []nova.IPAddress{{4, "10.0.0.4"}},
    87  	public:   []nova.IPAddress{{4, "8.8.4.4"}},
    88  	networks: []string{"private", "public"},
    89  	expected: "8.8.4.4",
    90  }, {
    91  	summary:  "public and private both IPv6",
    92  	private:  []nova.IPAddress{{6, "fc00::1"}},
    93  	public:   []nova.IPAddress{{6, "2001:db8::1"}},
    94  	networks: []string{"private", "public"},
    95  	expected: "2001:db8::1",
    96  }, {
    97  	summary:  "public, private, and localhost IPv4",
    98  	private:  []nova.IPAddress{{4, "127.0.0.4"}, {4, "192.168.0.1"}},
    99  	public:   []nova.IPAddress{{4, "8.8.8.8"}},
   100  	networks: []string{"private", "public"},
   101  	expected: "8.8.8.8",
   102  }, {
   103  	summary:  "public, private, and localhost IPv6",
   104  	private:  []nova.IPAddress{{6, "::1"}, {6, "fc00::1"}},
   105  	public:   []nova.IPAddress{{6, "2001:db8::1"}},
   106  	networks: []string{"private", "public"},
   107  	expected: "2001:db8::1",
   108  }, {
   109  	summary:  "public, private, and localhost - both IPv4 and IPv6",
   110  	private:  []nova.IPAddress{{4, "127.0.0.4"}, {4, "192.168.0.1"}, {6, "::1"}, {6, "fc00::1"}},
   111  	public:   []nova.IPAddress{{4, "8.8.8.8"}, {6, "2001:db8::1"}},
   112  	networks: []string{"private", "public"},
   113  	expected: "8.8.8.8",
   114  }, {
   115  	summary:  "public, private, and localhost - both IPv6 and IPv4",
   116  	private:  []nova.IPAddress{{6, "::1"}, {6, "fc00::1"}, {4, "127.0.0.4"}, {4, "192.168.0.1"}},
   117  	public:   []nova.IPAddress{{6, "2001:db8::1"}, {4, "8.8.8.8"}},
   118  	networks: []string{"private", "public"},
   119  	expected: "2001:db8::1",
   120  }, {
   121  	summary:  "custom only IPv4",
   122  	private:  []nova.IPAddress{{4, "192.168.0.1"}},
   123  	networks: []string{"special"},
   124  	expected: "192.168.0.1",
   125  }, {
   126  	summary:  "custom only IPv6",
   127  	private:  []nova.IPAddress{{6, "fc00::1"}},
   128  	networks: []string{"special"},
   129  	expected: "fc00::1",
   130  }, {
   131  	summary:  "custom only - both IPv4 and IPv6",
   132  	private:  []nova.IPAddress{{4, "192.168.0.1"}, {6, "fc00::1"}},
   133  	networks: []string{"special"},
   134  	expected: "192.168.0.1",
   135  }, {
   136  	summary:  "custom only - both IPv6 and IPv4",
   137  	private:  []nova.IPAddress{{6, "fc00::1"}, {4, "192.168.0.1"}},
   138  	networks: []string{"special"},
   139  	expected: "fc00::1",
   140  }, {
   141  	summary:  "custom and public IPv4",
   142  	private:  []nova.IPAddress{{4, "172.16.0.1"}},
   143  	public:   []nova.IPAddress{{4, "8.8.8.8"}},
   144  	networks: []string{"special", "public"},
   145  	expected: "8.8.8.8",
   146  }, {
   147  	summary:  "custom and public IPv6",
   148  	private:  []nova.IPAddress{{6, "fc00::1"}},
   149  	public:   []nova.IPAddress{{6, "2001:db8::1"}},
   150  	networks: []string{"special", "public"},
   151  	expected: "2001:db8::1",
   152  }, {
   153  	summary:  "custom and public - both IPv4 and IPv6",
   154  	private:  []nova.IPAddress{{4, "172.16.0.1"}, {6, "fc00::1"}},
   155  	public:   []nova.IPAddress{{4, "8.8.8.8"}, {6, "2001:db8::1"}},
   156  	networks: []string{"special", "public"},
   157  	expected: "8.8.8.8",
   158  }, {
   159  	summary:  "custom and public - both IPv6 and IPv4",
   160  	private:  []nova.IPAddress{{6, "fc00::1"}, {4, "172.16.0.1"}},
   161  	public:   []nova.IPAddress{{6, "2001:db8::1"}, {4, "8.8.8.8"}},
   162  	networks: []string{"special", "public"},
   163  	expected: "2001:db8::1",
   164  }, {
   165  	summary:    "floating and public, same address",
   166  	floatingIP: "8.8.8.8",
   167  	public:     []nova.IPAddress{{4, "8.8.8.8"}},
   168  	networks:   []string{"", "public"},
   169  	expected:   "8.8.8.8",
   170  }, {
   171  	summary:    "floating and public, different address",
   172  	floatingIP: "8.8.4.4",
   173  	public:     []nova.IPAddress{{4, "8.8.8.8"}},
   174  	networks:   []string{"", "public"},
   175  	expected:   "8.8.4.4",
   176  }, {
   177  	summary:    "floating and private",
   178  	floatingIP: "8.8.4.4",
   179  	private:    []nova.IPAddress{{4, "10.0.0.1"}},
   180  	networks:   []string{"private"},
   181  	expected:   "8.8.4.4",
   182  }, {
   183  	summary:    "floating, custom and public",
   184  	floatingIP: "8.8.4.4",
   185  	private:    []nova.IPAddress{{4, "172.16.0.1"}},
   186  	public:     []nova.IPAddress{{4, "8.8.8.8"}},
   187  	networks:   []string{"special", "public"},
   188  	expected:   "8.8.4.4",
   189  }}
   190  
   191  func (t *localTests) TestGetServerAddresses(c *gc.C) {
   192  	for i, t := range addressTests {
   193  		c.Logf("#%d. %s -> %s (%v)", i, t.summary, t.expected, t.failure)
   194  		addresses := make(map[string][]nova.IPAddress)
   195  		if t.private != nil {
   196  			if len(t.networks) < 1 {
   197  				addresses["private"] = t.private
   198  			} else {
   199  				addresses[t.networks[0]] = t.private
   200  			}
   201  		}
   202  		if t.public != nil {
   203  			if len(t.networks) < 2 {
   204  				addresses["public"] = t.public
   205  			} else {
   206  				addresses[t.networks[1]] = t.public
   207  			}
   208  		}
   209  		addr := openstack.InstanceAddress(t.floatingIP, addresses)
   210  		c.Assert(addr, gc.Equals, t.expected)
   211  	}
   212  }
   213  
   214  func (*localTests) TestPortsToRuleInfo(c *gc.C) {
   215  	groupId := "groupid"
   216  	testCases := []struct {
   217  		about    string
   218  		ports    []network.PortRange
   219  		expected []nova.RuleInfo
   220  	}{{
   221  		about: "single port",
   222  		ports: []network.PortRange{{
   223  			FromPort: 80,
   224  			ToPort:   80,
   225  			Protocol: "tcp",
   226  		}},
   227  		expected: []nova.RuleInfo{{
   228  			IPProtocol:    "tcp",
   229  			FromPort:      80,
   230  			ToPort:        80,
   231  			Cidr:          "0.0.0.0/0",
   232  			ParentGroupId: groupId,
   233  		}},
   234  	}, {
   235  		about: "multiple ports",
   236  		ports: []network.PortRange{{
   237  			FromPort: 80,
   238  			ToPort:   82,
   239  			Protocol: "tcp",
   240  		}},
   241  		expected: []nova.RuleInfo{{
   242  			IPProtocol:    "tcp",
   243  			FromPort:      80,
   244  			ToPort:        82,
   245  			Cidr:          "0.0.0.0/0",
   246  			ParentGroupId: groupId,
   247  		}},
   248  	}, {
   249  		about: "multiple port ranges",
   250  		ports: []network.PortRange{{
   251  			FromPort: 80,
   252  			ToPort:   82,
   253  			Protocol: "tcp",
   254  		}, {
   255  			FromPort: 100,
   256  			ToPort:   120,
   257  			Protocol: "tcp",
   258  		}},
   259  		expected: []nova.RuleInfo{{
   260  			IPProtocol:    "tcp",
   261  			FromPort:      80,
   262  			ToPort:        82,
   263  			Cidr:          "0.0.0.0/0",
   264  			ParentGroupId: groupId,
   265  		}, {
   266  			IPProtocol:    "tcp",
   267  			FromPort:      100,
   268  			ToPort:        120,
   269  			Cidr:          "0.0.0.0/0",
   270  			ParentGroupId: groupId,
   271  		}},
   272  	}}
   273  
   274  	for i, t := range testCases {
   275  		c.Logf("test %d: %s", i, t.about)
   276  		rules := openstack.PortsToRuleInfo(groupId, t.ports)
   277  		c.Check(len(rules), gc.Equals, len(t.expected))
   278  		c.Check(rules, gc.DeepEquals, t.expected)
   279  	}
   280  }
   281  
   282  func (*localTests) TestRuleMatchesPortRange(c *gc.C) {
   283  	proto_tcp := "tcp"
   284  	proto_udp := "udp"
   285  	port_80 := 80
   286  	port_85 := 85
   287  
   288  	testCases := []struct {
   289  		about    string
   290  		ports    network.PortRange
   291  		rule     nova.SecurityGroupRule
   292  		expected bool
   293  	}{{
   294  		about: "single port",
   295  		ports: network.PortRange{
   296  			FromPort: 80,
   297  			ToPort:   80,
   298  			Protocol: "tcp",
   299  		},
   300  		rule: nova.SecurityGroupRule{
   301  			IPProtocol: &proto_tcp,
   302  			FromPort:   &port_80,
   303  			ToPort:     &port_80,
   304  		},
   305  		expected: true,
   306  	}, {
   307  		about: "multiple port",
   308  		ports: network.PortRange{
   309  			FromPort: port_80,
   310  			ToPort:   port_85,
   311  			Protocol: proto_tcp,
   312  		},
   313  		rule: nova.SecurityGroupRule{
   314  			IPProtocol: &proto_tcp,
   315  			FromPort:   &port_80,
   316  			ToPort:     &port_85,
   317  		},
   318  		expected: true,
   319  	}, {
   320  		about: "nil rule components",
   321  		ports: network.PortRange{
   322  			FromPort: port_80,
   323  			ToPort:   port_85,
   324  			Protocol: proto_tcp,
   325  		},
   326  		rule: nova.SecurityGroupRule{
   327  			IPProtocol: nil,
   328  			FromPort:   nil,
   329  			ToPort:     nil,
   330  		},
   331  		expected: false,
   332  	}, {
   333  		about: "mismatched port range and rule",
   334  		ports: network.PortRange{
   335  			FromPort: port_80,
   336  			ToPort:   port_85,
   337  			Protocol: proto_tcp,
   338  		},
   339  		rule: nova.SecurityGroupRule{
   340  			IPProtocol: &proto_udp,
   341  			FromPort:   &port_80,
   342  			ToPort:     &port_80,
   343  		},
   344  		expected: false,
   345  	}}
   346  	for i, t := range testCases {
   347  		c.Logf("test %d: %s", i, t.about)
   348  		c.Check(openstack.RuleMatchesPortRange(t.rule, t.ports), gc.Equals, t.expected)
   349  	}
   350  }
   351  
   352  func (t *localTests) TestPrepareSetsControlBucket(c *gc.C) {
   353  	attrs := testing.FakeConfig().Merge(testing.Attrs{
   354  		"type": "openstack",
   355  	})
   356  	cfg, err := config.New(config.NoDefaults, attrs)
   357  	c.Assert(err, jc.ErrorIsNil)
   358  
   359  	cfg, err = openstack.ProviderInstance.PrepareForCreateEnvironment(cfg)
   360  	c.Assert(err, jc.ErrorIsNil)
   361  
   362  	bucket := cfg.UnknownAttrs()["control-bucket"]
   363  	c.Assert(bucket, gc.Matches, "[a-f0-9]{32}")
   364  }