From e2f1df9add0d3f52875c9ac61653d943a3fda8b2 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 23 Aug 2025 08:28:38 +0200 Subject: [PATCH] tests: replace godebug by go-cmp for structure diffs go-cmp is stricter and allow to catch more problems. Moreover, the output is a bit nicer. --- cmd/config_test.go | 179 ++++++---- common/clickhousedb/root_test.go | 4 +- common/helpers/intern/intern_test.go | 15 +- common/helpers/mapstructure_test.go | 4 +- common/helpers/subnetmap_test.go | 119 +++++-- common/helpers/tests.go | 2 +- common/helpers/tests_config.go | 3 +- common/helpers/tests_diff.go | 83 +---- common/helpers/tests_http.go | 20 +- common/helpers/tests_subnetmap.go | 23 ++ common/helpers/yaml/unmarshal_test.go | 16 +- .../clickhouse => common/pb}/tests.go | 9 +- common/remotedatasource/config_test.go | 4 +- common/remotedatasource/root_test.go | 2 +- common/reporter/healthcheck_test.go | 6 +- common/schema/clickhouse.go | 6 +- common/schema/clickhouse_test.go | 90 ++--- common/schema/definition_test.go | 9 +- common/schema/insert_test.go | 20 +- common/schema/tests.go | 6 +- console/filter/parser_test.go | 2 - console/filter/tests.go | 16 + console/line_test.go | 2 + console/query/column.go | 5 + console/query/column_test.go | 6 +- console/query/filter.go | 5 + console/tests.go | 7 + demoexporter/flows/nfdata_test.go | 42 +-- demoexporter/snmp/server_test.go | 4 +- go.mod | 3 +- inlet/flow/input/file/root_test.go | 2 +- orchestrator/clickhouse/config_test.go | 39 ++- outlet/core/config.go | 4 +- outlet/core/enricher_test.go | 76 ++--- outlet/core/root_test.go | 54 +-- outlet/flow/decoder/gob/root_test.go | 6 +- outlet/flow/decoder/helpers_test.go | 36 +- outlet/flow/decoder/netflow/root_test.go | 268 +++++++-------- outlet/flow/decoder/sflow/root_test.go | 322 +++++++++--------- outlet/metadata/cache_test.go | 20 +- .../metadata/provider/gnmi/collector_test.go | 6 +- outlet/metadata/provider/snmp/tests.go | 5 +- outlet/metadata/provider/static/tests.go | 5 +- outlet/routing/provider/bmp/rib_test.go | 2 +- outlet/routing/provider/bmp/tests.go | 5 +- 45 files changed, 852 insertions(+), 710 deletions(-) create mode 100644 common/helpers/tests_subnetmap.go rename {orchestrator/clickhouse => common/pb}/tests.go (55%) create mode 100644 console/filter/tests.go diff --git a/cmd/config_test.go b/cmd/config_test.go index 40ef643d..67d6dbd9 100644 --- a/cmd/config_test.go +++ b/cmd/config_test.go @@ -158,13 +158,13 @@ module2: if err := yaml.Unmarshal(out.Bytes(), &gotRaw); err != nil { t.Fatalf("Unmarshal() error:\n%+v", err) } - expectedRaw := gin.H{ - "module1": gin.H{ + expectedRaw := map[string]gin.H{ + "module1": { "listen": "127.0.0.1:8080", "topic": "flows", "workers": 100, }, - "module2": gin.H{ + "module2": { "stuff": "bye", "details": gin.H{ "workers": 5, @@ -356,7 +356,7 @@ invalid key "unused"`); diff != "" { } func TestDefaultInSlice(t *testing.T) { - try := func(t *testing.T, parse func(cmd.ConfigRelatedOptions, *bytes.Buffer) any) { + try := func(t *testing.T, parse func(cmd.ConfigRelatedOptions, *bytes.Buffer) any, expected any) { // Configuration file config := `--- modules: @@ -375,60 +375,6 @@ modules: out := bytes.NewBuffer([]byte{}) parsed := parse(c, out) - // Expected configuration - expected := map[string][]dummyConfiguration{ - "Modules": { - { - Module1: dummyModule1Configuration{ - Listen: "127.0.0.1:8080", - Topic: "flows1", - Workers: 100, - }, - Module2: dummyModule2Configuration{ - MoreDetails: MoreDetails{ - Stuff: "hello", - }, - Details: dummyModule2DetailsConfiguration{ - Workers: 1, - IntervalValue: time.Minute, - }, - Elements: []dummyModule2ElementsConfiguration{ - { - Name: "el1", - Gauge: 10, - }, { - Name: "el2", - Gauge: 11, - }, - }, - }, - }, { - Module1: dummyModule1Configuration{ - Listen: "127.0.0.1:8080", - Topic: "flows2", - Workers: 100, - }, - Module2: dummyModule2Configuration{ - MoreDetails: MoreDetails{ - Stuff: "hello", - }, - Details: dummyModule2DetailsConfiguration{ - Workers: 1, - IntervalValue: time.Minute, - }, - Elements: []dummyModule2ElementsConfiguration{ - { - Name: "el1", - Gauge: 10, - }, { - Name: "el2", - Gauge: 11, - }, - }, - }, - }, - }, - } if diff := helpers.Diff(parsed, expected); diff != "" { t.Errorf("Parse() (-got, +want):\n%s", diff) } @@ -442,7 +388,64 @@ modules: t.Fatalf("Parse() error:\n%+v", err) } return parsed - }) + }, + // Expected configuration + struct { + Modules []dummyConfiguration + }{ + Modules: []dummyConfiguration{ + { + Module1: dummyModule1Configuration{ + Listen: "127.0.0.1:8080", + Topic: "flows1", + Workers: 100, + }, + Module2: dummyModule2Configuration{ + MoreDetails: MoreDetails{ + Stuff: "hello", + }, + Details: dummyModule2DetailsConfiguration{ + Workers: 1, + IntervalValue: time.Minute, + }, + Elements: []dummyModule2ElementsConfiguration{ + { + Name: "el1", + Gauge: 10, + }, { + Name: "el2", + Gauge: 11, + }, + }, + }, + }, + { + Module1: dummyModule1Configuration{ + Listen: "127.0.0.1:8080", + Topic: "flows2", + Workers: 100, + }, + Module2: dummyModule2Configuration{ + MoreDetails: MoreDetails{ + Stuff: "hello", + }, + Details: dummyModule2DetailsConfiguration{ + Workers: 1, + IntervalValue: time.Minute, + }, + Elements: []dummyModule2ElementsConfiguration{ + { + Name: "el1", + Gauge: 10, + }, { + Name: "el2", + Gauge: 11, + }, + }, + }, + }, + }, + }) }) t.Run("with pointer", func(t *testing.T) { try(t, func(c cmd.ConfigRelatedOptions, out *bytes.Buffer) any { @@ -453,7 +456,63 @@ modules: t.Fatalf("Parse() error:\n%+v", err) } return parsed - }) + }, + struct { + Modules []*dummyConfiguration + }{ + Modules: []*dummyConfiguration{ + { + Module1: dummyModule1Configuration{ + Listen: "127.0.0.1:8080", + Topic: "flows1", + Workers: 100, + }, + Module2: dummyModule2Configuration{ + MoreDetails: MoreDetails{ + Stuff: "hello", + }, + Details: dummyModule2DetailsConfiguration{ + Workers: 1, + IntervalValue: time.Minute, + }, + Elements: []dummyModule2ElementsConfiguration{ + { + Name: "el1", + Gauge: 10, + }, { + Name: "el2", + Gauge: 11, + }, + }, + }, + }, + { + Module1: dummyModule1Configuration{ + Listen: "127.0.0.1:8080", + Topic: "flows2", + Workers: 100, + }, + Module2: dummyModule2Configuration{ + MoreDetails: MoreDetails{ + Stuff: "hello", + }, + Details: dummyModule2DetailsConfiguration{ + Workers: 1, + IntervalValue: time.Minute, + }, + Elements: []dummyModule2ElementsConfiguration{ + { + Name: "el1", + Gauge: 10, + }, { + Name: "el2", + Gauge: 11, + }, + }, + }, + }, + }, + }) }) } diff --git a/common/clickhousedb/root_test.go b/common/clickhousedb/root_test.go index 77934df5..64a91b02 100644 --- a/common/clickhousedb/root_test.go +++ b/common/clickhousedb/root_test.go @@ -130,8 +130,8 @@ func TestRealClickHouse(t *testing.T) { } expected := []struct { - N uint64 - M uint64 + N uint64 `ch:"n"` + M uint64 `ch:"m"` }{ {0, 1}, {1, 2}, diff --git a/common/helpers/intern/intern_test.go b/common/helpers/intern/intern_test.go index 8a4f174b..eb48e2dc 100644 --- a/common/helpers/intern/intern_test.go +++ b/common/helpers/intern/intern_test.go @@ -7,6 +7,8 @@ import ( "testing" "akvorado/common/helpers" + + "github.com/google/go-cmp/cmp/cmpopts" ) type likeInt int @@ -72,6 +74,7 @@ func TestPutCollision(t *testing.T) { func TestTake(t *testing.T) { p := NewPool[likeInt]() + diffOpt := cmpopts.EquateComparable(internValue[likeInt]{}) val1 := likeInt(10) ref1 := p.Put(val1) @@ -91,7 +94,7 @@ func TestTake(t *testing.T) { {value: 22, refCount: 1, previous: 2, next: 4}, {value: 32, refCount: 1, previous: 3}, } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } @@ -104,7 +107,7 @@ func TestTake(t *testing.T) { {value: 22, refCount: 0, previous: 2, next: 4}, // free {value: 32, refCount: 1, previous: 2}, } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } @@ -120,7 +123,7 @@ func TestTake(t *testing.T) { {value: 42, refCount: 1, previous: 4}, {value: 32, refCount: 1, previous: 2, next: 3}, } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } @@ -133,7 +136,7 @@ func TestTake(t *testing.T) { {value: 42, refCount: 1, previous: 4}, {value: 32, refCount: 1, next: 3}, } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } @@ -146,7 +149,7 @@ func TestTake(t *testing.T) { {value: 42, refCount: 1}, {value: 32, refCount: 0, next: 3}, // free } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } @@ -159,7 +162,7 @@ func TestTake(t *testing.T) { {value: 42, refCount: 0}, // free {value: 32, refCount: 0, next: 3}, // free } - if diff := helpers.Diff(p.values, expectedValues, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(p.values, expectedValues, diffOpt); diff != "" { t.Fatalf("p.values (-got, +want):\n%s", diff) } diff --git a/common/helpers/mapstructure_test.go b/common/helpers/mapstructure_test.go index 2352ad00..42bdc6c6 100644 --- a/common/helpers/mapstructure_test.go +++ b/common/helpers/mapstructure_test.go @@ -236,7 +236,7 @@ func TestParametrizedConfig(t *testing.T) { Expected: OuterConfiguration{ AA: "a1", BB: "b1", - Config: InnerConfigurationType1{ + Config: &InnerConfigurationType1{ CC: "c1", DD: "d1", }, @@ -256,7 +256,7 @@ func TestParametrizedConfig(t *testing.T) { Expected: OuterConfiguration{ AA: "a2", BB: "b2", - Config: InnerConfigurationType2{ + Config: &InnerConfigurationType2{ CC: "c2", EE: "e2", }, diff --git a/common/helpers/subnetmap_test.go b/common/helpers/subnetmap_test.go index c40794cf..2d126530 100644 --- a/common/helpers/subnetmap_test.go +++ b/common/helpers/subnetmap_test.go @@ -6,6 +6,7 @@ package helpers_test import ( "net/netip" "slices" + "strings" "testing" "github.com/gin-gonic/gin" @@ -19,6 +20,7 @@ import ( func TestSubnetMapUnmarshalHook(t *testing.T) { var nilMap map[string]string cases := []struct { + Pos helpers.Pos Description string Input any Tests map[string]string @@ -26,20 +28,24 @@ func TestSubnetMapUnmarshalHook(t *testing.T) { YAML any }{ { + Pos: helpers.Mark(), Description: "nil", Input: nilMap, Tests: map[string]string{ "::ffff:203.0.113.1": "", }, + YAML: map[string]string{}, }, { + Pos: helpers.Mark(), Description: "empty", - Input: gin.H{}, + Input: map[string]string{}, Tests: map[string]string{ "::ffff:203.0.113.1": "", }, }, { + Pos: helpers.Mark(), Description: "IPv4 subnet", - Input: gin.H{"203.0.113.0/24": "customer1"}, + Input: map[string]string{"203.0.113.0/24": "customer1"}, Tests: map[string]string{ "::ffff:203.0.113.18": "customer1", "::ffff:203.0.113.16": "customer1", @@ -49,59 +55,69 @@ func TestSubnetMapUnmarshalHook(t *testing.T) { "2001:db8:1::12": "", }, }, { + Pos: helpers.Mark(), Description: "IPv4 IP", - Input: gin.H{"203.0.113.1": "customer1"}, + Input: map[string]string{"203.0.113.1": "customer1"}, Tests: map[string]string{ "::ffff:203.0.113.1": "customer1", "2001:db8:1::12": "", }, - YAML: gin.H{"203.0.113.1/32": "customer1"}, + YAML: map[string]string{"203.0.113.1/32": "customer1"}, }, { + Pos: helpers.Mark(), Description: "IPv6 subnet", - Input: gin.H{"2001:db8:1::/64": "customer2"}, + Input: map[string]string{"2001:db8:1::/64": "customer2"}, Tests: map[string]string{ "2001:db8:1::1": "customer2", "2001:db8:1::2": "customer2", "2001:db8:2::2": "", }, }, { + Pos: helpers.Mark(), Description: "IPv6-mapped-IPv4 subnet", - Input: gin.H{"::ffff:203.0.113.0/120": "customer2"}, + Input: map[string]string{"::ffff:203.0.113.0/120": "customer2"}, Tests: map[string]string{ "::ffff:203.0.113.10": "customer2", "::ffff:203.0.112.10": "", }, - YAML: gin.H{"203.0.113.0/24": "customer2"}, + YAML: map[string]string{"203.0.113.0/24": "customer2"}, }, { + Pos: helpers.Mark(), Description: "IPv6 IP", - Input: gin.H{"2001:db8:1::1": "customer2"}, + Input: map[string]string{"2001:db8:1::1": "customer2"}, Tests: map[string]string{ "2001:db8:1::1": "customer2", "2001:db8:1::2": "", "2001:db8:2::2": "", }, - YAML: gin.H{"2001:db8:1::1/128": "customer2"}, + YAML: map[string]string{"2001:db8:1::1/128": "customer2"}, }, { + Pos: helpers.Mark(), Description: "Invalid subnet (1)", - Input: gin.H{"192.0.2.1/38": "customer"}, + Input: map[string]string{"192.0.2.1/38": "customer"}, Error: true, }, { + Pos: helpers.Mark(), Description: "Invalid subnet (2)", - Input: gin.H{"192.0.2.1/255.0.255.0": "customer"}, + Input: map[string]string{"192.0.2.1/255.0.255.0": "customer"}, Error: true, }, { + Pos: helpers.Mark(), Description: "Invalid subnet (3)", - Input: gin.H{"2001:db8::/1000": "customer"}, + Input: map[string]string{"2001:db8::/1000": "customer"}, Error: true, }, { + Pos: helpers.Mark(), Description: "Invalid IP", - Input: gin.H{"200.33.300.1": "customer"}, + Input: map[string]string{"200.33.300.1": "customer"}, Error: true, }, { + Pos: helpers.Mark(), Description: "Random key", - Input: gin.H{"kfgdjgkfj": "customer"}, + Input: map[string]string{"kfgdjgkfj": "customer"}, Error: true, }, { + Pos: helpers.Mark(), Description: "Single value", Input: "customer", Tests: map[string]string{ @@ -115,11 +131,10 @@ func TestSubnetMapUnmarshalHook(t *testing.T) { } for _, tc := range cases { if tc.YAML == nil { - if tc.Error { - tc.YAML = map[string]string{} - } else { - tc.YAML = tc.Input - } + tc.YAML = tc.Input + } + if tc.Tests == nil { + tc.Tests = map[string]string{} } t.Run(tc.Description, func(t *testing.T) { var tree helpers.SubnetMap[string] @@ -134,9 +149,11 @@ func TestSubnetMapUnmarshalHook(t *testing.T) { } err = decoder.Decode(tc.Input) if err != nil && !tc.Error { - t.Fatalf("Decode() error:\n%+v", err) + t.Fatalf("%sDecode() error:\n%+v", tc.Pos, err) } else if err == nil && tc.Error { - t.Fatal("Decode() did not return an error") + t.Fatalf("%sDecode() did not return an error", tc.Pos) + } else if tc.Error { + return } got := map[string]string{} for k := range tc.Tests { @@ -144,20 +161,20 @@ func TestSubnetMapUnmarshalHook(t *testing.T) { got[k] = v } if diff := helpers.Diff(got, tc.Tests); diff != "" { - t.Fatalf("Decode() (-got, +want):\n%s", diff) + t.Fatalf("%sDecode() (-got, +want):\n%s", tc.Pos, diff) } // Try to unmarshal with YAML buf, err := yaml.Marshal(tree) if err != nil { - t.Fatalf("yaml.Marshal() error:\n%+v", err) + t.Fatalf("%syaml.Marshal() error:\n%+v", tc.Pos, err) } got = map[string]string{} if err := yaml.Unmarshal(buf, &got); err != nil { - t.Fatalf("yaml.Unmarshal() error:\n%+v", err) + t.Fatalf("%syaml.Unmarshal() error:\n%+v", tc.Pos, err) } if diff := helpers.Diff(got, tc.YAML); diff != "" { - t.Fatalf("MarshalYAML() (-got, +want):\n%s", diff) + t.Fatalf("%sMarshalYAML() (-got, +want):\n%s", tc.Pos, diff) } }) } @@ -171,7 +188,7 @@ func TestSubnetMapUnmarshalHookWithMapValue(t *testing.T) { cases := []struct { Pos helpers.Pos Input gin.H - Expected gin.H + Expected any }{ { Pos: helpers.Mark(), @@ -179,10 +196,10 @@ func TestSubnetMapUnmarshalHookWithMapValue(t *testing.T) { "blip": "some", "blop": "thing", }, - Expected: gin.H{ - "::/0": gin.H{ - "Blip": "some", - "Blop": "thing", + Expected: map[string]SomeStruct{ + "::/0": { + Blip: "some", + Blop: "thing", }, }, }, { @@ -197,14 +214,14 @@ func TestSubnetMapUnmarshalHookWithMapValue(t *testing.T) { "blop": "stuff", }, }, - Expected: gin.H{ - "::/0": gin.H{ - "Blip": "some", - "Blop": "thing", + Expected: map[string]SomeStruct{ + "::/0": { + Blip: "some", + Blop: "thing", }, - "203.0.113.14/32": gin.H{ - "Blip": "other", - "Blop": "stuff", + "203.0.113.14/32": { + Blip: "other", + Blop: "stuff", }, }, }, @@ -717,3 +734,31 @@ func TestSubnetMapAllMaybeSorted(t *testing.T) { } }) } + +func TestSubnetmapDiff(t *testing.T) { + got := helpers.MustNewSubnetMap(map[string]string{ + "2001:db8::/64": "hello", + "::ffff:192.0.2.0/120": "bye", + }) + expected := helpers.MustNewSubnetMap(map[string]string{ + "2001:db8::/64": "hello", + "::ffff:192.0.2.0/120": "bye", + }) + + if diff := helpers.Diff(got, expected); diff != "" { + t.Fatalf("Diff():\n%+v", diff) + } + + got.Set(netip.MustParsePrefix("2001:db8:1::/64"), "bye") + diffGot := helpers.Diff(got, expected) + diffGot = strings.ReplaceAll(diffGot, "\u00a0", " ") + diffExpected := ` (*helpers.SubnetMap[string])(Inverse(subnetmap.Transform, map[string]string{ + "192.0.2.0/24": "bye", +- "2001:db8:1::/64": "bye", + "2001:db8::/64": "hello", + })) +` + if diff := helpers.Diff(diffGot, diffExpected); diff != "" { + t.Fatalf("Diff() (-got, +want):\n%+v", diff) + } +} diff --git a/common/helpers/tests.go b/common/helpers/tests.go index 0cebe682..2caec5be 100644 --- a/common/helpers/tests.go +++ b/common/helpers/tests.go @@ -141,7 +141,7 @@ func Mark() Pos { // String returns a textual representation of a Pos. func (p Pos) String() string { if p.file != "" { - return fmt.Sprintf("%s:%d", p.file, p.line) + return fmt.Sprintf("%s:%d: ", p.file, p.line) } return "" } diff --git a/common/helpers/tests_config.go b/common/helpers/tests_config.go index 07a59d2e..cd40d599 100644 --- a/common/helpers/tests_config.go +++ b/common/helpers/tests_config.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/go-viper/mapstructure/v2" + "github.com/google/go-cmp/cmp" "akvorado/common/helpers/yaml" ) @@ -28,7 +29,7 @@ type ConfigurationDecodeCases []struct { } // TestConfigurationDecode helps decoding configuration. It also test decoding from YAML. -func TestConfigurationDecode(t *testing.T, cases ConfigurationDecodeCases, options ...DiffOption) { +func TestConfigurationDecode(t *testing.T, cases ConfigurationDecodeCases, options ...cmp.Option) { t.Helper() for _, tc := range cases { for _, fromYAML := range []bool{false, true} { diff --git a/common/helpers/tests_diff.go b/common/helpers/tests_diff.go index d33747fc..3931f217 100644 --- a/common/helpers/tests_diff.go +++ b/common/helpers/tests_diff.go @@ -6,85 +6,28 @@ package helpers import ( - "fmt" - "net" "net/netip" - "reflect" - "time" - "github.com/kylelemons/godebug/pretty" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" ) -var prettyC = pretty.Config{ - Diffable: true, - PrintStringers: false, - SkipZeroFields: true, - IncludeUnexported: false, -} +var diffCmpOptions cmp.Options -func formatByte(v any) string { - return fmt.Sprintf("0x%x", v) -} - -func defaultPrettyFormatters() map[reflect.Type]any { - result := map[reflect.Type]any{ - reflect.TypeOf(net.IP{}): fmt.Sprint, - reflect.TypeOf(netip.Addr{}): fmt.Sprint, - reflect.TypeOf(netip.Prefix{}): fmt.Sprint, - reflect.TypeOf(time.Time{}): fmt.Sprint, - reflect.TypeOf(SubnetMap[string]{}): fmt.Sprint, - reflect.TypeOf(SubnetMap[uint]{}): fmt.Sprint, - reflect.TypeOf(SubnetMap[uint16]{}): fmt.Sprint, - reflect.TypeOf(byte(0)): formatByte, - } - for t, fn := range nonDefaultPrettyFormatters { - result[t] = fn - } - return result -} - -var nonDefaultPrettyFormatters = map[reflect.Type]any{} - -// AddPrettyFormatter add a global pretty formatter. We cannot put everything in -// the default map due to cycles. -func AddPrettyFormatter(t reflect.Type, fn any) { - nonDefaultPrettyFormatters[t] = fn -} - -// DiffOption changes the behavior of the Diff function. -type DiffOption struct { - kind int - // When this is a formatter - t reflect.Type - fn any +// RegisterCmpOption adds an option that will be used in all call to Diff(). +func RegisterCmpOption(option cmp.Option) { + diffCmpOptions = append(diffCmpOptions, option) } // Diff return a diff of two objects. If no diff, an empty string is // returned. -func Diff(a, b any, options ...DiffOption) string { - prettyC := prettyC - prettyC.Formatter = defaultPrettyFormatters() - for _, option := range options { - switch option.kind { - case DiffUnexported.kind: - prettyC.IncludeUnexported = true - case DiffZero.kind: - prettyC.SkipZeroFields = false - case DiffFormatter(nil, nil).kind: - prettyC.Formatter[option.t] = option.fn - } - } - return prettyC.Compare(a, b) +func Diff(a, b any, options ...cmp.Option) string { + options = append(options, diffCmpOptions...) + return cmp.Diff(a, b, options...) } -var ( - // DiffUnexported will display diff of unexported fields too. - DiffUnexported = DiffOption{kind: 1} - // DiffZero will include zero-field in diff - DiffZero = DiffOption{kind: 2} -) - -// DiffFormatter adds a new formatter -func DiffFormatter(t reflect.Type, fn any) DiffOption { - return DiffOption{kind: 3, t: t, fn: fn} +func init() { + RegisterCmpOption(cmpopts.EquateComparable(netip.Addr{})) + RegisterCmpOption(cmpopts.EquateComparable(netip.Prefix{})) + RegisterCmpOption(cmpopts.EquateErrors()) } diff --git a/common/helpers/tests_http.go b/common/helpers/tests_http.go index 08d2d28a..bcd9dcc9 100644 --- a/common/helpers/tests_http.go +++ b/common/helpers/tests_http.go @@ -24,12 +24,12 @@ type HTTPEndpointCases []struct { Method string URL string Header http.Header - JSONInput any + JSONInput gin.H ContentType string StatusCode int FirstLines []string - JSONOutput any + JSONOutput gin.H } // TestHTTPEndpoints test a few HTTP endpoints @@ -108,6 +108,9 @@ func TestHTTPEndpoints(t *testing.T, serverAddr net.Addr, cases HTTPEndpointCase for reader.Scan() && len(got) < len(tc.FirstLines) { got = append(got, reader.Text()) } + if tc.FirstLines == nil { + tc.FirstLines = []string{} + } if diff := Diff(got, tc.FirstLines); diff != "" { t.Errorf("%s%s %s (-got, +want):\n%s", tc.Pos, tc.Method, tc.URL, diff) } @@ -117,7 +120,18 @@ func TestHTTPEndpoints(t *testing.T, serverAddr net.Addr, cases HTTPEndpointCase if err := decoder.Decode(&got); err != nil { t.Fatalf("%s%s %s:\n%+v", tc.Pos, tc.Method, tc.URL, err) } - if diff := Diff(got, tc.JSONOutput); diff != "" { + + // Encode/decode expected to compare JSON stuff + var expected gin.H + expectedBytes, err := json.Marshal(tc.JSONOutput) + if err != nil { + t.Fatalf("json.Marshal() error:\n%+v", err) + } + if err := json.Unmarshal(expectedBytes, &expected); err != nil { + t.Fatalf("json.Unmarshal() error:\n%+v", err) + } + + if diff := Diff(got, expected); diff != "" { t.Fatalf("%s%s %s (-got, +want):\n%s", tc.Pos, tc.Method, tc.URL, diff) } } diff --git a/common/helpers/tests_subnetmap.go b/common/helpers/tests_subnetmap.go new file mode 100644 index 00000000..9951966f --- /dev/null +++ b/common/helpers/tests_subnetmap.go @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2022 Free Mobile +// SPDX-License-Identifier: AGPL-3.0-only + +//go:build !release + +package helpers + +import "github.com/google/go-cmp/cmp" + +// RegisterSubnetMapCmp register a subnetmap to work with cmp.Equal()/cmp.Diff() +func RegisterSubnetMapCmp[T any]() { + RegisterCmpOption( + cmp.Transformer("subnetmap.Transform", + func(sm *SubnetMap[T]) map[string]T { + return sm.ToMap() + })) +} + +func init() { + RegisterSubnetMapCmp[uint16]() + RegisterSubnetMapCmp[uint]() + RegisterSubnetMapCmp[string]() +} diff --git a/common/helpers/yaml/unmarshal_test.go b/common/helpers/yaml/unmarshal_test.go index 49133e1e..65434a26 100644 --- a/common/helpers/yaml/unmarshal_test.go +++ b/common/helpers/yaml/unmarshal_test.go @@ -9,8 +9,6 @@ import ( "akvorado/common/helpers" "akvorado/common/helpers/yaml" - - "github.com/gin-gonic/gin" ) func TestUnmarshalWithIn(t *testing.T) { @@ -19,14 +17,14 @@ func TestUnmarshalWithIn(t *testing.T) { if err := yaml.UnmarshalWithInclude(fsys, "base.yaml", &got); err != nil { t.Fatalf("UnmarshalWithInclude() error:\n%+v", err) } - expected := gin.H{ - "file1": gin.H{"name": "1.yaml"}, - "file2": gin.H{"name": "2.yaml"}, - "nested": gin.H{ - "file1": gin.H{"name": "1.yaml"}, + expected := map[string]any{ + "file1": map[string]any{"name": "1.yaml"}, + "file2": map[string]any{"name": "2.yaml"}, + "nested": map[string]any{ + "file1": map[string]any{"name": "1.yaml"}, }, - "list1": []string{"el1", "el2", "el3"}, - "list2": []any{gin.H{ + "list1": []any{"el1", "el2", "el3"}, + "list2": []any{map[string]any{ "protocol": "tcp", "size": 1300, }, "el2", "el3"}, diff --git a/orchestrator/clickhouse/tests.go b/common/pb/tests.go similarity index 55% rename from orchestrator/clickhouse/tests.go rename to common/pb/tests.go index ff5d1697..2572718c 100644 --- a/orchestrator/clickhouse/tests.go +++ b/common/pb/tests.go @@ -3,15 +3,14 @@ //go:build !release -package clickhouse +package pb import ( - "fmt" - "reflect" - "akvorado/common/helpers" + + "github.com/google/go-cmp/cmp/cmpopts" ) func init() { - helpers.AddPrettyFormatter(reflect.TypeOf(helpers.SubnetMap[NetworkAttributes]{}), fmt.Sprint) + helpers.RegisterCmpOption(cmpopts.IgnoreUnexported(RawFlow{})) } diff --git a/common/remotedatasource/config_test.go b/common/remotedatasource/config_test.go index 8a82903a..142ea611 100644 --- a/common/remotedatasource/config_test.go +++ b/common/remotedatasource/config_test.go @@ -4,8 +4,6 @@ package remotedatasource import ( - "fmt" - "reflect" "testing" "time" @@ -100,5 +98,5 @@ func TestSourceDecode(t *testing.T) { }, Error: true, }, - }, helpers.DiffFormatter(reflect.TypeOf(TransformQuery{}), fmt.Sprint), helpers.DiffZero) + }) } diff --git a/common/remotedatasource/root_test.go b/common/remotedatasource/root_test.go index 1f00dbbb..37436b35 100644 --- a/common/remotedatasource/root_test.go +++ b/common/remotedatasource/root_test.go @@ -136,7 +136,7 @@ func TestSource(t *testing.T) { handler := remoteDataHandler{ data: []remoteData{}, } - var expected []remoteData + expected := []remoteData{} handler.fetcher, _ = New[remoteData](r, handler.UpdateData, "test", config) handler.fetcher.Start() diff --git a/common/reporter/healthcheck_test.go b/common/reporter/healthcheck_test.go index 86f08d7a..10c12fb4 100644 --- a/common/reporter/healthcheck_test.go +++ b/common/reporter/healthcheck_test.go @@ -139,12 +139,12 @@ func TestHealthcheckHTTPHandler(t *testing.T) { } expected := gin.H{ "status": "error", - "details": gin.H{ - "hc1": map[string]string{ + "details": map[string]any{ + "hc1": map[string]any{ "status": "ok", "reason": "all well", }, - "hc2": map[string]string{ + "hc2": map[string]any{ "status": "error", "reason": "trying to be better", }, diff --git a/common/schema/clickhouse.go b/common/schema/clickhouse.go index 1dcd428d..d2415847 100644 --- a/common/schema/clickhouse.go +++ b/common/schema/clickhouse.go @@ -161,19 +161,23 @@ func (bf *FlowMessage) AppendUint(columnKey ColumnKey, value uint64) { switch col := col.(type) { case *proto.ColUInt64: col.Append(value) + bf.appendDebug(columnKey, value) case *proto.ColUInt32: col.Append(uint32(value)) + bf.appendDebug(columnKey, uint32(value)) case *proto.ColUInt16: col.Append(uint16(value)) + bf.appendDebug(columnKey, uint16(value)) case *proto.ColUInt8: col.Append(uint8(value)) + bf.appendDebug(columnKey, uint8(value)) case *proto.ColEnum8: col.Append(proto.Enum8(value)) + bf.appendDebug(columnKey, uint8(value)) default: panic(fmt.Sprintf("unhandled uint type %q", col.Type())) } bf.batch.columnSet.Set(uint(columnKey)) - bf.appendDebug(columnKey, value) } // AppendString adds a String value to the provided column diff --git a/common/schema/clickhouse_test.go b/common/schema/clickhouse_test.go index 7fa91810..b97ea134 100644 --- a/common/schema/clickhouse_test.go +++ b/common/schema/clickhouse_test.go @@ -6,11 +6,13 @@ package schema import ( "net/netip" "slices" + "strings" "testing" "akvorado/common/helpers" "github.com/ClickHouse/ch-go/proto" + "github.com/google/go-cmp/cmp" ) func TestAppendDefault(t *testing.T) { @@ -50,10 +52,10 @@ func TestAppendBasics(t *testing.T) { bf.AppendUint(ColumnPackets, 200) expected := map[ColumnKey]any{ - ColumnTimeReceived: 1000, - ColumnSamplingRate: 20000, - ColumnDstAS: 65000, - ColumnPackets: 100, + ColumnTimeReceived: uint32(1000), + ColumnSamplingRate: uint64(20000), + ColumnDstAS: uint32(65000), + ColumnPackets: uint64(100), } got := bf.OtherColumns if diff := helpers.Diff(got, expected); diff != "" { @@ -94,7 +96,7 @@ func TestAppendArrayUInt32Columns(t *testing.T) { Offsets: proto.ColUInt64{3, 6}, Data: &proto.ColUInt32{65400, 65500, 65001, 65403, 65503, 65003}, } - if diff := helpers.Diff(got, expected); diff != "" { + if diff := helpers.Diff(got, &expected); diff != "" { t.Errorf("AppendArrayUInt32 (-got, +want):\n%s", diff) } } @@ -122,7 +124,7 @@ func TestAppendArrayUInt128Columns(t *testing.T) { {High: (65401 << 32) + 100, Low: 201}, }, } - if diff := helpers.Diff(got, expected); diff != "" { + if diff := helpers.Diff(got, &expected); diff != "" { t.Errorf("AppendArrayUInt128 (-got, +want):\n%s", diff) } } @@ -142,10 +144,10 @@ func TestUndoUInt64(t *testing.T) { expectedBytes := proto.ColUInt64{100} expectedPackets := proto.ColUInt64{200} - if diff := helpers.Diff(bytesCol, expectedBytes); diff != "" { + if diff := helpers.Diff(bytesCol, &expectedBytes); diff != "" { t.Errorf("Initial bytes column state (-got, +want):\n%s", diff) } - if diff := helpers.Diff(packetsCol, expectedPackets); diff != "" { + if diff := helpers.Diff(packetsCol, &expectedPackets); diff != "" { t.Errorf("Initial packets column state (-got, +want):\n%s", diff) } @@ -155,10 +157,10 @@ func TestUndoUInt64(t *testing.T) { expectedBytesAfter := proto.ColUInt64{} expectedPacketsAfter := proto.ColUInt64{} - if diff := helpers.Diff(bytesCol, expectedBytesAfter); diff != "" { + if diff := helpers.Diff(bytesCol, &expectedBytesAfter); diff != "" { t.Errorf("Bytes column after undo (-got, +want):\n%s", diff) } - if diff := helpers.Diff(packetsCol, expectedPacketsAfter); diff != "" { + if diff := helpers.Diff(packetsCol, &expectedPacketsAfter); diff != "" { t.Errorf("Packets column after undo (-got, +want):\n%s", diff) } } @@ -178,10 +180,10 @@ func TestUndoUInt32(t *testing.T) { expectedSrc := proto.ColUInt32{65001} expectedDst := proto.ColUInt32{65002} - if diff := helpers.Diff(srcCol, expectedSrc); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrc); diff != "" { t.Errorf("Initial SrcAS column state (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDst); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDst); diff != "" { t.Errorf("Initial DstAS column state (-got, +want):\n%s", diff) } @@ -191,10 +193,10 @@ func TestUndoUInt32(t *testing.T) { expectedSrcAfter := proto.ColUInt32{} expectedDstAfter := proto.ColUInt32{} - if diff := helpers.Diff(srcCol, expectedSrcAfter); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrcAfter); diff != "" { t.Errorf("SrcAS column after undo (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDstAfter); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDstAfter); diff != "" { t.Errorf("DstAS column after undo (-got, +want):\n%s", diff) } } @@ -214,10 +216,10 @@ func TestUndoUInt16(t *testing.T) { expectedSrc := proto.ColUInt16{80} expectedDst := proto.ColUInt16{443} - if diff := helpers.Diff(srcCol, expectedSrc); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrc); diff != "" { t.Errorf("Initial SrcPort column state (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDst); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDst); diff != "" { t.Errorf("Initial DstPort column state (-got, +want):\n%s", diff) } @@ -227,10 +229,10 @@ func TestUndoUInt16(t *testing.T) { expectedSrcAfter := proto.ColUInt16{} expectedDstAfter := proto.ColUInt16{} - if diff := helpers.Diff(srcCol, expectedSrcAfter); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrcAfter); diff != "" { t.Errorf("SrcPort column after undo (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDstAfter); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDstAfter); diff != "" { t.Errorf("DstPort column after undo (-got, +want):\n%s", diff) } } @@ -246,7 +248,7 @@ func TestUndoUInt8(t *testing.T) { col := bf.batch.columns[ColumnSrcNetMask].(*proto.ColUInt8) expected := proto.ColUInt8{6} - if diff := helpers.Diff(col, expected); diff != "" { + if diff := helpers.Diff(col, &expected); diff != "" { t.Errorf("Initial Proto column state (-got, +want):\n%s", diff) } @@ -255,7 +257,7 @@ func TestUndoUInt8(t *testing.T) { expectedAfter := proto.ColUInt8{} - if diff := helpers.Diff(col, expectedAfter); diff != "" { + if diff := helpers.Diff(col, &expectedAfter); diff != "" { t.Errorf("Proto column after undo (-got, +want):\n%s", diff) } } @@ -278,10 +280,10 @@ func TestUndoIPv6(t *testing.T) { expectedSrc := proto.ColIPv6{srcAddr.As16()} expectedDst := proto.ColIPv6{dstAddr.As16()} - if diff := helpers.Diff(srcCol, expectedSrc); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrc); diff != "" { t.Errorf("Initial SrcAddr column state (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDst); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDst); diff != "" { t.Errorf("Initial DstAddr column state (-got, +want):\n%s", diff) } @@ -291,10 +293,10 @@ func TestUndoIPv6(t *testing.T) { expectedSrcAfter := proto.ColIPv6{} expectedDstAfter := proto.ColIPv6{} - if diff := helpers.Diff(srcCol, expectedSrcAfter); diff != "" { + if diff := helpers.Diff(srcCol, &expectedSrcAfter); diff != "" { t.Errorf("SrcAddr column after undo (-got, +want):\n%s", diff) } - if diff := helpers.Diff(dstCol, expectedDstAfter); diff != "" { + if diff := helpers.Diff(dstCol, &expectedDstAfter); diff != "" { t.Errorf("DstAddr column after undo (-got, +want):\n%s", diff) } } @@ -310,7 +312,7 @@ func TestUndoDateTime(t *testing.T) { col := bf.batch.columns[ColumnTimeReceived].(*proto.ColDateTime) expected := proto.ColDateTime{Data: []proto.DateTime{1000}} - if diff := helpers.Diff(col, expected); diff != "" { + if diff := helpers.Diff(col, &expected); diff != "" { t.Errorf("Initial TimeReceived column state (-got, +want):\n%s", diff) } @@ -319,7 +321,7 @@ func TestUndoDateTime(t *testing.T) { expectedAfter := proto.ColDateTime{Data: []proto.DateTime{}} - if diff := helpers.Diff(col, expectedAfter); diff != "" { + if diff := helpers.Diff(col, &expectedAfter); diff != "" { t.Errorf("TimeReceived column after undo (-got, +want):\n%s", diff) } } @@ -335,7 +337,7 @@ func TestUndoEnum8(t *testing.T) { col := bf.batch.columns[ColumnInIfBoundary].(*proto.ColEnum8) expected := proto.ColEnum8{proto.Enum8(InterfaceBoundaryExternal)} - if diff := helpers.Diff(col, expected); diff != "" { + if diff := helpers.Diff(col, &expected); diff != "" { t.Errorf("Initial InIfBoundary column state (-got, +want):\n%s", diff) } @@ -344,7 +346,7 @@ func TestUndoEnum8(t *testing.T) { expectedAfter := proto.ColEnum8{} - if diff := helpers.Diff(col, expectedAfter); diff != "" { + if diff := helpers.Diff(col, &expectedAfter); diff != "" { t.Errorf("InIfBoundary column after undo (-got, +want):\n%s", diff) } } @@ -364,10 +366,14 @@ func TestUndoLowCardinalityString(t *testing.T) { expectedName := proto.ColLowCardinality[string]{Values: []string{"router1"}} expectedRole := proto.ColLowCardinality[string]{Values: []string{"edge"}} - if diff := helpers.Diff(nameCol, expectedName); diff != "" { + diffOpt := cmp.Comparer(func(x, y proto.ColLowCardinality[string]) bool { + return slices.Compare(x.Values, y.Values) == 0 + }) + + if diff := helpers.Diff(nameCol, &expectedName, diffOpt); diff != "" { t.Errorf("Initial ExporterName column state (-got, +want):\n%s", diff) } - if diff := helpers.Diff(roleCol, expectedRole); diff != "" { + if diff := helpers.Diff(roleCol, &expectedRole, diffOpt); diff != "" { t.Errorf("Initial ExporterRole column state (-got, +want):\n%s", diff) } @@ -377,10 +383,10 @@ func TestUndoLowCardinalityString(t *testing.T) { expectedNameAfter := proto.ColLowCardinality[string]{Values: []string{}} expectedRoleAfter := proto.ColLowCardinality[string]{Values: []string{}} - if diff := helpers.Diff(nameCol, expectedNameAfter); diff != "" { + if diff := helpers.Diff(nameCol, &expectedNameAfter, diffOpt); diff != "" { t.Errorf("ExporterName column after undo (-got, +want):\n%s", diff) } - if diff := helpers.Diff(roleCol, expectedRoleAfter); diff != "" { + if diff := helpers.Diff(roleCol, &expectedRoleAfter, diffOpt); diff != "" { t.Errorf("ExporterRole column after undo (-got, +want):\n%s", diff) } } @@ -393,11 +399,17 @@ func TestUndoLowCardinalityIPv6(t *testing.T) { addr := netip.MustParseAddr("2001:db8::1") bf.AppendIPv6(ColumnExporterAddress, addr) + diffOpt := cmp.Comparer(func(x, y proto.ColLowCardinality[proto.IPv6]) bool { + return slices.CompareFunc(x.Values, y.Values, func(a, b proto.IPv6) int { + return strings.Compare(a.String(), b.String()) + }) == 0 + }) + // Check we have the expected initial state col := bf.batch.columns[ColumnExporterAddress].(*proto.ColLowCardinality[proto.IPv6]) expected := proto.ColLowCardinality[proto.IPv6]{Values: []proto.IPv6{addr.As16()}} - if diff := helpers.Diff(col, expected); diff != "" { + if diff := helpers.Diff(col, &expected, diffOpt); diff != "" { t.Errorf("Initial ExporterAddress column state (-got, +want):\n%s", diff) } @@ -406,7 +418,7 @@ func TestUndoLowCardinalityIPv6(t *testing.T) { expectedAfter := proto.ColLowCardinality[proto.IPv6]{Values: []proto.IPv6{}} - if diff := helpers.Diff(col, expectedAfter); diff != "" { + if diff := helpers.Diff(col, &expectedAfter, diffOpt); diff != "" { t.Errorf("ExporterAddress column after undo (-got, +want):\n%s", diff) } } @@ -593,11 +605,11 @@ func TestBuildProtoInput(t *testing.T) { // Let's compare a subset expected := proto.Input{ - {Name: "TimeReceived", Data: proto.ColDateTime{Data: []proto.DateTime{1002, 1003}}}, - {Name: "SrcAS", Data: proto.ColUInt32{65000, 65001}}, - {Name: "DstAS", Data: proto.ColUInt32{0, 0}}, - {Name: "Bytes", Data: proto.ColUInt64{2000, 202}}, - {Name: "Packets", Data: proto.ColUInt64{30, 3}}, + {Name: "TimeReceived", Data: &proto.ColDateTime{Data: []proto.DateTime{1002, 1003}}}, + {Name: "SrcAS", Data: &proto.ColUInt32{65000, 65001}}, + {Name: "DstAS", Data: &proto.ColUInt32{0, 0}}, + {Name: "Bytes", Data: &proto.ColUInt64{2000, 202}}, + {Name: "Packets", Data: &proto.ColUInt64{30, 3}}, } got = slices.DeleteFunc(got, func(col proto.InputColumn) bool { return !slices.Contains([]string{"TimeReceived", "SrcAS", "DstAS", "Packets", "Bytes"}, col.Name) diff --git a/common/schema/definition_test.go b/common/schema/definition_test.go index 02eb8b45..3e27793d 100644 --- a/common/schema/definition_test.go +++ b/common/schema/definition_test.go @@ -7,6 +7,9 @@ import ( "testing" "akvorado/common/helpers" + + "github.com/bits-and-blooms/bitset" + "github.com/google/go-cmp/cmp" ) func TestFlowsClickHouse(t *testing.T) { @@ -35,7 +38,11 @@ func TestFinalizeTwice(t *testing.T) { c := NewMock(t) oldSchema := c.Schema newSchema := c.finalize() - if diff := helpers.Diff(oldSchema, newSchema, helpers.DiffUnexported); diff != "" { + if diff := helpers.Diff(oldSchema, newSchema, + cmp.AllowUnexported(Schema{}), + cmp.Comparer(func(x, y bitset.BitSet) bool { + return x.Equal(&y) + })); diff != "" { t.Fatalf("finalize() (-old, +new):\n%s", diff) } } diff --git a/common/schema/insert_test.go b/common/schema/insert_test.go index 4bb3609d..c1c36ab5 100644 --- a/common/schema/insert_test.go +++ b/common/schema/insert_test.go @@ -160,29 +160,29 @@ func TestInsertMemory(t *testing.T) { "SamplingRate": "20000", "ExporterAddress": "::ffff:203.0.113.14", "ExporterName": "router1.example.net", - "SrcAS": 65000, - "DstAS": 12322, + "SrcAS": float64(65000), + "DstAS": float64(12322), "Bytes": "20", "Packets": "3", "InIfBoundary": "internal", "OutIfBoundary": "external", - "InIfSpeed": 10000, - "EType": helpers.ETypeIPv4, + "InIfSpeed": float64(10000), + "EType": float64(helpers.ETypeIPv4), }, { "TimeReceived": "1970-01-01 00:16:41", "SamplingRate": "20000", "ExporterAddress": "::ffff:203.0.113.14", "ExporterName": "router1.example.net", - "SrcAS": 12322, - "DstAS": 65000, + "SrcAS": float64(12322), + "DstAS": float64(65000), "Bytes": "200", "Packets": "3", "InIfBoundary": "external", "OutIfBoundary": "undefined", - "OutIfSpeed": 10000, - "EType": helpers.ETypeIPv4, - "DstASPath": []uint32{65400, 65500, 65001}, - "DstLargeCommunities": []string{ + "OutIfSpeed": float64(10000), + "EType": float64(helpers.ETypeIPv4), + "DstASPath": []any{float64(65400), float64(65500), float64(65001)}, + "DstLargeCommunities": []any{ "1206435509165107881967816", // 65401:100:200 "1206435509165107881967817", // 65401:100:201 }, diff --git a/common/schema/tests.go b/common/schema/tests.go index e0240d6e..6a8f8604 100644 --- a/common/schema/tests.go +++ b/common/schema/tests.go @@ -6,11 +6,11 @@ package schema import ( - "fmt" - "reflect" "testing" "akvorado/common/helpers" + + "github.com/google/go-cmp/cmp/cmpopts" ) var debug = true @@ -44,5 +44,5 @@ func (c *Component) EnableAllColumns() *Component { } func init() { - helpers.AddPrettyFormatter(reflect.TypeOf(ColumnBytes), fmt.Sprint) + helpers.RegisterCmpOption(cmpopts.IgnoreUnexported(FlowMessage{})) } diff --git a/console/filter/parser_test.go b/console/filter/parser_test.go index dce7d544..44270f9b 100644 --- a/console/filter/parser_test.go +++ b/console/filter/parser_test.go @@ -351,7 +351,6 @@ output provider */ = 'telia'`, s = s.EnableAllColumns() for _, tc := range cases { tc.MetaIn.Schema = s - tc.MetaOut.Schema = tc.MetaIn.Schema got, err := Parse("", []byte(tc.Input), GlobalStore("meta", &tc.MetaIn)) if err != nil { t.Errorf("Parse(%q) error:\n%+v", tc.Input, err) @@ -397,7 +396,6 @@ func TestValidMaterializedFilter(t *testing.T) { cs.ClickHouseMaterialized = true tc.MetaIn.Schema = s - tc.MetaOut.Schema = tc.MetaIn.Schema got, err := Parse("", []byte(tc.Input), GlobalStore("meta", &tc.MetaIn)) if err != nil { t.Errorf("Parse(%q) error:\n%+v", tc.Input, err) diff --git a/console/filter/tests.go b/console/filter/tests.go new file mode 100644 index 00000000..2e6377cc --- /dev/null +++ b/console/filter/tests.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2025 Free Mobile +// SPDX-License-Identifier: AGPL-3.0-only + +//go:build !release + +package filter + +import ( + "akvorado/common/helpers" + + "github.com/google/go-cmp/cmp/cmpopts" +) + +func init() { + helpers.RegisterCmpOption(cmpopts.IgnoreFields(Meta{}, "Schema")) +} diff --git a/console/line_test.go b/console/line_test.go index ca52cf5c..33936fa4 100644 --- a/console/line_test.go +++ b/console/line_test.go @@ -46,6 +46,8 @@ func TestGraphLineInputReverseDirection(t *testing.T) { }, Points: 100, } + input.Filter.Validate(input.schema) + expected.Filter.Validate(input.schema) query.Columns(input.Dimensions).Validate(input.schema) query.Columns(expected.Dimensions).Validate(input.schema) got := input.reverseDirection() diff --git a/console/query/column.go b/console/query/column.go index d7fed2f6..c83946bf 100644 --- a/console/query/column.go +++ b/console/query/column.go @@ -39,6 +39,11 @@ func (qc Column) String() string { return qc.name } +// Equal returns true iff two columns have the same name. +func (qc Column) Equal(oqc Column) bool { + return qc.name == oqc.name +} + // MarshalText turns a column into a string. func (qc Column) MarshalText() ([]byte, error) { return []byte(qc.name), nil diff --git a/console/query/column_test.go b/console/query/column_test.go index 7b2792bf..157c470d 100644 --- a/console/query/column_test.go +++ b/console/query/column_test.go @@ -4,8 +4,6 @@ package query_test import ( - "fmt" - "reflect" "testing" "akvorado/common/helpers" @@ -38,7 +36,7 @@ func TestUnmarshalQueryColumn(t *testing.T) { if err != nil { continue } - if diff := helpers.Diff(qc.Key(), tc.Expected, helpers.DiffFormatter(reflect.TypeOf(schema.ColumnBytes), fmt.Sprint)); diff != "" { + if diff := helpers.Diff(qc.Key(), tc.Expected); diff != "" { t.Fatalf("UnmarshalText(%q) (-got, +want):\n%s", tc.Input, diff) } } @@ -145,7 +143,7 @@ func TestReverseDirection(t *testing.T) { query.NewColumn("ExporterName"), query.NewColumn("OutIfProvider"), } - if diff := helpers.Diff(columns, expected, helpers.DiffFormatter(reflect.TypeOf(query.Column{}), fmt.Sprint)); diff != "" { + if diff := helpers.Diff(columns, expected); diff != "" { t.Fatalf("Reverse() (-got, +want):\n%s", diff) } } diff --git a/console/query/filter.go b/console/query/filter.go index bff215d8..f82c78a0 100644 --- a/console/query/filter.go +++ b/console/query/filter.go @@ -34,6 +34,11 @@ func (qf Filter) String() string { return qf.filter } +// Equal tells if two filters are equal. +func (qf Filter) Equal(oqf Filter) bool { + return qf.filter == oqf.filter +} + // MarshalText turns a filter into a string. func (qf Filter) MarshalText() ([]byte, error) { return []byte(qf.filter), nil diff --git a/console/tests.go b/console/tests.go index 152fd57e..25653e52 100644 --- a/console/tests.go +++ b/console/tests.go @@ -9,6 +9,8 @@ import ( "testing" "github.com/benbjohnson/clock" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "akvorado/common/clickhousedb" "akvorado/common/clickhousedb/mocks" @@ -43,3 +45,8 @@ func NewMock(t *testing.T, config Configuration) (*Component, *httpserver.Compon helpers.StartStop(t, c) return c, h, mockConn, mockClock } + +func init() { + helpers.RegisterCmpOption(cmpopts.IgnoreUnexported(graphCommonHandlerInput{})) + helpers.RegisterCmpOption(cmp.AllowUnexported(graphLineHandlerInput{})) +} diff --git a/demoexporter/flows/nfdata_test.go b/demoexporter/flows/nfdata_test.go index e166bfad..6ee04022 100644 --- a/demoexporter/flows/nfdata_test.go +++ b/demoexporter/flows/nfdata_test.go @@ -129,13 +129,13 @@ func TestGetNetFlowData(t *testing.T) { SrcNetMask: 24, DstNetMask: 23, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 34974, - schema.ColumnForwardingStatus: 64, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(34974), + schema.ColumnForwardingStatus: uint32(64), }, }, { @@ -150,13 +150,13 @@ func TestGetNetFlowData(t *testing.T) { SrcNetMask: 24, DstNetMask: 24, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1339, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 33199, - schema.ColumnForwardingStatus: 64, + schema.ColumnBytes: uint64(1339), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(33199), + schema.ColumnForwardingStatus: uint32(64), }, }, { @@ -171,13 +171,13 @@ func TestGetNetFlowData(t *testing.T) { SrcNetMask: 48, DstNetMask: 48, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1300, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 33179, - schema.ColumnDstPort: 443, - schema.ColumnForwardingStatus: 64, + schema.ColumnBytes: uint64(1300), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(33179), + schema.ColumnDstPort: uint16(443), + schema.ColumnForwardingStatus: uint32(64), }, }, } diff --git a/demoexporter/snmp/server_test.go b/demoexporter/snmp/server_test.go index 9dd22e09..c544770c 100644 --- a/demoexporter/snmp/server_test.go +++ b/demoexporter/snmp/server_test.go @@ -70,11 +70,11 @@ func TestSNMPServer(t *testing.T) { Type: gosnmp.OctetString, }, { Name: ".1.3.6.1.2.1.31.1.1.1.15.1", - Value: 10000, + Value: uint(10000), Type: gosnmp.Gauge32, }, { Name: ".1.3.6.1.2.1.31.1.1.1.15.2", - Value: 10000, + Value: uint(10000), Type: gosnmp.Gauge32, }, { Name: ".1.3.6.1.2.1.31.1.1.1.18.1", diff --git a/go.mod b/go.mod index cf9ed7ce..b648a634 100644 --- a/go.mod +++ b/go.mod @@ -22,12 +22,12 @@ require ( github.com/go-playground/validator/v10 v10.20.0 github.com/go-redis/redis/v8 v8.11.5 github.com/go-viper/mapstructure/v2 v2.4.0 + github.com/google/go-cmp v0.7.0 github.com/google/gopacket v1.1.19 github.com/gosnmp/gosnmp v1.42.1 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 github.com/hashicorp/go-version v1.7.0 github.com/itchyny/gojq v0.12.17 - github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-isatty v0.0.20 github.com/netsampler/goflow2/v2 v2.2.3 github.com/openconfig/gnmi v0.14.0 @@ -111,7 +111,6 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/go-cmp v0.7.0 // indirect github.com/google/licensecheck v0.3.1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/inlet/flow/input/file/root_test.go b/inlet/flow/input/file/root_test.go index 3d2033b2..eaec5e00 100644 --- a/inlet/flow/input/file/root_test.go +++ b/inlet/flow/input/file/root_test.go @@ -22,7 +22,7 @@ func TestFileInput(t *testing.T) { configuration.Paths = []string{path.Join("testdata", "file1.txt"), path.Join("testdata", "file2.txt")} done := make(chan bool) - expected := []pb.RawFlow{ + expected := []*pb.RawFlow{ { Payload: []byte("hello world!\n"), SourceAddress: net.ParseIP("127.0.0.1").To16(), diff --git a/orchestrator/clickhouse/config_test.go b/orchestrator/clickhouse/config_test.go index 34ad066b..f2febdc2 100644 --- a/orchestrator/clickhouse/config_test.go +++ b/orchestrator/clickhouse/config_test.go @@ -4,8 +4,6 @@ package clickhouse import ( - "fmt" - "reflect" "testing" "github.com/gin-gonic/gin" @@ -16,46 +14,53 @@ import ( func TestNetworkNamesUnmarshalHook(t *testing.T) { helpers.TestConfigurationDecode(t, helpers.ConfigurationDecodeCases{ { + Pos: helpers.Mark(), Description: "nil", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return nil }, - Expected: helpers.SubnetMap[NetworkAttributes]{}, + Expected: &helpers.SubnetMap[NetworkAttributes]{}, }, { + Pos: helpers.Mark(), Description: "empty", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{} }, - Expected: helpers.SubnetMap[NetworkAttributes]{}, + Expected: &helpers.SubnetMap[NetworkAttributes]{}, }, { + Pos: helpers.Mark(), Description: "IPv4", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"203.0.113.0/24": gin.H{"name": "customer"}} }, Expected: helpers.MustNewSubnetMap(map[string]NetworkAttributes{ "::ffff:203.0.113.0/120": {Name: "customer"}, }), }, { + Pos: helpers.Mark(), Description: "IPv6", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"2001:db8:1::/64": gin.H{"name": "customer"}} }, Expected: helpers.MustNewSubnetMap(map[string]NetworkAttributes{ "2001:db8:1::/64": {Name: "customer"}, }), }, { + Pos: helpers.Mark(), Description: "IPv4 subnet (compatibility)", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"203.0.113.0/24": "customer"} }, Expected: helpers.MustNewSubnetMap(map[string]NetworkAttributes{ "::ffff:203.0.113.0/120": {Name: "customer"}, }), }, { + Pos: helpers.Mark(), Description: "IPv6 subnet (compatibility)", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"2001:db8:1::/64": "customer"} }, Expected: helpers.MustNewSubnetMap(map[string]NetworkAttributes{ "2001:db8:1::/64": {Name: "customer"}, }), }, { + Pos: helpers.Mark(), Description: "all attributes", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"203.0.113.0/24": gin.H{ "name": "customer1", @@ -73,17 +78,19 @@ func TestNetworkNamesUnmarshalHook(t *testing.T) { Tenant: "mobile", }}), }, { + Pos: helpers.Mark(), Description: "Invalid subnet (1)", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"192.0.2.1/38": "customer"} }, Error: true, }, { + Pos: helpers.Mark(), Description: "Invalid subnet (2)", - Initial: func() any { return helpers.SubnetMap[NetworkAttributes]{} }, + Initial: func() any { return &helpers.SubnetMap[NetworkAttributes]{} }, Configuration: func() any { return gin.H{"192.0.2.1/255.0.255.0": "customer"} }, Error: true, }, - }, helpers.DiffFormatter(reflect.TypeOf(helpers.SubnetMap[NetworkAttributes]{}), fmt.Sprint)) + }) } func TestDefaultConfiguration(t *testing.T) { @@ -92,3 +99,7 @@ func TestDefaultConfiguration(t *testing.T) { t.Fatalf("validate.Struct() error:\n%+v", err) } } + +func init() { + helpers.RegisterSubnetMapCmp[NetworkAttributes]() +} diff --git a/outlet/core/config.go b/outlet/core/config.go index 7e2e1fa1..c2cc5fb4 100644 --- a/outlet/core/config.go +++ b/outlet/core/config.go @@ -23,9 +23,9 @@ type Configuration struct { // ClassifierCacheDuration defines the default TTL for classifier cache ClassifierCacheDuration time.Duration `validate:"min=1s"` // DefaultSamplingRate defines the default sampling rate to use when the information is missing - DefaultSamplingRate helpers.SubnetMap[uint] + DefaultSamplingRate *helpers.SubnetMap[uint] // OverrideSamplingRate defines a sampling rate to use instead of the received on - OverrideSamplingRate helpers.SubnetMap[uint] + OverrideSamplingRate *helpers.SubnetMap[uint] // ASNProviders defines the source used to get AS numbers ASNProviders []ASNProvider `validate:"dive"` // NetProviders defines the source used to get Prefix/Network Information diff --git a/outlet/core/enricher_test.go b/outlet/core/enricher_test.go index f544a188..766b726e 100644 --- a/outlet/core/enricher_test.go +++ b/outlet/core/enricher_test.go @@ -58,8 +58,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -89,8 +89,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -115,8 +115,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -145,8 +145,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -181,8 +181,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -214,8 +214,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -282,8 +282,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -314,8 +314,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Super Speed", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -349,8 +349,8 @@ func TestEnrich(t *testing.T) { schema.ColumnOutIfName: "Gi0/0/200.300", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), }, }, }, @@ -385,10 +385,10 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, - schema.ColumnInIfBoundary: schema.InterfaceBoundaryInternal, - schema.ColumnOutIfBoundary: schema.InterfaceBoundaryInternal, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), + schema.ColumnInIfBoundary: uint8(schema.InterfaceBoundaryInternal), + schema.ColumnOutIfBoundary: uint8(schema.InterfaceBoundaryInternal), }, }, }, @@ -419,10 +419,10 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, - schema.ColumnInIfBoundary: 2, // Internal - schema.ColumnOutIfBoundary: 2, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), + schema.ColumnInIfBoundary: uint8(2), // Internal + schema.ColumnOutIfBoundary: uint8(2), }, }, }, @@ -453,8 +453,8 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), schema.ColumnInIfProvider: "telia", schema.ColumnOutIfProvider: "telia", }, @@ -488,14 +488,14 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), schema.ColumnInIfConnectivity: "p100", schema.ColumnOutIfConnectivity: "core", schema.ColumnInIfProvider: "othello", schema.ColumnOutIfProvider: "othello", - schema.ColumnInIfBoundary: 1, // external - schema.ColumnOutIfBoundary: 2, // internal + schema.ColumnInIfBoundary: uint8(1), // external + schema.ColumnOutIfBoundary: uint8(2), // internal }, }, }, @@ -532,14 +532,14 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/2010", schema.ColumnInIfDescription: "Interface 1010", schema.ColumnOutIfDescription: "Interface 2010", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), schema.ColumnInIfConnectivity: "p1010", schema.ColumnOutIfConnectivity: "metadata connectivity", schema.ColumnInIfProvider: "othello", schema.ColumnOutIfProvider: "metadata provider", - schema.ColumnInIfBoundary: schema.InterfaceBoundaryExternal, - schema.ColumnOutIfBoundary: schema.InterfaceBoundaryExternal, + schema.ColumnInIfBoundary: uint8(schema.InterfaceBoundaryExternal), + schema.ColumnOutIfBoundary: uint8(schema.InterfaceBoundaryExternal), }, }, }, @@ -573,8 +573,8 @@ ClassifyProviderRegex(Interface.Description, "^Transit: ([^ ]+)", "$1")`, schema.ColumnOutIfName: "Gi0/0/200", schema.ColumnInIfDescription: "Interface 100", schema.ColumnOutIfDescription: "Interface 200", - schema.ColumnInIfSpeed: 1000, - schema.ColumnOutIfSpeed: 1000, + schema.ColumnInIfSpeed: uint32(1000), + schema.ColumnOutIfSpeed: uint32(1000), schema.ColumnDstASPath: []uint32{64200, 1299, 174}, schema.ColumnDstCommunities: []uint32{100, 200, 400}, schema.ColumnDstLargeCommunities: []schema.UInt128{ diff --git a/outlet/core/root_test.go b/outlet/core/root_test.go index 7461059e..60232cb5 100644 --- a/outlet/core/root_test.go +++ b/outlet/core/root_test.go @@ -83,12 +83,12 @@ func TestCore(t *testing.T) { SrcAddr: netip.MustParseAddr("::ffff:67.43.156.77"), DstAddr: netip.MustParseAddr("::ffff:2.125.160.216"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 6765, - schema.ColumnPackets: 4, - schema.ColumnEType: 0x800, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 8534, - schema.ColumnDstPort: 80, + schema.ColumnBytes: uint64(6765), + schema.ColumnPackets: uint64(4), + schema.ColumnEType: uint32(0x800), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(8534), + schema.ColumnDstPort: uint16(80), }, } return msg @@ -102,8 +102,8 @@ func TestCore(t *testing.T) { expected.OtherColumns[schema.ColumnOutIfName] = fmt.Sprintf("Gi0/0/%d", out) expected.OtherColumns[schema.ColumnInIfDescription] = fmt.Sprintf("Interface %d", in) expected.OtherColumns[schema.ColumnOutIfDescription] = fmt.Sprintf("Interface %d", out) - expected.OtherColumns[schema.ColumnInIfSpeed] = 1000 - expected.OtherColumns[schema.ColumnOutIfSpeed] = 1000 + expected.OtherColumns[schema.ColumnInIfSpeed] = uint32(1000) + expected.OtherColumns[schema.ColumnOutIfSpeed] = uint32(1000) expected.OtherColumns[schema.ColumnExporterName] = strings.ReplaceAll(exporter, ".", "_") return expected } @@ -259,34 +259,34 @@ func TestCore(t *testing.T) { t.Fatalf("GET /api/v0/outlet/flows error while reading body:\n%+v", err) } expected := gin.H{ - "TimeReceived": 200, - "SamplingRate": 1000, + "TimeReceived": float64(200), + "SamplingRate": float64(1000), "ExporterAddress": "::ffff:192.0.2.142", "SrcAddr": "::ffff:67.43.156.77", "DstAddr": "::ffff:2.125.160.216", - "SrcAS": 0, // no geoip enrich anymore - "InIf": 434, - "OutIf": 677, + "SrcAS": float64(0), // no geoip enrich anymore + "InIf": float64(434), + "OutIf": float64(677), "NextHop": "", - "SrcNetMask": 0, - "DstNetMask": 0, - "SrcVlan": 0, - "DstVlan": 0, - "DstAS": 0, - "OtherColumns": gin.H{ + "SrcNetMask": float64(0), + "DstNetMask": float64(0), + "SrcVlan": float64(0), + "DstVlan": float64(0), + "DstAS": float64(0), + "OtherColumns": map[string]any{ "ExporterName": "192_0_2_142", "InIfName": "Gi0/0/434", "OutIfName": "Gi0/0/677", "InIfDescription": "Interface 434", "OutIfDescription": "Interface 677", - "InIfSpeed": 1000, - "OutIfSpeed": 1000, - "Bytes": 6765, - "Packets": 4, - "SrcPort": 8534, - "DstPort": 80, - "EType": 2048, - "Proto": 6, + "InIfSpeed": float64(1000), + "OutIfSpeed": float64(1000), + "Bytes": float64(6765), + "Packets": float64(4), + "SrcPort": float64(8534), + "DstPort": float64(80), + "EType": float64(2048), + "Proto": float64(6), }, } if diff := helpers.Diff(got, expected); diff != "" { diff --git a/outlet/flow/decoder/gob/root_test.go b/outlet/flow/decoder/gob/root_test.go index 5b56ba59..9afbd803 100644 --- a/outlet/flow/decoder/gob/root_test.go +++ b/outlet/flow/decoder/gob/root_test.go @@ -43,10 +43,10 @@ func TestGobDecoder(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:192.0.2.200"), OtherColumns: map[schema.ColumnKey]any{ schema.ColumnBytes: uint64(1024), - schema.ColumnPackets: 10, - schema.ColumnInIfBoundary: schema.InterfaceBoundaryExternal, + schema.ColumnPackets: uint64(10), + schema.ColumnInIfBoundary: uint8(schema.InterfaceBoundaryExternal), schema.ColumnExporterName: "hello", - schema.ColumnDstNetMask: uint32(8), + schema.ColumnDstNetMask: uint8(8), schema.ColumnDstPort: uint16(80), schema.ColumnDstASPath: []uint32{65000, 65001, 65002}, }, diff --git a/outlet/flow/decoder/helpers_test.go b/outlet/flow/decoder/helpers_test.go index 5743f660..d5b999ad 100644 --- a/outlet/flow/decoder/helpers_test.go +++ b/outlet/flow/decoder/helpers_test.go @@ -20,21 +20,21 @@ func TestDecodeMPLSAndIPv4(t *testing.T) { if l != 40 { t.Errorf("ParseEthernet() returned %d, expected 40", l) } - expected := schema.FlowMessage{ + expected := &schema.FlowMessage{ SrcAddr: netip.MustParseAddr("::ffff:10.31.0.1"), DstAddr: netip.MustParseAddr("::ffff:10.34.0.1"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 11001, - schema.ColumnDstPort: 23, - schema.ColumnTCPFlags: 16, - schema.ColumnMPLSLabels: []uint64{18, 16}, - schema.ColumnIPTTL: 255, - schema.ColumnIPTos: 0xb0, - schema.ColumnIPFragmentID: 8, - schema.ColumnSrcMAC: 0x003096052838, - schema.ColumnDstMAC: 0x003096e6fc39, + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(11001), + schema.ColumnDstPort: uint16(23), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnMPLSLabels: []uint32{18, 16}, + schema.ColumnIPTTL: uint8(255), + schema.ColumnIPTos: uint8(0xb0), + schema.ColumnIPFragmentID: uint32(8), + schema.ColumnSrcMAC: uint64(0x003096052838), + schema.ColumnDstMAC: uint64(0x003096e6fc39), }, } if diff := helpers.Diff(bf, expected); diff != "" { @@ -50,16 +50,16 @@ func TestDecodeVLANAndIPv6(t *testing.T) { if l != 179 { t.Errorf("ParseEthernet() returned %d, expected 179", l) } - expected := schema.FlowMessage{ + expected := &schema.FlowMessage{ SrcVlan: 100, SrcAddr: netip.MustParseAddr("2402:f000:1:8e01::5555"), DstAddr: netip.MustParseAddr("2607:fcd0:100:2300::b108:2a6b"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 4, - schema.ColumnIPTTL: 246, - schema.ColumnSrcMAC: 0x00121ef2613d, - schema.ColumnDstMAC: 0xc500000082c4, + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(4), + schema.ColumnIPTTL: uint8(246), + schema.ColumnSrcMAC: uint64(0x00121ef2613d), + schema.ColumnDstMAC: uint64(0xc500000082c4), }, } if diff := helpers.Diff(bf, expected); diff != "" { diff --git a/outlet/flow/decoder/netflow/root_test.go b/outlet/flow/decoder/netflow/root_test.go index c0ab3e9f..b19fb725 100644 --- a/outlet/flow/decoder/netflow/root_test.go +++ b/outlet/flow/decoder/netflow/root_test.go @@ -138,14 +138,14 @@ func TestDecode(t *testing.T) { SrcNetMask: 24, DstNetMask: 14, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 19624, - schema.ColumnForwardingStatus: 64, - schema.ColumnTCPFlags: 16, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(19624), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnTCPFlags: uint16(16), }, }, { SamplingRate: 30000, @@ -158,14 +158,14 @@ func TestDecode(t *testing.T) { SrcNetMask: 24, DstNetMask: 14, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 2444, - schema.ColumnForwardingStatus: 64, - schema.ColumnTCPFlags: 16, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(2444), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnTCPFlags: uint16(16), }, }, { SamplingRate: 30000, @@ -178,14 +178,14 @@ func TestDecode(t *testing.T) { SrcNetMask: 20, DstNetMask: 18, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1400, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 53697, - schema.ColumnForwardingStatus: 64, - schema.ColumnTCPFlags: 16, + schema.ColumnBytes: uint64(1400), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(53697), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnTCPFlags: uint16(16), }, }, { SamplingRate: 30000, @@ -198,19 +198,19 @@ func TestDecode(t *testing.T) { SrcNetMask: 16, DstNetMask: 14, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1448, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 52300, - schema.ColumnForwardingStatus: 64, - schema.ColumnTCPFlags: 16, + schema.ColumnBytes: uint64(1448), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(52300), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnTCPFlags: uint16(16), }, }, } - if diff := helpers.Diff(got, expectedFlows); diff != "" { + if diff := helpers.Diff(got, &expectedFlows); diff != "" { t.Fatalf("Decode() (-got, +want):\n%s", diff) } gotMetrics = r.GetMetrics( @@ -293,12 +293,12 @@ func TestDecodeSamplingRate(t *testing.T) { SrcVlan: 701, NextHop: netip.MustParseAddr("::ffff:0.0.0.0"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnPackets: 1, - schema.ColumnBytes: 160, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 13245, - schema.ColumnDstPort: 10907, - schema.ColumnEType: helpers.ETypeIPv4, + schema.ColumnPackets: uint64(1), + schema.ColumnBytes: uint64(160), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(13245), + schema.ColumnDstPort: uint16(10907), + schema.ColumnEType: uint32(helpers.ETypeIPv4), }, }, } @@ -353,17 +353,17 @@ func TestDecodeMultipleSamplingRates(t *testing.T) { InIf: 97, OutIf: 6, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnPackets: 18, - schema.ColumnBytes: 1348, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 52616, - schema.ColumnForwardingStatus: 64, - schema.ColumnIPTTL: 127, - schema.ColumnIPTos: 64, - schema.ColumnIPv6FlowLabel: 252813, - schema.ColumnTCPFlags: 16, - schema.ColumnEType: helpers.ETypeIPv6, + schema.ColumnPackets: uint64(18), + schema.ColumnBytes: uint64(1348), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(52616), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnIPTTL: uint8(127), + schema.ColumnIPTos: uint8(64), + schema.ColumnIPv6FlowLabel: uint32(252813), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnEType: uint32(helpers.ETypeIPv6), }, }, { @@ -377,16 +377,16 @@ func TestDecodeMultipleSamplingRates(t *testing.T) { InIf: 103, OutIf: 6, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnPackets: 4, - schema.ColumnBytes: 579, - schema.ColumnProto: 17, - schema.ColumnSrcPort: 2121, - schema.ColumnDstPort: 2121, - schema.ColumnForwardingStatus: 64, - schema.ColumnIPTTL: 57, - schema.ColumnIPTos: 40, - schema.ColumnIPv6FlowLabel: 570164, - schema.ColumnEType: helpers.ETypeIPv6, + schema.ColumnPackets: uint64(4), + schema.ColumnBytes: uint64(579), + schema.ColumnProto: uint32(17), + schema.ColumnSrcPort: uint16(2121), + schema.ColumnDstPort: uint16(2121), + schema.ColumnForwardingStatus: uint32(64), + schema.ColumnIPTTL: uint8(57), + schema.ColumnIPTos: uint8(40), + schema.ColumnIPv6FlowLabel: uint32(570164), + schema.ColumnEType: uint32(helpers.ETypeIPv6), }, }, } @@ -421,12 +421,12 @@ func TestDecodeICMP(t *testing.T) { SrcAddr: netip.MustParseAddr("2001:db8::"), DstAddr: netip.MustParseAddr("2001:db8::1"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 104, - schema.ColumnDstPort: 32768, - schema.ColumnEType: 34525, - schema.ColumnICMPv6Type: 128, // Code: 0 - schema.ColumnPackets: 1, - schema.ColumnProto: 58, + schema.ColumnBytes: uint64(104), + schema.ColumnDstPort: uint16(32768), + schema.ColumnEType: uint32(34525), + schema.ColumnICMPv6Type: uint8(128), // Code: 0 + schema.ColumnPackets: uint64(1), + schema.ColumnProto: uint32(58), }, }, { @@ -434,12 +434,12 @@ func TestDecodeICMP(t *testing.T) { SrcAddr: netip.MustParseAddr("2001:db8::1"), DstAddr: netip.MustParseAddr("2001:db8::"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 104, - schema.ColumnDstPort: 33024, - schema.ColumnEType: 34525, - schema.ColumnICMPv6Type: 129, // Code: 0 - schema.ColumnPackets: 1, - schema.ColumnProto: 58, + schema.ColumnBytes: uint64(104), + schema.ColumnDstPort: uint16(33024), + schema.ColumnEType: uint32(34525), + schema.ColumnICMPv6Type: uint8(129), // Code: 0 + schema.ColumnPackets: uint64(1), + schema.ColumnProto: uint32(58), }, }, { @@ -447,12 +447,12 @@ func TestDecodeICMP(t *testing.T) { SrcAddr: netip.MustParseAddr("::ffff:203.0.113.4"), DstAddr: netip.MustParseAddr("::ffff:203.0.113.5"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 84, - schema.ColumnDstPort: 2048, - schema.ColumnEType: 2048, - schema.ColumnICMPv4Type: 8, // Code: 0 - schema.ColumnPackets: 1, - schema.ColumnProto: 1, + schema.ColumnBytes: uint64(84), + schema.ColumnDstPort: uint16(2048), + schema.ColumnEType: uint32(2048), + schema.ColumnICMPv4Type: uint8(8), // Code: 0 + schema.ColumnPackets: uint64(1), + schema.ColumnProto: uint32(1), }, }, { @@ -460,16 +460,16 @@ func TestDecodeICMP(t *testing.T) { SrcAddr: netip.MustParseAddr("::ffff:203.0.113.5"), DstAddr: netip.MustParseAddr("::ffff:203.0.113.4"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 84, - schema.ColumnEType: 2048, - schema.ColumnPackets: 1, - schema.ColumnProto: 1, + schema.ColumnBytes: uint64(84), + schema.ColumnEType: uint32(2048), + schema.ColumnPackets: uint64(1), + schema.ColumnProto: uint32(1), // Type/Code = 0 }, }, } - if diff := helpers.Diff(got, expectedFlows); diff != "" { + if diff := helpers.Diff(got, &expectedFlows); diff != "" { t.Fatalf("Decode() (-got, +want):\n%s", diff) } } @@ -502,21 +502,21 @@ func TestDecodeDataLink(t *testing.T) { InIf: 582, OutIf: 0, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 96, - schema.ColumnSrcPort: 55501, - schema.ColumnDstPort: 11777, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnPackets: 1, - schema.ColumnProto: 17, - schema.ColumnSrcMAC: 0xb402165592f4, - schema.ColumnDstMAC: 0x182ad36e503f, - schema.ColumnIPFragmentID: 0x8f00, - schema.ColumnIPTTL: 119, + schema.ColumnBytes: uint64(96), + schema.ColumnSrcPort: uint16(55501), + schema.ColumnDstPort: uint16(11777), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnPackets: uint64(1), + schema.ColumnProto: uint32(17), + schema.ColumnSrcMAC: uint64(0xb402165592f4), + schema.ColumnDstMAC: uint64(0x182ad36e503f), + schema.ColumnIPFragmentID: uint32(0x8f00), + schema.ColumnIPTTL: uint8(119), }, }, } - if diff := helpers.Diff(got, expectedFlows); diff != "" { + if diff := helpers.Diff(got, &expectedFlows); diff != "" { t.Fatalf("Decode() (-got, +want):\n%s", diff) } } @@ -534,7 +534,7 @@ func TestDecodeWithoutTemplate(t *testing.T) { } expectedFlows := []*schema.FlowMessage{} - if diff := helpers.Diff(got, expectedFlows); diff != "" { + if diff := helpers.Diff(got, &expectedFlows); diff != "" { t.Fatalf("Decode() (-got, +want):\n%s", diff) } } @@ -560,14 +560,14 @@ func TestDecodeMPLS(t *testing.T) { SamplingRate: 10, OutIf: 16, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 89, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnForwardingStatus: 66, - schema.ColumnIPTTL: 255, - schema.ColumnProto: 17, - schema.ColumnSrcPort: 49153, - schema.ColumnDstPort: 862, + schema.ColumnBytes: uint64(89), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnForwardingStatus: uint32(66), + schema.ColumnIPTTL: uint8(255), + schema.ColumnProto: uint32(17), + schema.ColumnSrcPort: uint16(49153), + schema.ColumnDstPort: uint16(862), schema.ColumnMPLSLabels: []uint32{20005, 524250}, }, }, { @@ -578,20 +578,20 @@ func TestDecodeMPLS(t *testing.T) { SamplingRate: 10, OutIf: 17, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 890, - schema.ColumnPackets: 10, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnForwardingStatus: 66, - schema.ColumnIPTTL: 255, - schema.ColumnProto: 17, - schema.ColumnSrcPort: 49153, - schema.ColumnDstPort: 862, + schema.ColumnBytes: uint64(890), + schema.ColumnPackets: uint64(10), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnForwardingStatus: uint32(66), + schema.ColumnIPTTL: uint8(255), + schema.ColumnProto: uint32(17), + schema.ColumnSrcPort: uint16(49153), + schema.ColumnDstPort: uint16(862), schema.ColumnMPLSLabels: []uint32{20006, 524275}, }, }, } - if diff := helpers.Diff(got, expectedFlows); diff != "" { + if diff := helpers.Diff(got, &expectedFlows); diff != "" { t.Fatalf("Decode() (-got, +want):\n%s", diff) } } @@ -633,13 +633,13 @@ func TestDecodeNFv5(t *testing.T) { SrcNetMask: 19, DstNetMask: 24, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 133, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 30104, - schema.ColumnDstPort: 11963, - schema.ColumnTCPFlags: 0x18, + schema.ColumnBytes: uint64(133), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(30104), + schema.ColumnDstPort: uint16(11963), + schema.ColumnTCPFlags: uint16(0x18), }, }, } @@ -742,14 +742,14 @@ func TestDecodeNAT(t *testing.T) { SrcAddr: netip.MustParseAddr("::ffff:172.16.100.198"), DstAddr: netip.MustParseAddr("::ffff:10.89.87.1"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnSrcPort: 35303, - schema.ColumnDstPort: 53, + schema.ColumnSrcPort: uint16(35303), + schema.ColumnDstPort: uint16(53), schema.ColumnSrcAddrNAT: netip.MustParseAddr("::ffff:10.143.52.29"), schema.ColumnDstAddrNAT: netip.MustParseAddr("::ffff:10.89.87.1"), - schema.ColumnSrcPortNAT: 35303, - schema.ColumnDstPortNAT: 53, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 17, + schema.ColumnSrcPortNAT: uint16(35303), + schema.ColumnDstPortNAT: uint16(53), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(17), }, }, } @@ -785,15 +785,15 @@ func TestDecodePhysicalInterfaces(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:212.82.101.24"), NextHop: netip.MustParseAddr("::"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnSrcMAC: 0xc014fef6c365, - schema.ColumnDstMAC: 0xe8b6c24ae34c, - schema.ColumnPackets: 3, - schema.ColumnBytes: 4506, - schema.ColumnSrcPort: 55629, - schema.ColumnDstPort: 993, - schema.ColumnTCPFlags: 0x10, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, + schema.ColumnSrcMAC: uint64(0xc014fef6c365), + schema.ColumnDstMAC: uint64(0xe8b6c24ae34c), + schema.ColumnPackets: uint64(3), + schema.ColumnBytes: uint64(4506), + schema.ColumnSrcPort: uint16(55629), + schema.ColumnDstPort: uint16(993), + schema.ColumnTCPFlags: uint16(0x10), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), }, }, } diff --git a/outlet/flow/decoder/sflow/root_test.go b/outlet/flow/decoder/sflow/root_test.go index c0695e2f..c290084e 100644 --- a/outlet/flow/decoder/sflow/root_test.go +++ b/outlet/flow/decoder/sflow/root_test.go @@ -51,18 +51,18 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("2a0c:8880:2:0:185:21:130:39"), ExporterAddress: netip.MustParseAddr("::ffff:172.16.0.3"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 0x8, - schema.ColumnIPv6FlowLabel: 0x68094, - schema.ColumnTCPFlags: 0x10, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(0x8), + schema.ColumnIPv6FlowLabel: uint32(0x68094), + schema.ColumnTCPFlags: uint16(0x10), }, }, { SamplingRate: 1024, @@ -78,17 +78,17 @@ func TestDecode(t *testing.T) { SrcNetMask: 20, DstNetMask: 27, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 421, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 443, - schema.ColumnDstPort: 56876, - schema.ColumnSrcMAC: 216372595274807, - schema.ColumnDstMAC: 191421060163210, - schema.ColumnIPFragmentID: 0xa572, - schema.ColumnIPTTL: 59, - schema.ColumnTCPFlags: 0x18, + schema.ColumnBytes: uint64(421), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(443), + schema.ColumnDstPort: uint16(56876), + schema.ColumnSrcMAC: uint64(216372595274807), + schema.ColumnDstMAC: uint64(191421060163210), + schema.ColumnIPFragmentID: uint32(0xa572), + schema.ColumnIPTTL: uint8(59), + schema.ColumnTCPFlags: uint16(0x18), }, }, { SamplingRate: 1024, @@ -100,18 +100,18 @@ func TestDecode(t *testing.T) { SrcVlan: 100, DstVlan: 100, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 0x8, - schema.ColumnIPv6FlowLabel: 0x68094, - schema.ColumnTCPFlags: 0x10, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(0x8), + schema.ColumnIPv6FlowLabel: uint32(0x68094), + schema.ColumnTCPFlags: uint16(0x10), }, }, { SamplingRate: 1024, @@ -127,19 +127,19 @@ func TestDecode(t *testing.T) { SrcNetMask: 27, DstNetMask: 17, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 40, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 55658, - schema.ColumnDstPort: 5555, - schema.ColumnSrcMAC: 138617863011056, - schema.ColumnDstMAC: 216372595274807, + schema.ColumnBytes: uint64(40), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(55658), + schema.ColumnDstPort: uint16(5555), + schema.ColumnSrcMAC: uint64(138617863011056), + schema.ColumnDstMAC: uint64(216372595274807), schema.ColumnDstASPath: []uint32{203698, 6762, 26615}, - schema.ColumnDstCommunities: []uint64{2583495656, 2583495657, 4259880000, 4259880001, 4259900001}, - schema.ColumnIPFragmentID: 0xd431, - schema.ColumnIPTTL: 255, - schema.ColumnTCPFlags: 0x2, + schema.ColumnDstCommunities: []uint32{2583495656, 2583495657, 4259880000, 4259880001, 4259900001}, + schema.ColumnIPFragmentID: uint32(0xd431), + schema.ColumnIPTTL: uint8(255), + schema.ColumnTCPFlags: uint16(0x2), }, }, { SamplingRate: 1024, @@ -151,18 +151,18 @@ func TestDecode(t *testing.T) { SrcVlan: 100, DstVlan: 100, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 0x8, - schema.ColumnIPv6FlowLabel: 0x68094, - schema.ColumnTCPFlags: 0x10, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(0x8), + schema.ColumnIPv6FlowLabel: uint32(0x68094), + schema.ColumnTCPFlags: uint16(0x10), }, }, } @@ -205,18 +205,18 @@ func TestDecode(t *testing.T) { SrcVlan: 100, DstVlan: 100, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnTCPFlags: 16, - schema.ColumnIPv6FlowLabel: 426132, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 8, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnIPv6FlowLabel: uint32(426132), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(8), }, }, } @@ -246,19 +246,19 @@ func TestDecode(t *testing.T) { SrcVlan: 100, DstVlan: 100, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnForwardingStatus: 128, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnTCPFlags: 16, - schema.ColumnIPv6FlowLabel: 426132, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 8, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnForwardingStatus: uint32(128), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnIPv6FlowLabel: uint32(426132), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(8), }, }, } @@ -288,18 +288,18 @@ func TestDecode(t *testing.T) { SrcVlan: 100, DstVlan: 100, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1500, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 46026, - schema.ColumnDstPort: 22, - schema.ColumnSrcMAC: 40057391053392, - schema.ColumnDstMAC: 40057381862408, - schema.ColumnTCPFlags: 16, - schema.ColumnIPv6FlowLabel: 426132, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 8, + schema.ColumnBytes: uint64(1500), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(46026), + schema.ColumnDstPort: uint16(22), + schema.ColumnSrcMAC: uint64(40057391053392), + schema.ColumnDstMAC: uint64(40057381862408), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnIPv6FlowLabel: uint32(426132), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(8), }, }, } @@ -333,20 +333,20 @@ func TestDecode(t *testing.T) { SrcNetMask: 32, DstNetMask: 22, OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 104, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcPort: 22, - schema.ColumnDstPort: 52237, + schema.ColumnBytes: uint64(104), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcPort: uint16(22), + schema.ColumnDstPort: uint16(52237), schema.ColumnDstASPath: []uint32{8218, 29605, 203361}, - schema.ColumnDstCommunities: []uint64{538574949, 1911619684, 1911669584, 1911671290}, - schema.ColumnTCPFlags: 0x18, - schema.ColumnIPFragmentID: 0xab4e, - schema.ColumnIPTTL: 61, - schema.ColumnIPTos: 0x8, - schema.ColumnSrcMAC: 0x948ed30a713b, - schema.ColumnDstMAC: 0x22421f4a9fcd, + schema.ColumnDstCommunities: []uint32{538574949, 1911619684, 1911669584, 1911671290}, + schema.ColumnTCPFlags: uint16(0x18), + schema.ColumnIPFragmentID: uint32(0xab4e), + schema.ColumnIPTTL: uint8(61), + schema.ColumnIPTos: uint8(0x8), + schema.ColumnSrcMAC: uint64(0x948ed30a713b), + schema.ColumnDstMAC: uint64(0x22421f4a9fcd), }, }, } @@ -375,16 +375,16 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:51.51.51.51"), ExporterAddress: netip.MustParseAddr("::ffff:49.49.49.49"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 1344, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 17, - schema.ColumnSrcPort: 46622, - schema.ColumnDstPort: 58631, - schema.ColumnSrcMAC: 1094287164743, - schema.ColumnDstMAC: 1101091482116, - schema.ColumnIPFragmentID: 41647, - schema.ColumnIPTTL: 64, + schema.ColumnBytes: uint64(1344), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(17), + schema.ColumnSrcPort: uint16(46622), + schema.ColumnDstPort: uint16(58631), + schema.ColumnSrcMAC: uint64(1094287164743), + schema.ColumnDstMAC: uint64(1101091482116), + schema.ColumnIPFragmentID: uint32(41647), + schema.ColumnIPTTL: uint8(64), }, }, } @@ -412,13 +412,13 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:92.222.186.1"), ExporterAddress: netip.MustParseAddr("::ffff:172.19.64.116"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 32, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 1, - schema.ColumnIPFragmentID: 4329, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 8, + schema.ColumnBytes: uint64(32), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(1), + schema.ColumnIPFragmentID: uint32(4329), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(8), }, }, { SamplingRate: 1, @@ -428,13 +428,13 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:92.222.184.1"), ExporterAddress: netip.MustParseAddr("::ffff:172.19.64.116"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 32, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 1, - schema.ColumnIPFragmentID: 62945, - schema.ColumnIPTTL: 64, - schema.ColumnIPTos: 8, + schema.ColumnBytes: uint64(32), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(1), + schema.ColumnIPFragmentID: uint32(62945), + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPTos: uint8(8), }, }, } @@ -460,16 +460,16 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:203.0.113.5"), ExporterAddress: netip.MustParseAddr("::ffff:127.0.0.1"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 84, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 1, - schema.ColumnDstMAC: 0xd25b45ee5ecf, - schema.ColumnSrcMAC: 0xe2efc68f8cd4, - schema.ColumnICMPv4Type: 8, + schema.ColumnBytes: uint64(84), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(1), + schema.ColumnDstMAC: uint64(0xd25b45ee5ecf), + schema.ColumnSrcMAC: uint64(0xe2efc68f8cd4), + schema.ColumnICMPv4Type: uint8(8), // schema.ColumnICMPv4Code: 0, - schema.ColumnIPTTL: 64, - schema.ColumnIPFragmentID: 0x90c5, + schema.ColumnIPTTL: uint8(64), + schema.ColumnIPFragmentID: uint32(0x90c5), }, }, } @@ -495,14 +495,14 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("2001:db8::"), ExporterAddress: netip.MustParseAddr("::ffff:127.0.0.1"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 72, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv6, - schema.ColumnProto: 58, - schema.ColumnSrcMAC: 0xd25b45ee5ecf, - schema.ColumnDstMAC: 0xe2efc68f8cd4, - schema.ColumnIPTTL: 255, - schema.ColumnICMPv6Type: 135, + schema.ColumnBytes: uint64(72), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv6), + schema.ColumnProto: uint32(58), + schema.ColumnSrcMAC: uint64(0xd25b45ee5ecf), + schema.ColumnDstMAC: uint64(0xe2efc68f8cd4), + schema.ColumnIPTTL: uint8(255), + schema.ColumnICMPv6Type: uint8(135), // schema.ColumnICMPv6Code: 0, }, }, @@ -532,17 +532,17 @@ func TestDecode(t *testing.T) { DstAddr: netip.MustParseAddr("::ffff:49.49.49.109"), ExporterAddress: netip.MustParseAddr("::ffff:172.17.128.58"), OtherColumns: map[schema.ColumnKey]any{ - schema.ColumnBytes: 80, - schema.ColumnPackets: 1, - schema.ColumnEType: helpers.ETypeIPv4, - schema.ColumnProto: 6, - schema.ColumnSrcMAC: 0x4caea3520ff6, - schema.ColumnDstMAC: 0x000110621493, - schema.ColumnIPTTL: 62, - schema.ColumnIPFragmentID: 56159, - schema.ColumnTCPFlags: 16, - schema.ColumnSrcPort: 32017, - schema.ColumnDstPort: 443, + schema.ColumnBytes: uint64(80), + schema.ColumnPackets: uint64(1), + schema.ColumnEType: uint32(helpers.ETypeIPv4), + schema.ColumnProto: uint32(6), + schema.ColumnSrcMAC: uint64(0x4caea3520ff6), + schema.ColumnDstMAC: uint64(0x000110621493), + schema.ColumnIPTTL: uint8(62), + schema.ColumnIPFragmentID: uint32(56159), + schema.ColumnTCPFlags: uint16(16), + schema.ColumnSrcPort: uint16(32017), + schema.ColumnDstPort: uint16(443), }, }, } diff --git a/outlet/metadata/cache_test.go b/outlet/metadata/cache_test.go index 53444f20..ae5c98ff 100644 --- a/outlet/metadata/cache_test.go +++ b/outlet/metadata/cache_test.go @@ -289,31 +289,31 @@ func TestNeedUpdates(t *testing.T) { cases := []struct { Minutes time.Duration - Expected map[string][]uint + Expected map[netip.Addr][]uint }{ - {9, map[string][]uint{ - "::ffff:127.0.0.1": { + {9, map[netip.Addr][]uint{ + netip.MustParseAddr("::ffff:127.0.0.1"): { 676, 678, }, - "::ffff:127.0.0.2": { + netip.MustParseAddr("::ffff:127.0.0.2"): { 678, }, }}, - {19, map[string][]uint{ - "::ffff:127.0.0.1": { + {19, map[netip.Addr][]uint{ + netip.MustParseAddr("::ffff:127.0.0.1"): { 678, }, - "::ffff:127.0.0.2": { + netip.MustParseAddr("::ffff:127.0.0.2"): { 678, }, }}, - {29, map[string][]uint{ - "::ffff:127.0.0.1": { + {29, map[netip.Addr][]uint{ + netip.MustParseAddr("::ffff:127.0.0.1"): { 678, }, }}, - {39, map[string][]uint{}}, + {39, map[netip.Addr][]uint{}}, } for _, tc := range cases { t.Run(fmt.Sprintf("%d minutes", tc.Minutes), func(t *testing.T) { diff --git a/outlet/metadata/provider/gnmi/collector_test.go b/outlet/metadata/provider/gnmi/collector_test.go index e765971f..5a1e2e06 100644 --- a/outlet/metadata/provider/gnmi/collector_test.go +++ b/outlet/metadata/provider/gnmi/collector_test.go @@ -8,6 +8,8 @@ import ( "akvorado/common/helpers" "akvorado/outlet/metadata/provider" + + "github.com/google/go-cmp/cmp/cmpopts" ) func TestStateUpdate(t *testing.T) { @@ -28,7 +30,7 @@ func TestStateUpdate(t *testing.T) { Name: "", Interfaces: map[uint]provider.Interface{}, } - if diff := helpers.Diff(state, expected); diff != "" { + if diff := helpers.Diff(state, expected, cmpopts.IgnoreUnexported(state)); diff != "" { t.Fatalf("udpate() (-got, +want):\n%s", diff) } @@ -90,7 +92,7 @@ func TestStateUpdate(t *testing.T) { }, }, } - if diff := helpers.Diff(state, expected); diff != "" { + if diff := helpers.Diff(state, expected, cmpopts.IgnoreUnexported(state)); diff != "" { t.Fatalf("udpate() (-got, +want):\n%s", diff) } } diff --git a/outlet/metadata/provider/snmp/tests.go b/outlet/metadata/provider/snmp/tests.go index 57596be1..bffd4657 100644 --- a/outlet/metadata/provider/snmp/tests.go +++ b/outlet/metadata/provider/snmp/tests.go @@ -6,12 +6,9 @@ package snmp import ( - "fmt" - "reflect" - "akvorado/common/helpers" ) func init() { - helpers.AddPrettyFormatter(reflect.TypeOf(helpers.SubnetMap[Credentials]{}), fmt.Sprint) + helpers.RegisterSubnetMapCmp[Credentials]() } diff --git a/outlet/metadata/provider/static/tests.go b/outlet/metadata/provider/static/tests.go index 0f2ccb4e..0a5b8eb0 100644 --- a/outlet/metadata/provider/static/tests.go +++ b/outlet/metadata/provider/static/tests.go @@ -6,12 +6,9 @@ package static import ( - "fmt" - "reflect" - "akvorado/common/helpers" ) func init() { - helpers.AddPrettyFormatter(reflect.TypeOf(helpers.SubnetMap[ExporterConfiguration]{}), fmt.Sprint) + helpers.RegisterSubnetMapCmp[ExporterConfiguration]() } diff --git a/outlet/routing/provider/bmp/rib_test.go b/outlet/routing/provider/bmp/rib_test.go index f0adc542..815ebc81 100644 --- a/outlet/routing/provider/bmp/rib_test.go +++ b/outlet/routing/provider/bmp/rib_test.go @@ -206,7 +206,7 @@ func TestRemoveRoutes(t *testing.T) { if count != 1 { t.Error("removeRoutes() should have removed 1 route") } - if diff := helpers.Diff(r.routes, map[prefixIndex]route{}); diff != "" { + if diff := helpers.Diff(r.routes, map[routeKey]route{}); diff != "" { t.Errorf("removeRoutes() (-got, +want):\n%s", diff) } }) diff --git a/outlet/routing/provider/bmp/tests.go b/outlet/routing/provider/bmp/tests.go index 3f20bbb6..a62ce961 100644 --- a/outlet/routing/provider/bmp/tests.go +++ b/outlet/routing/provider/bmp/tests.go @@ -6,10 +6,8 @@ package bmp import ( - "fmt" "net" "net/netip" - "reflect" "testing" "akvorado/common/daemon" @@ -18,6 +16,7 @@ import ( "akvorado/outlet/routing/provider" "github.com/benbjohnson/clock" + "github.com/google/go-cmp/cmp" "github.com/osrg/gobgp/v3/pkg/packet/bgp" "github.com/osrg/gobgp/v3/pkg/packet/bmp" ) @@ -149,5 +148,5 @@ func MustParseRD(input string) RD { } func init() { - helpers.AddPrettyFormatter(reflect.TypeOf(route{}), fmt.Sprint) + helpers.RegisterCmpOption(cmp.AllowUnexported(route{})) }