diff --git a/engine/engine_test.go b/engine/engine_test.go index 0261e36..a10c1a0 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -20,111 +20,12 @@ package engine // engine tests. import ( - "fmt" - "net" - - "github.com/google/seesaw/common/seesaw" - "github.com/google/seesaw/ipvs" ncclient "github.com/google/seesaw/ncc/client" - ncctypes "github.com/google/seesaw/ncc/types" - "github.com/google/seesaw/quagga" - - log "github.com/golang/glog" ) -type dummyNCC struct{} - -func (nc *dummyNCC) NewLBInterface(name string, cfg *ncctypes.LBConfig) ncclient.LBInterface { - return nil -} -func (nc *dummyNCC) Dial() error { return nil } -func (nc *dummyNCC) Close() error { return nil } -func (nc *dummyNCC) ARPSendGratuitous(iface string, ip net.IP) error { return nil } -func (nc *dummyNCC) BGPConfig() ([]string, error) { return nil, nil } -func (nc *dummyNCC) BGPNeighbors() ([]*quagga.Neighbor, error) { return nil, nil } -func (nc *dummyNCC) BGPWithdrawAll() error { return nil } -func (nc *dummyNCC) BGPAdvertiseVIP(ip net.IP) error { return nil } -func (nc *dummyNCC) BGPWithdrawVIP(ip net.IP) error { return nil } -func (nc *dummyNCC) IPVSFlush() error { return nil } -func (nc *dummyNCC) IPVSGetServices() ([]*ipvs.Service, error) { return nil, nil } -func (nc *dummyNCC) IPVSGetService(svc *ipvs.Service) (*ipvs.Service, error) { return nil, nil } -func (nc *dummyNCC) IPVSAddService(svc *ipvs.Service) error { return nil } -func (nc *dummyNCC) IPVSUpdateService(svc *ipvs.Service) error { return nil } -func (nc *dummyNCC) IPVSDeleteService(svc *ipvs.Service) error { return nil } -func (nc *dummyNCC) IPVSAddDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } -func (nc *dummyNCC) IPVSUpdateDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } -func (nc *dummyNCC) IPVSDeleteDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } -func (nc *dummyNCC) RouteDefaultIPv4() (net.IP, error) { return nil, nil } - -type dummyLBInterface struct { - vips map[seesaw.VIP]bool - vlans map[uint16]bool - vservers map[string]map[seesaw.AF]bool -} - -func newDummyLBInterface() *dummyLBInterface { - return &dummyLBInterface{ - make(map[seesaw.VIP]bool), - make(map[uint16]bool), - make(map[string]map[seesaw.AF]bool), - } -} - -func (lb *dummyLBInterface) Init() error { return nil } -func (lb *dummyLBInterface) Up() error { return nil } -func (lb *dummyLBInterface) Down() error { return nil } -func (lb *dummyLBInterface) AddVIP(vip *seesaw.VIP) error { - log.Infof("Adding vip %v", vip) - lb.vips[*vip] = true - return nil -} -func (lb *dummyLBInterface) DeleteVIP(vip *seesaw.VIP) error { - log.Infof("Deleting vip %v", vip) - if _, ok := lb.vips[*vip]; !ok { - return fmt.Errorf("deleting non-existent VIP: %v", vip) - } - delete(lb.vips, *vip) - return nil -} -func (lb *dummyLBInterface) AddVLAN(vlan *seesaw.VLAN) error { - lb.vlans[vlan.Key()] = true - return nil -} -func (lb *dummyLBInterface) DeleteVLAN(vlan *seesaw.VLAN) error { - if _, ok := lb.vlans[vlan.Key()]; !ok { - return fmt.Errorf("deleting non-existent VLAN: %v", vlan) - } - delete(lb.vlans, vlan.Key()) - return nil -} -func (lb *dummyLBInterface) AddVserver(v *seesaw.Vserver, af seesaw.AF) error { - log.Infof("Adding vserver %v", v) - afMap, ok := lb.vservers[v.Name] - if !ok { - afMap = make(map[seesaw.AF]bool) - lb.vservers[v.Name] = afMap - } - afMap[af] = true - return nil -} -func (lb *dummyLBInterface) DeleteVserver(v *seesaw.Vserver, af seesaw.AF) error { - log.Infof("Deleting vserver %v", v) - if afMap, ok := lb.vservers[v.Name]; !ok { - return fmt.Errorf("deleting non-existent Vserver: %v", v) - } else if _, ok := afMap[af]; !ok { - return fmt.Errorf("deleting wrong AF for Vserver %v: %v", v, af) - } else { - delete(afMap, af) - if len(afMap) == 0 { - delete(lb.vservers, v.Name) - } - } - return nil -} - func newTestEngine() *Engine { - e := newEngineWithNCC(nil, &dummyNCC{}) - e.lbInterface = newDummyLBInterface() + e := newEngineWithNCC(nil, ncclient.NewDummyNCC()) + e.lbInterface = ncclient.NewDummyLBInterface() return e } @@ -133,6 +34,5 @@ func newTestVserver(engine *Engine) *vserver { engine = newTestEngine() } v := newVserver(engine) - v.ncc = &dummyNCC{} return v } diff --git a/engine/vserver_test.go b/engine/vserver_test.go index 4076671..251cae0 100644 --- a/engine/vserver_test.go +++ b/engine/vserver_test.go @@ -28,6 +28,7 @@ import ( "github.com/google/seesaw/common/seesaw" "github.com/google/seesaw/engine/config" "github.com/google/seesaw/healthcheck" + ncclient "github.com/google/seesaw/ncc/client" "github.com/kylelemons/godebug/pretty" log "github.com/golang/glog" @@ -1763,7 +1764,7 @@ func TestUpdateVserver(t *testing.T) { func TestReIPVserver(t *testing.T) { e := newTestEngine() vserver := newTestVserver(e) - lbIF := e.lbInterface.(*dummyLBInterface) + lbIF := e.lbInterface.(*ncclient.DummyLBInterface) clusterName := "au-syd" serviceName := "dns.resolver@au-syd" tests := []struct { @@ -1830,7 +1831,7 @@ func TestReIPVserver(t *testing.T) { } gotIFIPs := make(map[string]bool) - for v := range lbIF.vips { + for v := range lbIF.Vips { gotIFIPs[v.IP.String()] = true } if diff := pretty.Compare(wantVIPs, gotIFIPs); diff != "" { diff --git a/ncc/client/dummy.go b/ncc/client/dummy.go new file mode 100644 index 0000000..44b114f --- /dev/null +++ b/ncc/client/dummy.go @@ -0,0 +1,130 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Author: jsing@google.com (Joel Sing) + +package client + +// This file contains dummy implementation of interfaces for testing purposes + +import ( + "fmt" + "net" + + "github.com/google/seesaw/common/seesaw" + "github.com/google/seesaw/ipvs" + ncctypes "github.com/google/seesaw/ncc/types" + "github.com/google/seesaw/quagga" + + log "github.com/golang/glog" +) + +type dummyNCC struct{} + +// NewDummyNCC returns a dummy NCC client for testing purpose. +// It implements all methods NCC interface requires with no-op. +func NewDummyNCC() NCC { + return &dummyNCC{} +} + +func (nc *dummyNCC) NewLBInterface(name string, cfg *ncctypes.LBConfig) LBInterface { + return nil +} +func (nc *dummyNCC) Dial() error { return nil } +func (nc *dummyNCC) Close() error { return nil } +func (nc *dummyNCC) ARPSendGratuitous(iface string, ip net.IP) error { return nil } +func (nc *dummyNCC) BGPConfig() ([]string, error) { return nil, nil } +func (nc *dummyNCC) BGPNeighbors() ([]*quagga.Neighbor, error) { return nil, nil } +func (nc *dummyNCC) BGPWithdrawAll() error { return nil } +func (nc *dummyNCC) BGPAdvertiseVIP(ip net.IP) error { return nil } +func (nc *dummyNCC) BGPWithdrawVIP(ip net.IP) error { return nil } +func (nc *dummyNCC) IPVSFlush() error { return nil } +func (nc *dummyNCC) IPVSGetServices() ([]*ipvs.Service, error) { return nil, nil } +func (nc *dummyNCC) IPVSGetService(svc *ipvs.Service) (*ipvs.Service, error) { return nil, nil } +func (nc *dummyNCC) IPVSAddService(svc *ipvs.Service) error { return nil } +func (nc *dummyNCC) IPVSUpdateService(svc *ipvs.Service) error { return nil } +func (nc *dummyNCC) IPVSDeleteService(svc *ipvs.Service) error { return nil } +func (nc *dummyNCC) IPVSAddDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } +func (nc *dummyNCC) IPVSUpdateDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } +func (nc *dummyNCC) IPVSDeleteDestination(svc *ipvs.Service, dst *ipvs.Destination) error { return nil } +func (nc *dummyNCC) RouteDefaultIPv4() (net.IP, error) { return nil, nil } + +type DummyLBInterface struct { + Vips map[seesaw.VIP]bool + Vlans map[uint16]bool + Vservers map[string]map[seesaw.AF]bool +} + +// NewDummyLBInterface returns a dummy LBInterface for testing purpose. +// Internally it tracks the vips, vlans and vservers resources it manages and +// can be read back through public fields. +func NewDummyLBInterface() *DummyLBInterface { + return &DummyLBInterface{ + make(map[seesaw.VIP]bool), + make(map[uint16]bool), + make(map[string]map[seesaw.AF]bool), + } +} + +func (lb *DummyLBInterface) Init() error { return nil } +func (lb *DummyLBInterface) Up() error { return nil } +func (lb *DummyLBInterface) Down() error { return nil } +func (lb *DummyLBInterface) AddVIP(vip *seesaw.VIP) error { + log.Infof("Adding vip %v", vip) + lb.Vips[*vip] = true + return nil +} +func (lb *DummyLBInterface) DeleteVIP(vip *seesaw.VIP) error { + log.Infof("Deleting vip %v", vip) + if _, ok := lb.Vips[*vip]; !ok { + return fmt.Errorf("deleting non-existent VIP: %v", vip) + } + delete(lb.Vips, *vip) + return nil +} +func (lb *DummyLBInterface) AddVLAN(vlan *seesaw.VLAN) error { + lb.Vlans[vlan.Key()] = true + return nil +} +func (lb *DummyLBInterface) DeleteVLAN(vlan *seesaw.VLAN) error { + if _, ok := lb.Vlans[vlan.Key()]; !ok { + return fmt.Errorf("deleting non-existent VLAN: %v", vlan) + } + delete(lb.Vlans, vlan.Key()) + return nil +} +func (lb *DummyLBInterface) AddVserver(v *seesaw.Vserver, af seesaw.AF) error { + log.Infof("Adding vserver %v", v) + afMap, ok := lb.Vservers[v.Name] + if !ok { + afMap = make(map[seesaw.AF]bool) + lb.Vservers[v.Name] = afMap + } + afMap[af] = true + return nil +} +func (lb *DummyLBInterface) DeleteVserver(v *seesaw.Vserver, af seesaw.AF) error { + log.Infof("Deleting vserver %v", v) + if afMap, ok := lb.Vservers[v.Name]; !ok { + return fmt.Errorf("deleting non-existent Vserver: %v", v) + } else if _, ok := afMap[af]; !ok { + return fmt.Errorf("deleting wrong AF for Vserver %v: %v", v, af) + } else { + delete(afMap, af) + if len(afMap) == 0 { + delete(lb.Vservers, v.Name) + } + } + return nil +}