123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- package rfc3164
- import (
- "testing"
- "time"
- )
- func TestPri(t *testing.T) {
- tests := []struct {
- input string
- expected int
- expectedErr string
- }{
- {"<0>", 0, ""},
- {"<19>", 19, ""},
- {"<200>", 200, ""},
- {"<4999>", 0, "PRI must be up to 3 characters long"},
- {"<123", 0, "PRI must end with '>'"},
- {"123>", 0, "PRI must start with '<'"},
- {"<abc>", 0, "PRI must be a number"},
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- r := &RFC3164{}
- r.buf = []byte(test.input)
- r.len = len(r.buf)
- err := r.parsePRI()
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error %s, got %s", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: %s", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error %s, got no error", test.expectedErr)
- } else {
- if r.PRI != test.expected {
- t.Errorf("expected %d, got %d", test.expected, r.PRI)
- }
- }
- }
- })
- }
- }
- func TestTimestamp(t *testing.T) {
- tests := []struct {
- input string
- expected string
- expectedErr string
- currentYear bool
- }{
- {"May 20 09:33:54", "0000-05-20T09:33:54Z", "", false},
- {"May 20 09:33:54", "2022-05-20T09:33:54Z", "", true},
- {"May 20 09:33:54 2022", "2022-05-20T09:33:54Z", "", false},
- {"May 1 09:33:54 2022", "2022-05-01T09:33:54Z", "", false},
- {"May 01 09:33:54 2021", "2021-05-01T09:33:54Z", "", true},
- {"foobar", "", "timestamp is not valid", false},
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- opts := []RFC3164Option{}
- if test.currentYear {
- opts = append(opts, WithCurrentYear())
- }
- r := NewRFC3164Parser(opts...)
- r.buf = []byte(test.input)
- r.len = len(r.buf)
- err := r.parseTimestamp()
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error %s, got %s", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: %s", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error %s, got no error", test.expectedErr)
- } else {
- if r.Timestamp.Format(time.RFC3339) != test.expected {
- t.Errorf("expected %s, got %s", test.expected, r.Timestamp.Format(time.RFC3339))
- }
- }
- }
- })
- }
- }
- func TestHostname(t *testing.T) {
- tests := []struct {
- input string
- expected string
- expectedErr string
- strictHostname bool
- }{
- {"127.0.0.1", "127.0.0.1", "", false},
- {"::1", "::1", "", false},
- {"foo.-bar", "", "hostname is not valid", true},
- {"foo-.bar", "", "hostname is not valid", true},
- {"foo123.bar", "foo123.bar", "", true},
- {"a..", "", "hostname is not valid", true},
- {"foo.bar", "foo.bar", "", false},
- {"foo,bar", "foo,bar", "", false},
- {"foo,bar", "", "hostname is not valid", true},
- {"", "", "hostname is empty", false},
- {".", ".", "", true},
- {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "", "hostname is not valid", true},
- {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bla", "", "hostname is not valid", true},
- {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bla", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bla", "", false},
- {"a.foo-", "", "hostname is not valid", true},
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- opts := []RFC3164Option{}
- if test.strictHostname {
- opts = append(opts, WithStrictHostname())
- }
- r := NewRFC3164Parser(opts...)
- r.buf = []byte(test.input)
- r.len = len(r.buf)
- err := r.parseHostname()
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error %s, got %s", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: %s", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error %s, got no error", test.expectedErr)
- } else {
- if r.Hostname != test.expected {
- t.Errorf("expected %s, got %s", test.expected, r.Hostname)
- }
- }
- }
- })
- }
- }
- func TestTag(t *testing.T) {
- tests := []struct {
- input string
- expected string
- expectedPID string
- expectedErr string
- }{
- {"foobar", "foobar", "", ""},
- {"foobar[42]", "foobar", "42", ""},
- {"", "", "", "tag is empty"},
- {"foobar[", "", "", "pid inside tag must be closed with ']'"},
- {"foobar[42", "", "", "pid inside tag must be closed with ']'"},
- {"foobar[asd]", "foobar", "", "pid inside tag must be a number"},
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- r := &RFC3164{}
- r.buf = []byte(test.input)
- r.len = len(r.buf)
- err := r.parseTag()
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error %s, got %s", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: %s", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error %s, got no error", test.expectedErr)
- } else {
- if r.Tag != test.expected {
- t.Errorf("expected %s, got %s", test.expected, r.Tag)
- }
- if r.PID != test.expectedPID {
- t.Errorf("expected %s, got %s", test.expected, r.Message)
- }
- }
- }
- })
- }
- }
- func TestMessage(t *testing.T) {
- tests := []struct {
- input string
- expected string
- expectedErr string
- }{
- {"foobar: pouet", "pouet", ""},
- {"foobar[42]: test", "test", ""},
- {"foobar[123]: this is a test", "this is a test", ""},
- {"foobar[123]: ", "", "message is empty"},
- {"foobar[123]:", "", "message is empty"},
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- r := &RFC3164{}
- r.buf = []byte(test.input)
- r.len = len(r.buf)
- err := r.parseMessage()
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error %s, got %s", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: %s", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error %s, got no error", test.expectedErr)
- } else {
- if r.Message != test.expected {
- t.Errorf("expected message %s, got %s", test.expected, r.Tag)
- }
- }
- }
- })
- }
- }
- func TestParse(t *testing.T) {
- type expected struct {
- Timestamp time.Time
- Hostname string
- Tag string
- PID string
- Message string
- PRI int
- }
- tests := []struct {
- input string
- expected expected
- expectedErr string
- opts []RFC3164Option
- }{
- {
- "<12>May 20 09:33:54 UDMPRO,a2edd0c6ae48,udm-1.10.0.3686 kernel: foo", expected{
- Timestamp: time.Date(0, time.May, 20, 9, 33, 54, 0, time.UTC),
- Hostname: "UDMPRO,a2edd0c6ae48,udm-1.10.0.3686",
- Tag: "kernel",
- PID: "",
- Message: "foo",
- PRI: 12,
- }, "", []RFC3164Option{},
- },
- {
- "<12>May 20 09:33:54 UDMPRO,a2edd0c6ae48,udm-1.10.0.3686 kernel: foo", expected{
- Timestamp: time.Date(2022, time.May, 20, 9, 33, 54, 0, time.UTC),
- Hostname: "UDMPRO,a2edd0c6ae48,udm-1.10.0.3686",
- Tag: "kernel",
- PID: "",
- Message: "foo",
- PRI: 12,
- }, "", []RFC3164Option{WithCurrentYear()},
- },
- {
- "<12>May 20 09:33:54 UDMPRO,a2edd0c6ae48,udm-1.10.0.3686 kernel: foo", expected{}, "hostname is not valid", []RFC3164Option{WithStrictHostname()},
- },
- {
- "foobar", expected{}, "PRI must start with '<'", []RFC3164Option{},
- },
- {
- "<12>", expected{}, "timestamp is not valid", []RFC3164Option{},
- },
- {
- "<12 May 02 09:33:54 foo.bar", expected{}, "PRI must be a number", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54", expected{}, "hostname is empty", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar", expected{}, "tag is empty", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar bla[42", expected{}, "pid inside tag must be closed with ']'", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar bla[42]", expected{}, "message is empty", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar bla[42]: ", expected{}, "message is empty", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar bla", expected{}, "message is empty", []RFC3164Option{},
- },
- {
- "<12>May 02 09:33:54 foo.bar bla:", expected{}, "message is empty", []RFC3164Option{},
- },
- {
- "", expected{}, "message is empty", []RFC3164Option{},
- },
- {
- `<13>1 2021-05-18T11:58:40.828081+02:00 mantis sshd 49340 - [timeQuality isSynced="0" tzKnown="1"] blabla`, expected{}, "timestamp is not valid", []RFC3164Option{},
- },
- {
- `<46>Jun 2 06:55:39 localhost haproxy[27213]: Connect from 100.100.100.99:52611 to 100.100.100.99:443 (https_shared-merged/HTTP)\\n 10.0.0.1}`, expected{
- Timestamp: time.Date(time.Now().Year(), time.June, 2, 6, 55, 39, 0, time.UTC),
- Hostname: "localhost",
- Tag: "haproxy",
- PID: "27213",
- Message: `Connect from 100.100.100.99:52611 to 100.100.100.99:443 (https_shared-merged/HTTP)\\n 10.0.0.1}`,
- PRI: 46,
- }, "", []RFC3164Option{WithCurrentYear()},
- },
- {
- `<46>Jun 2 06:55:39 2022 localhost haproxy[27213]: Connect from 100.100.100.99:52611 to 100.100.100.99:443 (https_shared-merged/HTTP)\\n 10.0.0.1}`, expected{
- Timestamp: time.Date(2022, time.June, 2, 6, 55, 39, 0, time.UTC),
- Hostname: "localhost",
- Tag: "haproxy",
- PID: "27213",
- Message: `Connect from 100.100.100.99:52611 to 100.100.100.99:443 (https_shared-merged/HTTP)\\n 10.0.0.1}`,
- PRI: 46,
- }, "", []RFC3164Option{},
- },
- }
- for _, test := range tests {
- test := test
- t.Run(test.input, func(t *testing.T) {
- r := NewRFC3164Parser(test.opts...)
- err := r.Parse([]byte(test.input))
- if err != nil {
- if test.expectedErr != "" {
- if err.Error() != test.expectedErr {
- t.Errorf("expected error '%s', got '%s'", test.expectedErr, err)
- }
- } else {
- t.Errorf("unexpected error: '%s'", err)
- }
- } else {
- if test.expectedErr != "" {
- t.Errorf("expected error '%s', got no error", test.expectedErr)
- } else {
- if r.Timestamp != test.expected.Timestamp {
- t.Errorf("expected timestamp '%s', got '%s'", test.expected.Timestamp, r.Timestamp)
- }
- if r.Hostname != test.expected.Hostname {
- t.Errorf("expected hostname '%s', got '%s'", test.expected.Hostname, r.Hostname)
- }
- if r.Tag != test.expected.Tag {
- t.Errorf("expected tag '%s', got '%s'", test.expected.Tag, r.Tag)
- }
- if r.PID != test.expected.PID {
- t.Errorf("expected pid '%s', got '%s'", test.expected.PID, r.PID)
- }
- if r.Message != test.expected.Message {
- t.Errorf("expected message '%s', got '%s'", test.expected.Message, r.Message)
- }
- if r.PRI != test.expected.PRI {
- t.Errorf("expected pri '%d', got '%d'", test.expected.PRI, r.PRI)
- }
- }
- }
- })
- }
- }
|