Files
akvorado/common/schema/root_test.go
2024-01-22 20:34:08 +01:00

242 lines
7.9 KiB
Go

// SPDX-FileCopyrightText: 2023 Free Mobile
// SPDX-License-Identifier: AGPL-3.0-only
package schema_test
import (
"testing"
"akvorado/common/helpers"
"akvorado/common/schema"
)
func TestEnableDisableColumns(t *testing.T) {
config := schema.DefaultConfiguration()
config.Enabled = []schema.ColumnKey{schema.ColumnDstVlan, schema.ColumnSrcVlan}
config.Disabled = []schema.ColumnKey{schema.ColumnSrcCountry, schema.ColumnDstCountry}
c, err := schema.New(config)
if err != nil {
t.Fatalf("New() error:\n%+v", err)
}
if column, ok := c.LookupColumnByKey(schema.ColumnDstVlan); !ok {
t.Fatal("DstVlan not found")
} else if column.Disabled {
t.Fatal("DstVlan is still disabled")
}
if column, ok := c.LookupColumnByKey(schema.ColumnDstCountry); !ok {
t.Fatal("DstCountry not found")
} else if !column.Disabled {
t.Fatal("DstCountry is not disabled")
}
}
func TestDisableForbiddenColumns(t *testing.T) {
config := schema.DefaultConfiguration()
config.Disabled = []schema.ColumnKey{schema.ColumnDst1stAS}
if _, err := schema.New(config); err == nil {
t.Fatal("New() did not error")
}
config = schema.DefaultConfiguration()
config.Disabled = []schema.ColumnKey{schema.ColumnDstLargeCommunitiesASN}
if _, err := schema.New(config); err == nil {
t.Fatal("New() did not error")
}
config = schema.DefaultConfiguration()
config.Disabled = []schema.ColumnKey{schema.ColumnDstLargeCommunities}
if _, err := schema.New(config); err == nil {
t.Fatal("New() did not error")
}
config = schema.DefaultConfiguration()
config.Disabled = []schema.ColumnKey{
schema.ColumnDstLargeCommunities,
schema.ColumnDstLargeCommunitiesASN,
schema.ColumnDstLargeCommunitiesLocalData1,
schema.ColumnDstLargeCommunitiesLocalData2,
}
if _, err := schema.New(config); err != nil {
t.Fatalf("New() error:\n%+v", err)
}
}
func TestCustomDictionaries(t *testing.T) {
config := schema.DefaultConfiguration()
config.CustomDictionaries = make(map[string]schema.CustomDict)
config.CustomDictionaries["test"] = schema.CustomDict{
Keys: []schema.CustomDictKey{
{Name: "SrcAddr", Type: "string"},
},
Attributes: []schema.CustomDictAttribute{
{Name: "csv_col_name", Type: "string", Label: "DimensionAttribute"},
{Name: "role", Type: "string"},
},
Source: "test.csv",
Dimensions: []string{"SrcAddr", "DstAddr"},
}
s, err := schema.New(config)
if err != nil {
t.Fatalf("New() error:\n%+v", err)
}
// Test if SrcAddrAttribute and DstAddrAttribute are in s.columns
srcFound := false
dstFound := false
srcRoleFound := false
dstRoleFound := false
// Check if srcAddrAttribute and dstAddrAttribute are in s.columns, and have the correct type/generatefrom
for _, column := range s.Columns() {
if column.Name == "SrcAddrDimensionAttribute" {
srcFound = true
if column.ClickHouseType != "LowCardinality(string)" {
t.Fatalf("SrcAddrDimensionAttribute should be LowCardinality(string), is %s", column.ClickHouseType)
}
if column.ClickHouseGenerateFrom != "dictGet('custom_dict_test', 'csv_col_name', SrcAddr)" {
t.Fatalf("SrcAddrDimensionAttribute should be generated from `dictGet('custom_dict_test', 'csv_col_name', SrcAddr)`, is %s", column.ClickHouseGenerateFrom)
}
}
if column.Name == "DstAddrDimensionAttribute" {
dstFound = true
if column.ClickHouseType != "LowCardinality(string)" {
t.Fatalf("DstAddrDimensionAttribute should be LowCardinality(string), is %s", column.ClickHouseType)
}
if column.ClickHouseGenerateFrom != "dictGet('custom_dict_test', 'csv_col_name', DstAddr)" {
t.Fatalf("DstAddrDimensionAttribute should be generated from `dictGet('custom_dict_test', 'csv_col_name', DstAddr)`, is %s", column.ClickHouseGenerateFrom)
}
}
// This part only tests default dimension name generation
if column.Name == "SrcAddrRole" {
srcRoleFound = true
}
if column.Name == "DstAddrRole" {
dstRoleFound = true
}
}
if !srcFound {
t.Fatal("SrcAddrDimensionAttribute not found")
}
if !dstFound {
t.Fatal("DstAddrDimensionAttribute not found")
}
if !srcRoleFound {
t.Fatal("SrcAddrRole not found")
}
if !dstRoleFound {
t.Fatal("DstAddrRole not found")
}
}
func TestCustomDictionariesMatcher(t *testing.T) {
config := schema.DefaultConfiguration()
config.CustomDictionaries = make(map[string]schema.CustomDict)
config.CustomDictionaries["test"] = schema.CustomDict{
Keys: []schema.CustomDictKey{
{Name: "exporter", Type: "string", MatchDimension: "ExporterAddress"},
{Name: "interface", Type: "string", MatchDimensionSuffix: "Name"},
},
Attributes: []schema.CustomDictAttribute{
{Name: "csv_col_name", Type: "string", Label: "DimensionAttribute"},
},
Source: "test.csv",
Dimensions: []string{"OutIf", "InIf"},
Layout: "complex_key_hashed",
}
s, err := schema.New(config)
if err != nil {
t.Fatalf("New() error:\n%+v", err)
}
// Test if SrcAddrAttribute and DstAddrAttribute are in s.columns
outFound := false
inFound := false
// Check if srcAddrAttribute and dstAddrAttribute are in s.columns, and have the correct type/generatefrom
for _, column := range s.Columns() {
if column.Name == "OutIfDimensionAttribute" {
outFound = true
if column.ClickHouseType != "LowCardinality(string)" {
t.Fatalf("OutIfDimensionAttribute should be LowCardinality(string), is %s", column.ClickHouseType)
}
if column.ClickHouseGenerateFrom != "dictGet('custom_dict_test', 'csv_col_name', (ExporterAddress,OutIfName))" {
t.Fatalf("OutIfDimensionAttribute should be generated from `dictGet('custom_dict_test', 'csv_col_name', (ExporterAddress,OutIfName))`, is %s", column.ClickHouseGenerateFrom)
}
}
if column.Name == "InIfDimensionAttribute" {
inFound = true
if column.ClickHouseType != "LowCardinality(string)" {
t.Fatalf("InIfDimensionAttribute should be LowCardinality(string), is %s", column.ClickHouseType)
}
if column.ClickHouseGenerateFrom != "dictGet('custom_dict_test', 'csv_col_name', (ExporterAddress,InIfName))" {
t.Fatalf("InIfDimensionAttribute should be generated from `dictGet('custom_dict_test', 'csv_col_name', (ExporterAddress,InIfName)), is %s", column.ClickHouseGenerateFrom)
}
}
}
if !outFound {
t.Fatal("OutIfDimensionAttribute not found")
}
if !inFound {
t.Fatal("InIfDimensionAttribute not found")
}
}
// We need MatchDimension or MatchDimensionSuffix for multiple keys
func TestCustomDictMultiKeyErr(t *testing.T) {
config := schema.DefaultConfiguration()
config.CustomDictionaries = make(map[string]schema.CustomDict)
config.CustomDictionaries["test"] = schema.CustomDict{
Keys: []schema.CustomDictKey{
{Name: "exporter", Type: "string"},
{Name: "interface", Type: "string"},
},
Attributes: []schema.CustomDictAttribute{
{Name: "csv_col_name", Type: "string", Label: "DimensionAttribute"},
},
Source: "test.csv",
Dimensions: []string{"OutIf", "InIf"},
Layout: "complex_key_hashed",
}
_, err := schema.New(config)
if err == nil {
t.Fatal("New() did not error")
}
if diff := helpers.Diff(err.Error(), "custom dictionary test has more than one key, but key exporter has neither MatchDimension nor MatchDimensionSuffix set"); diff != "" {
t.Fatalf("New() did not error correctly\n %s", diff)
}
}
// A dict without key makes no sense, catch this
func TestCustomDictNoKeyErr(t *testing.T) {
config := schema.DefaultConfiguration()
config.CustomDictionaries = make(map[string]schema.CustomDict)
config.CustomDictionaries["test"] = schema.CustomDict{
Keys: []schema.CustomDictKey{},
Attributes: []schema.CustomDictAttribute{
{Name: "csv_col_name", Type: "string", Label: "DimensionAttribute"},
},
Source: "test.csv",
Dimensions: []string{"OutIf", "InIf"},
Layout: "complex_key_hashed",
}
_, err := schema.New(config)
if err == nil {
t.Fatal("New() did not error")
}
if diff := helpers.Diff(err.Error(), "custom dictionary test has no keys, this is not supported"); diff != "" {
t.Fatalf("New() did not error correctly\n %s", diff)
}
}