github.com/netdata/go.d.plugin@v0.58.1/modules/weblog/parser_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package weblog 4 5 import ( 6 "fmt" 7 "testing" 8 9 "github.com/netdata/go.d.plugin/pkg/logs" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestWebLog_guessParser(t *testing.T) { 16 type test = struct { 17 name string 18 inputs []string 19 wantParserType string 20 wantErr bool 21 } 22 tests := []test{ 23 { 24 name: "guessed csv", 25 wantParserType: logs.TypeCSV, 26 inputs: []string{ 27 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123 0.123,0.321`, 28 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123`, 29 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123 0.123,0.321`, 30 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123`, 31 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 32 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123 0.123,0.321`, 33 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123`, 34 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123 0.123,0.321`, 35 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123`, 36 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 37 }, 38 }, 39 { 40 name: "guessed ltsv", 41 wantParserType: logs.TypeLTSV, 42 inputs: []string{ 43 `field1:test.example.com:80 field2:88.191.254.20 field3:"GET / HTTP/1.0" 200 8674 field4:8674 field5:0.123`, 44 }, 45 }, 46 { 47 name: "guessed json", 48 wantParserType: logs.TypeJSON, 49 inputs: []string{ 50 `{}`, 51 ` {}`, 52 ` {} `, 53 `{"host": "example.com"}`, 54 `{"host": "example.com","time": "2020-08-04T20:23:27+03:00", "upstream_response_time": "0.776", "remote_addr": "1.2.3.4"}`, 55 ` {"host": "example.com","time": "2020-08-04T20:23:27+03:00", "upstream_response_time": "0.776", "remote_addr": "1.2.3.4"} `, 56 }, 57 }, 58 { 59 name: "unknown", 60 wantErr: true, 61 inputs: []string{ 62 `test.example.com 80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 63 `test.example.com 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 64 }, 65 }, 66 } 67 68 weblog := prepareWebLog() 69 70 for _, tc := range tests { 71 for i, input := range tc.inputs { 72 name := fmt.Sprintf("name=%s,input_num=%d", tc.name, i+1) 73 74 t.Run(name, func(t *testing.T) { 75 p, err := weblog.newParser([]byte(input)) 76 77 if tc.wantErr { 78 assert.Error(t, err) 79 } else { 80 require.NoError(t, err) 81 switch tc.wantParserType { 82 default: 83 t.Errorf("unknown parser type: %s", tc.wantParserType) 84 case logs.TypeLTSV: 85 assert.IsType(t, (*logs.LTSVParser)(nil), p) 86 case logs.TypeCSV: 87 require.IsType(t, (*logs.CSVParser)(nil), p) 88 case logs.TypeJSON: 89 require.IsType(t, (*logs.JSONParser)(nil), p) 90 } 91 } 92 }) 93 } 94 } 95 } 96 97 func TestWebLog_guessCSVParser(t *testing.T) { 98 type test = struct { 99 name string 100 inputs []string 101 wantCSVFormat string 102 wantErr bool 103 } 104 tests := []test{ 105 { 106 name: "guessed vhost custom4", 107 wantCSVFormat: csvVhostCustom4, 108 inputs: []string{ 109 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123 0.123,0.321`, 110 }, 111 }, 112 { 113 name: "guessed vhost custom3", 114 wantCSVFormat: csvVhostCustom3, 115 inputs: []string{ 116 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123`, 117 }, 118 }, 119 { 120 name: "guessed vhost custom2", 121 wantCSVFormat: csvVhostCustom2, 122 inputs: []string{ 123 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123 0.123,0.321`, 124 }, 125 }, 126 { 127 name: "guessed vhost custom1", 128 wantCSVFormat: csvVhostCustom1, 129 inputs: []string{ 130 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123`, 131 }, 132 }, 133 { 134 name: "guessed vhost common", 135 wantCSVFormat: csvVhostCommon, 136 inputs: []string{ 137 `test.example.com:80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 138 }, 139 }, 140 { 141 name: "guessed custom4", 142 wantCSVFormat: csvCustom4, 143 inputs: []string{ 144 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123 0.123,0.321`, 145 }, 146 }, 147 { 148 name: "guessed custom3", 149 wantCSVFormat: csvCustom3, 150 inputs: []string{ 151 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 "-" "-" 8674 0.123`, 152 }, 153 }, 154 { 155 name: "guessed custom2", 156 wantCSVFormat: csvCustom2, 157 inputs: []string{ 158 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123 0.123,0.321`, 159 }, 160 }, 161 { 162 name: "guessed custom1", 163 wantCSVFormat: csvCustom1, 164 inputs: []string{ 165 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674 8674 0.123`, 166 }, 167 }, 168 { 169 name: "guessed common", 170 wantCSVFormat: csvCommon, 171 inputs: []string{ 172 `88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 173 }, 174 }, 175 { 176 name: "unknown", 177 wantErr: true, 178 inputs: []string{ 179 `test.example.com 80 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 180 `test.example.com 88.191.254.20 - - [22/Mar/2009:09:30:31 +0100] "GET / HTTP/1.0" 200 8674`, 181 }, 182 }, 183 } 184 185 weblog := prepareWebLog() 186 187 for i, tc := range tests { 188 for _, input := range tc.inputs { 189 name := fmt.Sprintf("name=%s,input_num=%d", tc.name, i+1) 190 191 t.Run(name, func(t *testing.T) { 192 p, err := weblog.guessCSVParser([]byte(input)) 193 194 if tc.wantErr { 195 assert.Error(t, err) 196 } else { 197 require.NoError(t, err) 198 assert.Equal(t, cleanCSVFormat(tc.wantCSVFormat), p.(*logs.CSVParser).Config.Format) 199 } 200 }) 201 } 202 } 203 } 204 205 func prepareWebLog() *WebLog { 206 cfg := logs.ParserConfig{ 207 LogType: typeAuto, 208 CSV: logs.CSVConfig{ 209 Delimiter: " ", 210 CheckField: checkCSVFormatField, 211 }, 212 LTSV: logs.LTSVConfig{ 213 FieldDelimiter: "\t", 214 ValueDelimiter: ":", 215 }, 216 } 217 218 return &WebLog{ 219 Config: Config{ 220 GroupRespCodes: false, 221 Parser: cfg, 222 }, 223 } 224 }