diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 12:08:18 +0000 |
commit | 5da14042f70711ea5cf66e034699730335462f66 (patch) | |
tree | 0f6354ccac934ed87a2d555f45be4c831cf92f4a /src/go/collectors/go.d.plugin/pkg/logs/csv_test.go | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-5da14042f70711ea5cf66e034699730335462f66.tar.xz netdata-5da14042f70711ea5cf66e034699730335462f66.zip |
Merging upstream version 1.45.3+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/go/collectors/go.d.plugin/pkg/logs/csv_test.go')
-rw-r--r-- | src/go/collectors/go.d.plugin/pkg/logs/csv_test.go | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/pkg/logs/csv_test.go b/src/go/collectors/go.d.plugin/pkg/logs/csv_test.go new file mode 100644 index 000000000..d7baaa1b5 --- /dev/null +++ b/src/go/collectors/go.d.plugin/pkg/logs/csv_test.go @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package logs + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var testCSVConfig = CSVConfig{ + Delimiter: " ", + Format: "$A %B", +} + +func TestNewCSVParser(t *testing.T) { + tests := []struct { + name string + format string + wantErr bool + }{ + {name: "valid format", format: "$A $B"}, + {name: "empty format", wantErr: true}, + {name: "bad format: csv read error", format: "$A $B \"$C", wantErr: true}, + {name: "bad format: duplicate fields", format: "$A $A", wantErr: true}, + {name: "bad format: zero fields", format: "!A !B", wantErr: true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := testCSVConfig + c.Format = tt.format + p, err := NewCSVParser(c, nil) + if tt.wantErr { + assert.Error(t, err) + assert.Nil(t, p) + } else { + assert.NoError(t, err) + assert.NotNil(t, p) + } + }) + } +} + +func TestNewCSVFormat(t *testing.T) { + tests := []struct { + format string + wantFormat csvFormat + wantErr bool + }{ + {format: "$A $B", wantFormat: csvFormat{maxIndex: 1, fields: []csvField{{"$A", 0}, {"$B", 1}}}}, + {format: "$A $B !C $E", wantFormat: csvFormat{maxIndex: 3, fields: []csvField{{"$A", 0}, {"$B", 1}, {"$E", 3}}}}, + {format: "!A !B !C $E", wantFormat: csvFormat{maxIndex: 3, fields: []csvField{{"$E", 3}}}}, + {format: "$A $OFFSET $B", wantFormat: csvFormat{maxIndex: 3, fields: []csvField{{"$A", 0}, {"$B", 3}}}}, + {format: "$A $OFFSET $B $OFFSET !A", wantFormat: csvFormat{maxIndex: 3, fields: []csvField{{"$A", 0}, {"$B", 3}}}}, + {format: "$A $OFFSET $OFFSET $B", wantFormat: csvFormat{maxIndex: 5, fields: []csvField{{"$A", 0}, {"$B", 5}}}}, + {format: "$OFFSET $A $OFFSET $B", wantFormat: csvFormat{maxIndex: 5, fields: []csvField{{"$A", 2}, {"$B", 5}}}}, + {format: "$A \"$A", wantErr: true}, + {format: "$A $A", wantErr: true}, + {format: "!A !A", wantErr: true}, + {format: "", wantErr: true}, + } + + for _, tt := range tests { + t.Run(tt.format, func(t *testing.T) { + c := testCSVConfig + c.Format = tt.format + c.CheckField = testCheckCSVFormatField + tt.wantFormat.raw = tt.format + + f, err := newCSVFormat(c) + + if tt.wantErr { + assert.Error(t, err) + assert.Nil(t, f) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantFormat, *f) + } + }) + } +} + +func TestCSVParser_ReadLine(t *testing.T) { + tests := []struct { + name string + row string + format string + wantErr bool + wantParseErr bool + }{ + {name: "match and no error", row: "1 2 3", format: `$A $B $C`}, + {name: "match but error on assigning", row: "1 2 3", format: `$A $B $ERR`, wantErr: true, wantParseErr: true}, + {name: "not match", row: "1 2 3", format: `$A $B $C $d`, wantErr: true, wantParseErr: true}, + {name: "error on reading csv.Err", row: "1 2\"3", format: `$A $B $C`, wantErr: true, wantParseErr: true}, + {name: "error on reading EOF", row: "", format: `$A $B $C`, wantErr: true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var line logLine + r := strings.NewReader(tt.row) + c := testCSVConfig + c.Format = tt.format + p, err := NewCSVParser(c, r) + require.NoError(t, err) + + err = p.ReadLine(&line) + + if tt.wantErr { + require.Error(t, err) + if tt.wantParseErr { + assert.True(t, IsParseError(err)) + } else { + assert.False(t, IsParseError(err)) + } + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestCSVParser_Parse(t *testing.T) { + tests := []struct { + name string + row string + format string + wantErr bool + }{ + {name: "match and no error", row: "1 2 3", format: `$A $B $C`}, + {name: "match but error on assigning", row: "1 2 3", format: `$A $B $ERR`, wantErr: true}, + {name: "not match", row: "1 2 3", format: `$A $B $C $d`, wantErr: true}, + {name: "error on reading csv.Err", row: "1 2\"3", format: `$A $B $C`, wantErr: true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var line logLine + r := strings.NewReader(tt.row) + c := testCSVConfig + c.Format = tt.format + p, err := NewCSVParser(c, r) + require.NoError(t, err) + + err = p.ReadLine(&line) + + if tt.wantErr { + require.Error(t, err) + assert.True(t, IsParseError(err)) + } else { + assert.NoError(t, err) + } + }) + } + +} + +func TestCSVParser_Info(t *testing.T) { + p, err := NewCSVParser(testCSVConfig, nil) + require.NoError(t, err) + assert.NotZero(t, p.Info()) +} + +func testCheckCSVFormatField(name string) (newName string, offset int, valid bool) { + if len(name) < 2 || !strings.HasPrefix(name, "$") { + return "", 0, false + } + if name == "$OFFSET" { + return "", 1, false + } + return name, 0, true +} |