diff --git a/go.mod b/go.mod index b28d5927..dce4237d 100644 --- a/go.mod +++ b/go.mod @@ -31,12 +31,12 @@ require ( gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.28.2 + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 ) require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -65,7 +65,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apimachinery v0.28.2 // indirect k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) diff --git a/src/go/pt-galera-log-explainer/translate/translate.go b/src/go/pt-galera-log-explainer/translate/translate.go index f549a3b8..3c15ba1e 100644 --- a/src/go/pt-galera-log-explainer/translate/translate.go +++ b/src/go/pt-galera-log-explainer/translate/translate.go @@ -66,11 +66,15 @@ func AddHashToIP(hash, ip string, ts time.Time) { db.HashToIP[hash] = translationUnit{Value: ip, Timestamp: ts} } +func sameAsLatestValue(m map[string][]translationUnit, key string, newvalue string) bool { + return len(m[key]) > 0 && m[key][len(m[key])-1].Value == newvalue +} + func AddHashToNodeName(hash, name string, ts time.Time) { db.rwlock.Lock() defer db.rwlock.Unlock() name = utils.ShortNodeName(name) - if len(db.HashToNodeNames[hash]) > 0 && db.HashToNodeNames[hash][len(db.HashToNodeNames[hash])-1].Value == name { + if sameAsLatestValue(db.HashToNodeNames, hash, name) { return } db.HashToNodeNames[hash] = append(db.HashToNodeNames[hash], translationUnit{Value: name, Timestamp: ts}) @@ -80,7 +84,7 @@ func AddIPToNodeName(ip, name string, ts time.Time) { db.rwlock.Lock() defer db.rwlock.Unlock() name = utils.ShortNodeName(name) - if len(db.IPToNodeNames[ip]) > 0 && db.IPToNodeNames[ip][len(db.IPToNodeNames[ip])-1].Value == name { + if sameAsLatestValue(db.IPToNodeNames, ip, name) { return } db.IPToNodeNames[ip] = append(db.IPToNodeNames[ip], translationUnit{Value: name, Timestamp: ts}) @@ -89,7 +93,7 @@ func AddIPToNodeName(ip, name string, ts time.Time) { func AddIPToMethod(ip, method string, ts time.Time) { db.rwlock.Lock() defer db.rwlock.Unlock() - if len(db.IPToMethods[ip]) > 0 && db.IPToMethods[ip][len(db.IPToMethods[ip])-1].Value == method { + if sameAsLatestValue(db.IPToMethods, ip, method) { return } db.IPToMethods[ip] = append(db.IPToMethods[ip], translationUnit{Value: method, Timestamp: ts}) diff --git a/src/go/pt-galera-log-explainer/translate/translate_test.go b/src/go/pt-galera-log-explainer/translate/translate_test.go new file mode 100644 index 00000000..1d69aa0f --- /dev/null +++ b/src/go/pt-galera-log-explainer/translate/translate_test.go @@ -0,0 +1,103 @@ +package translate + +import ( + "testing" + "time" +) + +func TestAddHashToNodeName(t *testing.T) { + hash1 := "somehash" + name1 := "somename" + ResetDB() + ts1, _ := time.Parse(time.RFC3339, "2001-01-01T01:01:01") + AddHashToNodeName(hash1, name1, ts1) + if length := len(db.HashToNodeNames[hash1]); length != 1 { + t.Errorf("incorrect hashtonodenames length: %d, expected 1", length) + t.Fail() + } + name2 := "somename.with.a.fqdn.net" + AddHashToNodeName(hash1, name2, ts1) + if length := len(db.HashToNodeNames[hash1]); length != 1 { + t.Errorf("incorrect hashtonodenames length: %d, expected 1", length) + t.Fail() + } + name3 := "somename2.with.a.fqdn.net" + AddHashToNodeName(hash1, name3, ts1) + if length := len(db.HashToNodeNames[hash1]); length != 2 { + t.Errorf("incorrect hashtonodenames length: %d, expected 2", length) + t.Fail() + } +} + +func TestAddIPToNodeName(t *testing.T) { + ip := "127.0.0.1" + name1 := "somename" + ResetDB() + ts1, _ := time.Parse(time.RFC3339, "2001-01-01T01:01:01") + AddIPToNodeName(ip, name1, ts1) + if length := len(db.IPToNodeNames[ip]); length != 1 { + t.Errorf("incorrect iptonodenames length: %d, expected 1", length) + t.Fail() + } + name2 := "somename.with.a.fqdn.net" + AddIPToNodeName(ip, name2, ts1) + if length := len(db.IPToNodeNames[ip]); length != 1 { + t.Errorf("incorrect iptonodenames length: %d, expected 1", length) + t.Fail() + } + name3 := "somename2.with.a.fqdn.net" + AddIPToNodeName(ip, name3, ts1) + if length := len(db.IPToNodeNames[ip]); length != 2 { + t.Errorf("incorrect iptonodenames length: %d, expected 2", length) + t.Fail() + } +} + +func testMostAppropriateValueFromTS(t *testing.T) { + tests := []struct { + inputunits []translationUnit + inputts time.Time + expected string + }{ + { + inputunits: []translationUnit{ + translationUnit{Value: "value1", Timestamp: time.Date(2001, time.January, 1, 1, 1, 1, 0, time.UTC)}, + translationUnit{Value: "value2", Timestamp: time.Date(2001, time.January, 1, 3, 1, 1, 0, time.UTC)}, + }, + inputts: time.Date(2001, time.January, 1, 2, 1, 1, 0, time.UTC), + expected: "value1", + }, + { + inputunits: []translationUnit{ + translationUnit{Value: "value1", Timestamp: time.Date(2001, time.January, 1, 1, 1, 1, 0, time.UTC)}, + translationUnit{Value: "value2", Timestamp: time.Date(2001, time.January, 1, 3, 1, 1, 0, time.UTC)}, + }, + inputts: time.Date(2001, time.January, 1, 4, 1, 1, 0, time.UTC), + expected: "value2", + }, + { + inputunits: []translationUnit{ + translationUnit{Value: "value1", Timestamp: time.Date(2001, time.January, 1, 1, 1, 1, 0, time.UTC)}, + translationUnit{Value: "value2", Timestamp: time.Date(2001, time.January, 1, 3, 1, 1, 0, time.UTC)}, + translationUnit{Value: "value3", Timestamp: time.Date(2001, time.January, 1, 5, 1, 1, 0, time.UTC)}, + }, + inputts: time.Date(2001, time.January, 1, 4, 1, 1, 0, time.UTC), + expected: "value2", + }, + { + inputunits: []translationUnit{ + translationUnit{Value: "value1", Timestamp: time.Date(2001, time.January, 1, 1, 1, 1, 0, time.UTC)}, + translationUnit{Value: "value2", Timestamp: time.Date(2001, time.January, 1, 3, 1, 1, 0, time.UTC)}, + }, + inputts: time.Date(2001, time.January, 1, 0, 1, 1, 0, time.UTC), + expected: "value1", + }, + } + + for i, test := range tests { + out := mostAppropriateValueFromTS(test.inputunits, test.inputts) + if out != test.expected { + t.Errorf("test %d, expected: %s, got: %s", i, test.expected, out) + } + } +}