From 352722b1e78bc5dc9a5acf6a56d6fc84c15f2515 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Sat, 3 Feb 2018 05:14:10 +0000 Subject: [PATCH] Add some more tests for routes. --- .../providers/azure/azure_fakes.go | 83 +++++++++ .../providers/azure/azure_routes_test.go | 170 +++++++++++++++++- 2 files changed, 252 insertions(+), 1 deletion(-) diff --git a/pkg/cloudprovider/providers/azure/azure_fakes.go b/pkg/cloudprovider/providers/azure/azure_fakes.go index b6689cc711c..8450dcbb759 100644 --- a/pkg/cloudprovider/providers/azure/azure_fakes.go +++ b/pkg/cloudprovider/providers/azure/azure_fakes.go @@ -25,6 +25,10 @@ import ( "sync" "time" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/cloudprovider" + "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/disk" "github.com/Azure/azure-sdk-for-go/arm/network" @@ -846,6 +850,7 @@ func (fRC *fakeRoutesClient) Delete(resourceGroupName string, routeTableName str type fakeRouteTablesClient struct { mutex *sync.Mutex FakeStore map[string]map[string]network.RouteTable + Calls []string } func newFakeRouteTablesClient() *fakeRouteTablesClient { @@ -859,6 +864,8 @@ func (fRTC *fakeRouteTablesClient) CreateOrUpdate(resourceGroupName string, rout fRTC.mutex.Lock() defer fRTC.mutex.Unlock() + fRTC.Calls = append(fRTC.Calls, "CreateOrUpdate") + resultChan := make(chan network.RouteTable, 1) errChan := make(chan error, 1) var result network.RouteTable @@ -885,6 +892,9 @@ func (fRTC *fakeRouteTablesClient) CreateOrUpdate(resourceGroupName string, rout func (fRTC *fakeRouteTablesClient) Get(resourceGroupName string, routeTableName string, expand string) (result network.RouteTable, err error) { fRTC.mutex.Lock() defer fRTC.mutex.Unlock() + + fRTC.Calls = append(fRTC.Calls, "Get") + if _, ok := fRTC.FakeStore[resourceGroupName]; ok { if entity, ok := fRTC.FakeStore[resourceGroupName][routeTableName]; ok { return entity, nil @@ -1102,3 +1112,76 @@ func (fDC *fakeDisksClient) Get(resourceGroupName string, diskName string) (resu Message: "Not such Disk", } } + +type fakeVMSet struct { + NodeToIP map[string]map[string]string + Err error +} + +func (f *fakeVMSet) GetInstanceIDByNodeName(name string) (string, error) { + return "", fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetInstanceTypeByNodeName(name string) (string, error) { + return "", fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetIPByNodeName(name, vmSetName string) (string, error) { + nodes, found := f.NodeToIP[vmSetName] + if !found { + return "", fmt.Errorf("not found") + } + ip, found := nodes[name] + if !found { + return "", fmt.Errorf("not found") + } + return ip, nil +} + +func (f *fakeVMSet) GetPrimaryInterface(nodeName, vmSetName string) (network.Interface, error) { + return network.Interface{}, fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetNodeNameByProviderID(providerID string) (types.NodeName, error) { + return types.NodeName(""), fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetZoneByNodeName(name string) (cloudprovider.Zone, error) { + return cloudprovider.Zone{}, fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetPrimaryVMSetName() string { + return "" +} + +func (f *fakeVMSet) GetVMSetNames(service *v1.Service, nodes []*v1.Node) (availabilitySetNames *[]string, err error) { + return nil, fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) EnsureHostsInPool(serviceName string, nodes []*v1.Node, backendPoolID string, vmSetName string) error { + return fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) EnsureBackendPoolDeleted(poolID, vmSetName string) error { + return fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes) error { + return fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) DetachDiskByName(diskName, diskURI string, nodeName types.NodeName) error { + return fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetDiskLun(diskName, diskURI string, nodeName types.NodeName) (int32, error) { + return -1, fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) GetNextDiskLun(nodeName types.NodeName) (int32, error) { + return -1, fmt.Errorf("unimplemented") +} + +func (f *fakeVMSet) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) { + return nil, fmt.Errorf("unimplemented") +} diff --git a/pkg/cloudprovider/providers/azure/azure_routes_test.go b/pkg/cloudprovider/providers/azure/azure_routes_test.go index 31f31ee4eb4..0da8a1a15db 100644 --- a/pkg/cloudprovider/providers/azure/azure_routes_test.go +++ b/pkg/cloudprovider/providers/azure/azure_routes_test.go @@ -17,6 +17,7 @@ limitations under the License. package azure import ( + "context" "fmt" "reflect" "testing" @@ -27,7 +28,105 @@ import ( "github.com/Azure/go-autorest/autorest/to" ) +func TestDeleteRoute(t *testing.T) { + fakeRoutes := newFakeRoutesClient() + + cloud := &Cloud{ + RoutesClient: fakeRoutes, + Config: Config{ + ResourceGroup: "foo", + RouteTableName: "bar", + Location: "location", + }, + } + route := cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/24"} + routeName := mapNodeNameToRouteName(route.TargetNode) + + fakeRoutes.FakeStore = map[string]map[string]network.Route{ + cloud.RouteTableName: { + routeName: {}, + }, + } + + err := cloud.DeleteRoute(context.TODO(), "cluster", &route) + if err != nil { + t.Errorf("unexpected error deleting route: %v", err) + t.FailNow() + } + + mp, found := fakeRoutes.FakeStore[cloud.RouteTableName] + if !found { + t.Errorf("unexpected missing item for %s", cloud.RouteTableName) + t.FailNow() + } + ob, found := mp[routeName] + if found { + t.Errorf("unexpectedly found: %v that should have been deleted.", ob) + } +} + func TestCreateRoute(t *testing.T) { + fakeTable := newFakeRouteTablesClient() + fakeVM := &fakeVMSet{} + fakeRoutes := newFakeRoutesClient() + + cloud := &Cloud{ + RouteTablesClient: fakeTable, + RoutesClient: fakeRoutes, + vmSet: fakeVM, + Config: Config{ + ResourceGroup: "foo", + RouteTableName: "bar", + Location: "location", + }, + } + cache, _ := cloud.newRouteTableCache() + cloud.rtCache = cache + + expectedTable := network.RouteTable{ + Name: &cloud.RouteTableName, + Location: &cloud.Location, + } + fakeTable.FakeStore = map[string]map[string]network.RouteTable{} + fakeTable.FakeStore[cloud.ResourceGroup] = map[string]network.RouteTable{ + cloud.RouteTableName: expectedTable, + } + route := cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/24"} + + nodeIP := "2.4.6.8" + fakeVM.NodeToIP = map[string]map[string]string{ + "": { + "node": nodeIP, + }, + } + + err := cloud.CreateRoute(context.TODO(), "cluster", "unused", &route) + if err != nil { + t.Errorf("unexpected error create if not exists route table: %v", err) + t.FailNow() + } + if len(fakeTable.Calls) != 1 || fakeTable.Calls[0] != "Get" { + t.Errorf("unexpected calls create if not exists, exists: %v", fakeTable.Calls) + } + + routeName := mapNodeNameToRouteName(route.TargetNode) + routeInfo, found := fakeRoutes.FakeStore[cloud.RouteTableName][routeName] + if !found { + t.Errorf("could not find route: %v in %v", routeName, fakeRoutes.FakeStore) + t.FailNow() + } + if *routeInfo.AddressPrefix != route.DestinationCIDR { + t.Errorf("Expected cidr: %s, saw %s", *routeInfo.AddressPrefix, route.DestinationCIDR) + } + if routeInfo.NextHopType != network.RouteNextHopTypeVirtualAppliance { + t.Errorf("Expected next hop: %v, saw %v", network.RouteNextHopTypeVirtualAppliance, routeInfo.NextHopType) + } + if *routeInfo.NextHopIPAddress != nodeIP { + t.Errorf("Expected IP addres: %s, saw %s", nodeIP, *routeInfo.NextHopIPAddress) + } +} + +func TestCreateRouteTableIfNotExists_Exists(t *testing.T) { fake := newFakeRouteTablesClient() cloud := &Cloud{ RouteTablesClient: fake, @@ -37,7 +136,76 @@ func TestCreateRoute(t *testing.T) { Location: "location", }, } - cloud.rtCache, _ = cloud.newRouteTableCache() + cache, _ := cloud.newRouteTableCache() + cloud.rtCache = cache + + expectedTable := network.RouteTable{ + Name: &cloud.RouteTableName, + Location: &cloud.Location, + } + fake.FakeStore = map[string]map[string]network.RouteTable{} + fake.FakeStore[cloud.ResourceGroup] = map[string]network.RouteTable{ + cloud.RouteTableName: expectedTable, + } + err := cloud.createRouteTableIfNotExists("clusterName", &cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/16"}) + if err != nil { + t.Errorf("unexpected error create if not exists route table: %v", err) + t.FailNow() + } + if len(fake.Calls) != 1 || fake.Calls[0] != "Get" { + t.Errorf("unexpected calls create if not exists, exists: %v", fake.Calls) + } +} + +func TestCreateRouteTableIfNotExists_NotExists(t *testing.T) { + fake := newFakeRouteTablesClient() + cloud := &Cloud{ + RouteTablesClient: fake, + Config: Config{ + ResourceGroup: "foo", + RouteTableName: "bar", + Location: "location", + }, + } + cache, _ := cloud.newRouteTableCache() + cloud.rtCache = cache + + expectedTable := network.RouteTable{ + Name: &cloud.RouteTableName, + Location: &cloud.Location, + } + + err := cloud.createRouteTableIfNotExists("clusterName", &cloudprovider.Route{TargetNode: "node", DestinationCIDR: "1.2.3.4/16"}) + if err != nil { + t.Errorf("unexpected error create if not exists route table: %v", err) + t.FailNow() + } + + table := fake.FakeStore[cloud.ResourceGroup][cloud.RouteTableName] + if *table.Location != *expectedTable.Location { + t.Errorf("mismatch: %s vs %s", *table.Location, *expectedTable.Location) + } + if *table.Name != *expectedTable.Name { + t.Errorf("mismatch: %s vs %s", *table.Name, *expectedTable.Name) + } + if len(fake.Calls) != 2 || fake.Calls[0] != "Get" || fake.Calls[1] != "CreateOrUpdate" { + t.Errorf("unexpected calls create if not exists, exists: %v", fake.Calls) + } +} + +func TestCreateRouteTable(t *testing.T) { + fake := newFakeRouteTablesClient() + cloud := &Cloud{ + RouteTablesClient: fake, + Config: Config{ + ResourceGroup: "foo", + RouteTableName: "bar", + Location: "location", + }, + } + cache, _ := cloud.newRouteTableCache() + cloud.rtCache = cache + expectedTable := network.RouteTable{ Name: &cloud.RouteTableName, Location: &cloud.Location,