Fix tests

Also, refactor some tests and MakeRegistry in api_topologies
This commit is contained in:
Alfonso Acosta
2016-11-29 07:18:08 -08:00
committed by Mike Lang
parent 003ef6b4ea
commit 9c7282231f
4 changed files with 95 additions and 88 deletions
+69 -77
View File
@@ -45,13 +45,76 @@ var (
}
)
func init() {
AddInitialTopologiesToRegistry(topologyRegistry)
// kubernetesFilters generates the current kubernetes filters based on the
// available k8s topologies.
func kubernetesFilters(namespaces ...string) APITopologyOptionGroup {
options := APITopologyOptionGroup{ID: "namespace", Default: "all"}
for _, namespace := range namespaces {
if namespace == "default" {
options.Default = namespace
}
options.Options = append(options.Options, APITopologyOption{
Value: namespace, Label: namespace, filter: render.IsNamespace(namespace), filterPseudo: false,
})
}
options.Options = append(options.Options, APITopologyOption{Value: "all", Label: "All Namespaces", filter: nil, filterPseudo: false})
return options
}
// AddInitialTopologiesToRegistry does the initial setup for a Registry.
// This is needed for testing.
func AddInitialTopologiesToRegistry(registry *Registry) {
// updateFilters updates the available filters based on the current report.
// Currently only kubernetes changes.
func updateFilters(rpt report.Report, topologies []APITopologyDesc) []APITopologyDesc {
namespaces := map[string]struct{}{}
for _, t := range []report.Topology{rpt.Pod, rpt.Service, rpt.Deployment, rpt.ReplicaSet} {
for _, n := range t.Nodes {
if state, ok := n.Latest.Lookup(kubernetes.State); ok && state == kubernetes.StateDeleted {
continue
}
if namespace, ok := n.Latest.Lookup(kubernetes.Namespace); ok {
namespaces[namespace] = struct{}{}
}
}
}
var ns []string
for namespace := range namespaces {
ns = append(ns, namespace)
}
sort.Strings(ns)
for i, t := range topologies {
if t.id == podsID || t.id == servicesID || t.id == deploymentsID || t.id == replicaSetsID {
topologies[i] = updateTopologyFilters(t, []APITopologyOptionGroup{
kubernetesFilters(ns...), unmanagedFilter,
})
}
}
return topologies
}
// updateTopologyFilters recursively sets the options on a topology description
func updateTopologyFilters(t APITopologyDesc, options []APITopologyOptionGroup) APITopologyDesc {
t.Options = options
for i, sub := range t.SubTopologies {
t.SubTopologies[i] = updateTopologyFilters(sub, options)
}
return t
}
// MakeAPITopologyOption provides an external interface to the package for creating an APITopologyOption.
func MakeAPITopologyOption(value string, label string, filterFunc render.FilterFunc, pseudo bool) APITopologyOption {
return APITopologyOption{Value: value, Label: label, filter: filterFunc, filterPseudo: pseudo}
}
// Registry is a threadsafe store of the available topologies
type Registry struct {
sync.RWMutex
items map[string]APITopologyDesc
}
// MakeRegistry returns a new Registry
func MakeRegistry() *Registry {
registry := &Registry{
items: map[string]APITopologyDesc{},
}
containerFilters := []APITopologyOptionGroup{
{
ID: containerLabelFiltersGroupID,
@@ -189,79 +252,8 @@ func AddInitialTopologiesToRegistry(registry *Registry) {
Name: "Weave Net",
},
)
}
// kubernetesFilters generates the current kubernetes filters based on the
// available k8s topologies.
func kubernetesFilters(namespaces ...string) APITopologyOptionGroup {
options := APITopologyOptionGroup{ID: "namespace", Default: "all"}
for _, namespace := range namespaces {
if namespace == "default" {
options.Default = namespace
}
options.Options = append(options.Options, APITopologyOption{
Value: namespace, Label: namespace, filter: render.IsNamespace(namespace), filterPseudo: false,
})
}
options.Options = append(options.Options, APITopologyOption{Value: "all", Label: "All Namespaces", filter: nil, filterPseudo: false})
return options
}
// updateFilters updates the available filters based on the current report.
// Currently only kubernetes changes.
func updateFilters(rpt report.Report, topologies []APITopologyDesc) []APITopologyDesc {
namespaces := map[string]struct{}{}
for _, t := range []report.Topology{rpt.Pod, rpt.Service, rpt.Deployment, rpt.ReplicaSet} {
for _, n := range t.Nodes {
if state, ok := n.Latest.Lookup(kubernetes.State); ok && state == kubernetes.StateDeleted {
continue
}
if namespace, ok := n.Latest.Lookup(kubernetes.Namespace); ok {
namespaces[namespace] = struct{}{}
}
}
}
var ns []string
for namespace := range namespaces {
ns = append(ns, namespace)
}
sort.Strings(ns)
for i, t := range topologies {
if t.id == podsID || t.id == servicesID || t.id == deploymentsID || t.id == replicaSetsID {
topologies[i] = updateTopologyFilters(t, []APITopologyOptionGroup{
kubernetesFilters(ns...), unmanagedFilter,
})
}
}
return topologies
}
// updateTopologyFilters recursively sets the options on a topology description
func updateTopologyFilters(t APITopologyDesc, options []APITopologyOptionGroup) APITopologyDesc {
t.Options = options
for i, sub := range t.SubTopologies {
t.SubTopologies[i] = updateTopologyFilters(sub, options)
}
return t
}
// MakeAPITopologyOption provides an external interface to the package for creating an APITopologyOption.
func MakeAPITopologyOption(value string, label string, filterFunc render.FilterFunc, pseudo bool) APITopologyOption {
return APITopologyOption{Value: value, Label: label, filter: filterFunc, filterPseudo: pseudo}
}
// Registry is a threadsafe store of the available topologies
type Registry struct {
sync.RWMutex
items map[string]APITopologyDesc
}
// MakeRegistry returns a new Registry
func MakeRegistry() *Registry {
newRegistry := &Registry{
items: map[string]APITopologyDesc{},
}
return newRegistry
return registry
}
// APITopologyDesc is returned in a list by the /api/topology handler.
+20 -11
View File
@@ -20,7 +20,7 @@ import (
)
const (
containerLabelFiltersGroupID = "container_label_filters_group"
containerLabelFiltersGroupID = "container-label-filters-group"
customAPITopologyOptionFilterID = "containerLabelFilter0"
)
@@ -35,7 +35,7 @@ func TestAPITopology(t *testing.T) {
if err := decoder.Decode(&topologies); err != nil {
t.Fatalf("JSON parse error: %s", err)
}
equals(t, 4, len(topologies))
equals(t, 5, len(topologies))
for _, topology := range topologies {
is200(t, ts, topology.URL)
@@ -44,6 +44,11 @@ func TestAPITopology(t *testing.T) {
is200(t, ts, subTopology.URL)
}
// TODO: add ECS nodes in report fixture
if topology.Name == "Tasks" {
continue
}
if have := topology.Stats.EdgeCount; have <= 0 {
t.Errorf("EdgeCount isn't positive for %s: %d", topology.Name, have)
}
@@ -79,8 +84,9 @@ func TestContainerLabelFilterExclude(t *testing.T) {
// all containers but the excluded container should be present
for key := range topologySummaries {
if report.MakeContainerNodeID(fixture.ServerContainerNodeID) == key {
t.Errorf("TestAPITopologyNegativeContainerLabelFilter Failed. Expected to not find " + report.MakeContainerNodeID(fixture.ServerContainerNodeID) + " in report")
id := report.MakeContainerNodeID(fixture.ServerContainerNodeID)
if id == key {
t.Errorf("Didn't expect to find %q in report", id)
}
}
}
@@ -89,14 +95,17 @@ func getTestContainerLabelFilterTopologySummary(t *testing.T, exclude bool) (det
ts := topologyServer()
defer ts.Close()
topologyRegistry := app.MakeRegistry()
app.AddInitialTopologiesToRegistry(topologyRegistry)
var (
topologyRegistry = app.MakeRegistry()
filter render.FilterFunc
)
if exclude == true {
topologyRegistry.AddContainerFilters(app.MakeAPITopologyOption(customAPITopologyOptionFilterID, "title", render.DoesNotHaveLabel(fixture.TestLabelKey2, fixture.ApplicationLabelValue2), false))
filter = render.DoesNotHaveLabel(fixture.TestLabelKey2, fixture.ApplicationLabelValue2)
} else {
topologyRegistry.AddContainerFilters(app.MakeAPITopologyOption(customAPITopologyOptionFilterID, "title", render.HasLabel(fixture.TestLabelKey1, fixture.ApplicationLabelValue1), false))
filter = render.HasLabel(fixture.TestLabelKey1, fixture.ApplicationLabelValue1)
}
option := app.MakeAPITopologyOption(customAPITopologyOptionFilterID, "title", filter, false)
topologyRegistry.AddContainerFilters(option)
urlvalues := url.Values{}
urlvalues.Set(containerLabelFiltersGroupID, customAPITopologyOptionFilterID)
@@ -123,7 +132,7 @@ func TestAPITopologyAddsKubernetes(t *testing.T) {
if err := decoder.Decode(&topologies); err != nil {
t.Fatalf("JSON parse error: %s", err)
}
equals(t, 4, len(topologies))
equals(t, 5, len(topologies))
// Enable the kubernetes topologies
rpt := report.MakeReport()
@@ -157,7 +166,7 @@ func TestAPITopologyAddsKubernetes(t *testing.T) {
if err := decoder.Decode(&topologies); err != nil {
t.Fatalf("JSON parse error: %s", err)
}
equals(t, 4, len(topologies))
equals(t, 5, len(topologies))
found := false
for _, topology := range topologies {
@@ -83,6 +83,8 @@ func TestAppClientPublish(t *testing.T) {
rpt.ReplicaSet = report.MakeTopology()
rpt.Host = report.MakeTopology()
rpt.Overlay = report.MakeTopology()
rpt.ECSTask = report.MakeTopology()
rpt.ECSService = report.MakeTopology()
rpt.Endpoint.Controls = nil
rpt.Process.Controls = nil
rpt.Container.Controls = nil
@@ -93,6 +95,8 @@ func TestAppClientPublish(t *testing.T) {
rpt.ReplicaSet.Controls = nil
rpt.Host.Controls = nil
rpt.Overlay.Controls = nil
rpt.ECSTask.Controls = nil
rpt.ECSService.Controls = nil
s := dummyServer(t, token, id, version, rpt, done)
defer s.Close()
+2
View File
@@ -91,6 +91,8 @@ func TestProbe(t *testing.T) {
want.ReplicaSet.Controls = nil
want.Host.Controls = nil
want.Overlay.Controls = nil
want.ECSTask.Controls = nil
want.ECSService.Controls = nil
want.Endpoint.AddNode(node)
pub := mockPublisher{make(chan report.Report, 10)}