summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/pkg/logs/regexp_test.go
blob: fc7bacaa5e39211abb2f2937aaae8346e6586cb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-License-Identifier: GPL-3.0-or-later

package logs

import (
	"errors"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestNewRegExpParser(t *testing.T) {
	tests := []struct {
		name    string
		pattern string
		wantErr bool
	}{
		{name: "valid pattern", pattern: `(?P<A>\d+) (?P<B>\d+)`},
		{name: "no names subgroups in pattern", pattern: `(?:\d+) (?:\d+)`, wantErr: true},
		{name: "invalid pattern", pattern: `(((?P<A>\d+) (?P<B>\d+)`, wantErr: true},
		{name: "empty pattern", wantErr: true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, nil)
			if tt.wantErr {
				assert.Error(t, err)
				assert.Nil(t, p)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, p)
			}
		})
	}
}

func TestRegExpParser_ReadLine(t *testing.T) {
	tests := []struct {
		name         string
		row          string
		pattern      string
		wantErr      bool
		wantParseErr bool
	}{
		{name: "match and no error", row: "1 2", pattern: `(?P<A>\d+) (?P<B>\d+)`},
		{name: "match but error on assigning", row: "1 2", pattern: `(?P<A>\d+) (?P<ERR>\d+)`, wantErr: true, wantParseErr: true},
		{name: "not match", row: "A B", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true, wantParseErr: true},
		{name: "not match multiline", row: "a b\n3 4", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true, wantParseErr: true},
		{name: "error on reading EOF", row: "", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var line logLine
			r := strings.NewReader(tt.row)
			p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, 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 TestRegExpParser_Parse(t *testing.T) {
	tests := []struct {
		name    string
		row     string
		pattern string
		wantErr bool
	}{
		{name: "match and no error", row: "1 2", pattern: `(?P<A>\d+) (?P<B>\d+)`},
		{name: "match but error on assigning", row: "1 2", pattern: `(?P<A>\d+) (?P<ERR>\d+)`, wantErr: true},
		{name: "not match", row: "A B", pattern: `(?P<A>\d+) (?P<B>\d+)`, wantErr: true},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			var line logLine
			p, err := NewRegExpParser(RegExpConfig{Pattern: tt.pattern}, nil)
			require.NoError(t, err)

			err = p.Parse([]byte(tt.row), &line)
			if tt.wantErr {
				require.Error(t, err)
				assert.True(t, IsParseError(err))
			} else {
				assert.NoError(t, err)
			}
		})
	}
}

func TestRegExpParser_Info(t *testing.T) {
	p, err := NewRegExpParser(RegExpConfig{Pattern: `(?P<A>\d+) (?P<B>\d+)`}, nil)
	require.NoError(t, err)
	assert.NotZero(t, p.Info())
}

type logLine struct {
	assigned map[string]string
}

func newLogLine() *logLine {
	return &logLine{
		assigned: make(map[string]string),
	}
}

func (l *logLine) Assign(name, val string) error {
	switch name {
	case "$ERR", "ERR":
		return errors.New("assign error")
	}
	if l.assigned != nil {
		l.assigned[name] = val
	}
	return nil
}