mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
- Added more testcases for libnetwork API testing
- Added new error types for all of libnetwork errors Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
parent
ec7d417a37
commit
56c3adda07
3 changed files with 310 additions and 22 deletions
63
libnetwork/error.go
Normal file
63
libnetwork/error.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNilNetworkDriver is returned if a nil network driver
|
||||
// is passed to NewNetwork api.
|
||||
ErrNilNetworkDriver = errors.New("nil NetworkDriver instance")
|
||||
// ErrInvalidNetworkDriver is returned if an invalid driver
|
||||
// instance is passed.
|
||||
ErrInvalidNetworkDriver = errors.New("invalid driver bound to network")
|
||||
)
|
||||
|
||||
// NetworkTypeError type is returned when the network type string is not
|
||||
// known to libnetwork.
|
||||
type NetworkTypeError string
|
||||
|
||||
func (nt NetworkTypeError) Error() string {
|
||||
return fmt.Sprintf("unknown driver %q", string(nt))
|
||||
}
|
||||
|
||||
// NetworkNameError is returned when a network with the same name already exists.
|
||||
type NetworkNameError string
|
||||
|
||||
func (name NetworkNameError) Error() string {
|
||||
return fmt.Sprintf("network with name %s already exists", string(name))
|
||||
}
|
||||
|
||||
// UnknownNetworkError is returned when libnetwork could not find in it's database
|
||||
// a network with the same name and id.
|
||||
type UnknownNetworkError struct {
|
||||
name string
|
||||
id string
|
||||
}
|
||||
|
||||
func (une *UnknownNetworkError) Error() string {
|
||||
return fmt.Sprintf("unknown network %s id %s", une.name, une.id)
|
||||
}
|
||||
|
||||
// ActiveEndpointsError is returned when a network is deleted which has active
|
||||
// endpoints in it.
|
||||
type ActiveEndpointsError struct {
|
||||
name string
|
||||
id string
|
||||
}
|
||||
|
||||
func (aee *ActiveEndpointsError) Error() string {
|
||||
return fmt.Sprintf("network with name %s id %s has active endpoints", aee.name, aee.id)
|
||||
}
|
||||
|
||||
// UnknownEndpointError is returned when libnetwork could not find in it's database
|
||||
// an endpoint with the same name and id.
|
||||
type UnknownEndpointError struct {
|
||||
name string
|
||||
id string
|
||||
}
|
||||
|
||||
func (uee *UnknownEndpointError) Error() string {
|
||||
return fmt.Sprintf("unknown endpoint %s id %s", uee.name, uee.id)
|
||||
}
|
|
@ -8,15 +8,27 @@ import (
|
|||
"github.com/docker/libnetwork"
|
||||
_ "github.com/docker/libnetwork/drivers/bridge"
|
||||
"github.com/docker/libnetwork/pkg/options"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
var bridgeName = "dockertest0"
|
||||
|
||||
func TestSimplebridge(t *testing.T) {
|
||||
bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}
|
||||
netlink.LinkDel(bridge)
|
||||
func createTestNetwork(networkType, networkName string, option options.Generic) (libnetwork.Network, error) {
|
||||
controller := libnetwork.New()
|
||||
|
||||
driver, err := controller.NewNetworkDriver(networkType, option)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
network, err := controller.NewNetwork(driver, networkName, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return network, nil
|
||||
}
|
||||
|
||||
func TestSimplebridge(t *testing.T) {
|
||||
ip, subnet, err := net.ParseCIDR("192.168.100.1/24")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -36,7 +48,7 @@ func TestSimplebridge(t *testing.T) {
|
|||
cidrv6.IP = ip
|
||||
|
||||
log.Debug("Adding a simple bridge")
|
||||
options := options.Generic{
|
||||
option := options.Generic{
|
||||
"BridgeName": bridgeName,
|
||||
"AddressIPv4": subnet,
|
||||
"FixedCIDR": cidr,
|
||||
|
@ -48,14 +60,7 @@ func TestSimplebridge(t *testing.T) {
|
|||
"EnableIPForwarding": true,
|
||||
"AllowNonDefaultBridge": true}
|
||||
|
||||
controller := libnetwork.New()
|
||||
|
||||
driver, err := controller.NewNetworkDriver("simplebridge", options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
network, err := controller.NewNetwork(driver, "testnetwork", "")
|
||||
network, err := createTestNetwork("simplebridge", "testnetwork", option)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -73,3 +78,206 @@ func TestSimplebridge(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownDriver(t *testing.T) {
|
||||
_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if _, ok := err.(libnetwork.NetworkTypeError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilDriver(t *testing.T) {
|
||||
controller := libnetwork.New()
|
||||
|
||||
option := options.Generic{}
|
||||
_, err := controller.NewNetwork(nil, "dummy", option)
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if err != libnetwork.ErrNilNetworkDriver {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoInitDriver(t *testing.T) {
|
||||
controller := libnetwork.New()
|
||||
|
||||
option := options.Generic{}
|
||||
_, err := controller.NewNetwork(&libnetwork.NetworkDriver{}, "dummy", option)
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if err != libnetwork.ErrInvalidNetworkDriver {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuplicateNetwork(t *testing.T) {
|
||||
controller := libnetwork.New()
|
||||
|
||||
option := options.Generic{}
|
||||
driver, err := controller.NewNetworkDriver("simplebridge", option)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = controller.NewNetwork(driver, "testnetwork", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = controller.NewNetwork(driver, "testnetwork", "")
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if _, ok := err.(libnetwork.NetworkNameError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkName(t *testing.T) {
|
||||
networkName := "testnetwork"
|
||||
|
||||
n, err := createTestNetwork("simplebridge", networkName, options.Generic{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n.Name() != networkName {
|
||||
t.Fatalf("Expected network name %s, got %s", networkName, n.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkType(t *testing.T) {
|
||||
networkType := "simplebridge"
|
||||
|
||||
n, err := createTestNetwork(networkType, "testnetwork", options.Generic{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n.Type() != networkType {
|
||||
t.Fatalf("Expected network type %s, got %s", networkType, n.Type())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkID(t *testing.T) {
|
||||
networkType := "simplebridge"
|
||||
|
||||
n, err := createTestNetwork(networkType, "testnetwork", options.Generic{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n.ID() == "" {
|
||||
t.Fatal("Expected non-empty network id")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
|
||||
option := options.Generic{
|
||||
"BridgeName": bridgeName,
|
||||
"AllowNonDefaultBridge": true}
|
||||
|
||||
network, err := createTestNetwork("simplebridge", "testnetwork", option)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ep, _, err := network.CreateEndpoint("testep", "", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = network.Delete()
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if _, ok := err.(*libnetwork.ActiveEndpointsError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
|
||||
// Done testing. Now cleanup.
|
||||
if err := ep.Delete(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := network.Delete(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownNetwork(t *testing.T) {
|
||||
option := options.Generic{
|
||||
"BridgeName": bridgeName,
|
||||
"AllowNonDefaultBridge": true}
|
||||
|
||||
network, err := createTestNetwork("simplebridge", "testnetwork", option)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = network.Delete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = network.Delete()
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if _, ok := err.(*libnetwork.UnknownNetworkError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownEndpoint(t *testing.T) {
|
||||
ip, subnet, err := net.ParseCIDR("192.168.100.1/24")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
subnet.IP = ip
|
||||
|
||||
option := options.Generic{
|
||||
"BridgeName": bridgeName,
|
||||
"AddressIPv4": subnet,
|
||||
"AllowNonDefaultBridge": true}
|
||||
|
||||
network, err := createTestNetwork("simplebridge", "testnetwork", option)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ep, _, err := network.CreateEndpoint("testep", "", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = ep.Delete()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = ep.Delete()
|
||||
if err == nil {
|
||||
t.Fatal("Expected to fail. But instead succeeded")
|
||||
}
|
||||
|
||||
if _, ok := err.(*libnetwork.UnknownEndpointError); !ok {
|
||||
t.Fatalf("Did not fail with expected error. Actual error: %v", err)
|
||||
}
|
||||
|
||||
// Done testing. Now cleanup
|
||||
if err := network.Delete(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ create network namespaces and allocate interfaces for containers to use.
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/common"
|
||||
|
@ -84,6 +83,7 @@ type Endpoint interface {
|
|||
|
||||
// NetworkDriver provides a reference to driver and way to push driver specific config
|
||||
type NetworkDriver struct {
|
||||
networkType string
|
||||
internalDriver driverapi.Driver
|
||||
}
|
||||
|
||||
|
@ -121,19 +121,32 @@ func New() NetworkController {
|
|||
func (c *controller) NewNetworkDriver(networkType string, options interface{}) (*NetworkDriver, error) {
|
||||
d, ok := c.drivers[networkType]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown driver %q", networkType)
|
||||
return nil, NetworkTypeError(networkType)
|
||||
}
|
||||
|
||||
if err := d.Config(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &NetworkDriver{internalDriver: d}, nil
|
||||
return &NetworkDriver{networkType: networkType, internalDriver: d}, nil
|
||||
}
|
||||
|
||||
// NewNetwork creates a new network of the specified networkType. The options
|
||||
// NewNetwork creates a new network of the specified NetworkDriver. The options
|
||||
// are driver specific and modeled in a generic way.
|
||||
func (c *controller) NewNetwork(nd *NetworkDriver, name string, options interface{}) (Network, error) {
|
||||
if nd == nil {
|
||||
return nil, ErrNilNetworkDriver
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
for _, n := range c.networks {
|
||||
if n.name == name {
|
||||
c.Unlock()
|
||||
return nil, NetworkNameError(name)
|
||||
}
|
||||
}
|
||||
c.Unlock()
|
||||
|
||||
network := &network{
|
||||
name: name,
|
||||
id: driverapi.UUID(common.GenerateRandomID()),
|
||||
|
@ -143,7 +156,7 @@ func (c *controller) NewNetwork(nd *NetworkDriver, name string, options interfac
|
|||
|
||||
d := network.driver.internalDriver
|
||||
if d == nil {
|
||||
return nil, fmt.Errorf("invalid driver bound to network")
|
||||
return nil, ErrInvalidNetworkDriver
|
||||
}
|
||||
|
||||
if err := d.CreateNetwork(network.id, options); err != nil {
|
||||
|
@ -166,7 +179,11 @@ func (n *network) ID() string {
|
|||
}
|
||||
|
||||
func (n *network) Type() string {
|
||||
return n.networkType
|
||||
if n.driver == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return n.driver.networkType
|
||||
}
|
||||
|
||||
func (n *network) Delete() error {
|
||||
|
@ -176,7 +193,7 @@ func (n *network) Delete() error {
|
|||
_, ok := n.ctrlr.networks[n.id]
|
||||
if !ok {
|
||||
n.ctrlr.Unlock()
|
||||
return fmt.Errorf("unknown network %s id %s", n.name, n.id)
|
||||
return &UnknownNetworkError{name: n.name, id: string(n.id)}
|
||||
}
|
||||
|
||||
n.Lock()
|
||||
|
@ -184,7 +201,7 @@ func (n *network) Delete() error {
|
|||
n.Unlock()
|
||||
if numEps != 0 {
|
||||
n.ctrlr.Unlock()
|
||||
return fmt.Errorf("network %s has active endpoints", n.id)
|
||||
return &ActiveEndpointsError{name: n.name, id: string(n.id)}
|
||||
}
|
||||
|
||||
delete(n.ctrlr.networks, n.id)
|
||||
|
@ -228,7 +245,7 @@ func (ep *endpoint) Delete() error {
|
|||
_, ok := n.endpoints[ep.id]
|
||||
if !ok {
|
||||
n.Unlock()
|
||||
return fmt.Errorf("unknown endpoint %s id %s", ep.name, ep.id)
|
||||
return &UnknownEndpointError{name: ep.name, id: string(ep.id)}
|
||||
}
|
||||
|
||||
delete(n.endpoints, ep.id)
|
||||
|
|
Loading…
Reference in a new issue