package plugin import ( "testing" "k8s.io/kubernetes/pkg/util/sets" osapi "github.com/openshift/origin/pkg/sdn/api" ) func TestNodeVNIDMap(t *testing.T) { vmap := newNodeVNIDMap(nil, nil) // empty vmap checkNotExists(t, vmap, "alpha") checkNamespaces(t, vmap, 1, []string{}) checkAllocatedVNIDs(t, vmap, []uint32{}) // set vnids, non-overlapping vmap.setVNID("alpha", 1) vmap.setVNID("bravo", 2) vmap.setVNID("charlie", 3) vmap.setVNID("delta", 4) checkExists(t, vmap, "alpha", 1) checkExists(t, vmap, "bravo", 2) checkExists(t, vmap, "charlie", 3) checkExists(t, vmap, "delta", 4) checkNotExists(t, vmap, "echo") checkNamespaces(t, vmap, 1, []string{"alpha"}) checkNamespaces(t, vmap, 2, []string{"bravo"}) checkNamespaces(t, vmap, 3, []string{"charlie"}) checkNamespaces(t, vmap, 4, []string{"delta"}) checkAllocatedVNIDs(t, vmap, []uint32{1, 2, 3, 4}) // unset vnids id, err := vmap.unsetVNID("alpha") if id != 1 || err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } id, err = vmap.unsetVNID("charlie") if id != 3 || err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } checkNotExists(t, vmap, "alpha") checkExists(t, vmap, "bravo", 2) checkNotExists(t, vmap, "charlie") checkExists(t, vmap, "delta", 4) id, err = vmap.unsetVNID("alpha") if err == nil { t.Fatalf("Unexpected success: %d", id) } id, err = vmap.unsetVNID("echo") if err == nil { t.Fatalf("Unexpected success: %d", id) } checkNamespaces(t, vmap, 1, []string{}) checkNamespaces(t, vmap, 2, []string{"bravo"}) checkNamespaces(t, vmap, 3, []string{}) checkNamespaces(t, vmap, 4, []string{"delta"}) checkAllocatedVNIDs(t, vmap, []uint32{2, 4}) // change vnids vmap.setVNID("bravo", 1) vmap.setVNID("delta", 2) checkExists(t, vmap, "bravo", 1) checkExists(t, vmap, "delta", 2) checkNamespaces(t, vmap, 1, []string{"bravo"}) checkNamespaces(t, vmap, 2, []string{"delta"}) checkNamespaces(t, vmap, 3, []string{}) checkNamespaces(t, vmap, 4, []string{}) checkAllocatedVNIDs(t, vmap, []uint32{1, 2}) // overlapping vnids vmap.setVNID("echo", 3) vmap.setVNID("foxtrot", 5) vmap.setVNID("golf", 1) vmap.setVNID("hotel", 1) vmap.setVNID("india", 1) vmap.setVNID("juliet", 3) checkExists(t, vmap, "bravo", 1) checkExists(t, vmap, "delta", 2) checkExists(t, vmap, "echo", 3) checkExists(t, vmap, "foxtrot", 5) checkExists(t, vmap, "golf", 1) checkExists(t, vmap, "hotel", 1) checkExists(t, vmap, "india", 1) checkExists(t, vmap, "juliet", 3) checkNamespaces(t, vmap, 1, []string{"bravo", "golf", "hotel", "india"}) checkNamespaces(t, vmap, 2, []string{"delta"}) checkNamespaces(t, vmap, 3, []string{"echo", "juliet"}) checkNamespaces(t, vmap, 4, []string{}) checkNamespaces(t, vmap, 5, []string{"foxtrot"}) checkAllocatedVNIDs(t, vmap, []uint32{1, 2, 3, 5}) // deleting with overlapping vnids id, err = vmap.unsetVNID("golf") if err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } id, err = vmap.unsetVNID("echo") if err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } id, err = vmap.unsetVNID("juliet") if err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } checkExists(t, vmap, "bravo", 1) checkExists(t, vmap, "delta", 2) checkNotExists(t, vmap, "echo") checkExists(t, vmap, "foxtrot", 5) checkNotExists(t, vmap, "golf") checkExists(t, vmap, "hotel", 1) checkExists(t, vmap, "india", 1) checkNotExists(t, vmap, "juliet") checkNamespaces(t, vmap, 1, []string{"bravo", "hotel", "india"}) checkNamespaces(t, vmap, 2, []string{"delta"}) checkNamespaces(t, vmap, 3, []string{}) checkNamespaces(t, vmap, 4, []string{}) checkNamespaces(t, vmap, 5, []string{"foxtrot"}) checkAllocatedVNIDs(t, vmap, []uint32{1, 2, 5}) } func checkExists(t *testing.T, vmap *nodeVNIDMap, name string, expected uint32) { id, err := vmap.GetVNID(name) if id != expected || err != nil { t.Fatalf("Unexpected failure: %d, %v", id, err) } } func checkNotExists(t *testing.T, vmap *nodeVNIDMap, name string) { id, err := vmap.GetVNID(name) if err == nil { t.Fatalf("Unexpected success: %d", id) } } func checkNamespaces(t *testing.T, vmap *nodeVNIDMap, vnid uint32, match []string) { namespaces := vmap.GetNamespaces(vnid) if len(namespaces) != len(match) { t.Fatalf("Wrong number of namespaces: %v vs %v", namespaces, match) } for _, m := range match { found := false for _, n := range namespaces { if n == m { found = true break } } if !found { t.Fatalf("Missing namespace: %s", m) } } } func checkAllocatedVNIDs(t *testing.T, vmap *nodeVNIDMap, match []uint32) { ids := []uint32{} idSet := sets.Int{} for _, id := range vmap.ids { if id != osapi.GlobalVNID { if !idSet.Has(int(id)) { ids = append(ids, id) idSet.Insert(int(id)) } } } if len(ids) != len(match) { t.Fatalf("Wrong number of VNIDs: %d vs %d", len(ids), len(match)) } for _, m := range match { found := false for _, n := range ids { if n == m { found = true break } } if !found { t.Fatalf("Missing VNID: %d", m) } } }