mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 01:31:17 +00:00
refactor: add a generic MergeActiveControls method
Use this instead of hard-coded knowledge about expected controls and counts when merging host topology.
This commit is contained in:
@@ -143,6 +143,37 @@ func (n Node) ActiveControls() []string {
|
||||
return strings.Split(activeControls, ScopeDelim)
|
||||
}
|
||||
|
||||
// MergeActiveControls merges the control lists from n and b
|
||||
func (n Node) MergeActiveControls(b Node) Node {
|
||||
activeControlsB, tsB, foundB := b.Latest.LookupEntry(NodeActiveControls)
|
||||
if !foundB { // nothing to merge
|
||||
return n
|
||||
}
|
||||
activeControlsA, tsA, foundA := n.Latest.LookupEntry(NodeActiveControls)
|
||||
if !foundA {
|
||||
return n.WithLatest(NodeActiveControls, tsB, activeControlsB)
|
||||
}
|
||||
if activeControlsA == activeControlsB {
|
||||
return n
|
||||
}
|
||||
// If we get here we have active controls in both n and b that are different
|
||||
merged := make(map[string]struct{})
|
||||
for _, c := range strings.Split(activeControlsA, ScopeDelim) {
|
||||
merged[c] = struct{}{}
|
||||
}
|
||||
for _, c := range strings.Split(activeControlsB, ScopeDelim) {
|
||||
merged[c] = struct{}{}
|
||||
}
|
||||
cs := make([]string, 0, len(merged))
|
||||
for c := range merged {
|
||||
cs = append(cs, c)
|
||||
}
|
||||
if tsA.Before(tsB) {
|
||||
tsA = tsB
|
||||
}
|
||||
return n.WithLatest(NodeActiveControls, tsA, strings.Join(cs, ScopeDelim))
|
||||
}
|
||||
|
||||
// WithParent returns a fresh copy of n, with one parent added
|
||||
func (n Node) WithParent(key, parent string) Node {
|
||||
n.Parents = n.Parents.AddString(key, parent)
|
||||
@@ -200,33 +231,7 @@ func (n Node) Merge(other Node) Node {
|
||||
|
||||
// Special case to merge controls from two different probes.
|
||||
if topology == "host" {
|
||||
controlString, _ := newNode.Latest.Lookup(NodeActiveControls)
|
||||
activeControls := strings.Split(controlString, ScopeDelim)
|
||||
// Host topology should have only two active controls.
|
||||
// Length equals to 2 means controls were merged properly.
|
||||
if len(activeControls) != 2 {
|
||||
// Check if host_exec control is missing.
|
||||
if !StringSet(activeControls).Contains("host_exec") {
|
||||
activeControls = append(activeControls, "host_exec")
|
||||
return newNode.
|
||||
WithLatestActiveControls(activeControls...)
|
||||
}
|
||||
// Else control kubernetes_cordon_node or kubernetes_uncordon_node is missing.
|
||||
// Merge controls from current node.
|
||||
c, _ := n.Latest.Lookup(NodeActiveControls)
|
||||
x := strings.Split(c, ScopeDelim)
|
||||
activeControls = append(activeControls, x...)
|
||||
|
||||
// Merge controls from incoming node.
|
||||
c, _ = other.Latest.Lookup(NodeActiveControls)
|
||||
x = strings.Split(c, ScopeDelim)
|
||||
activeControls = append(activeControls, x...)
|
||||
|
||||
// Use a StringSet to avoid duplicate controls from current and incoming node.
|
||||
var final StringSet
|
||||
return newNode.
|
||||
WithLatestActiveControls(final.Add(activeControls...)...)
|
||||
}
|
||||
newNode = newNode.MergeActiveControls(other)
|
||||
}
|
||||
|
||||
return newNode
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package report_test
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -180,3 +181,28 @@ func TestCounters(t *testing.T) {
|
||||
t.Errorf("Counters: %s", test.Diff(want, have))
|
||||
}
|
||||
}
|
||||
|
||||
func TestActiveControls(t *testing.T) {
|
||||
mtime.NowForce(time.Now())
|
||||
defer mtime.NowReset()
|
||||
|
||||
controls1 := []string{"bar", "foo"}
|
||||
node1 := report.MakeNode("node1").WithLatestActiveControls(controls1...)
|
||||
assert.Equal(t, controls1, node1.ActiveControls())
|
||||
assert.Equal(t, controls1, sorted(node1.MergeActiveControls(node1).ActiveControls()))
|
||||
|
||||
node2 := report.MakeNode("node2")
|
||||
assert.Equal(t, controls1, node1.MergeActiveControls(node2).ActiveControls())
|
||||
assert.Equal(t, controls1, node2.MergeActiveControls(node1).ActiveControls())
|
||||
|
||||
controls2 := []string{"bar", "bor"}
|
||||
controls3 := []string{"bar", "bor", "foo"}
|
||||
node3 := report.MakeNode("node1").WithLatestActiveControls(controls2...)
|
||||
assert.Equal(t, controls3, sorted(node1.MergeActiveControls(node3).ActiveControls()))
|
||||
assert.Equal(t, controls3, sorted(node3.MergeActiveControls(node1).ActiveControls()))
|
||||
}
|
||||
|
||||
func sorted(s []string) []string {
|
||||
sort.Strings(s)
|
||||
return s
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user