1/* 2** Zabbix 3** Copyright (C) 2001-2021 Zabbix SIA 4** 5** This program is free software; you can redistribute it and/or modify 6** it under the terms of the GNU General Public License as published by 7** the Free Software Foundation; either version 2 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU General Public License for more details. 14** 15** You should have received a copy of the GNU General Public License 16** along with this program; if not, write to the Free Software 17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18**/ 19 20package metric 21 22import ( 23 "reflect" 24 "testing" 25 26 "zabbix.com/pkg/conf" 27) 28 29var ( 30 paramURI = NewConnParam("URI", "Description.").WithDefault("localhost:1521").WithSession() 31 paramUsername = NewConnParam("User", "Description.").WithDefault("") 32 paramRequiredUsername = NewConnParam("User", "Description.").SetRequired() 33 paramUserValidation = NewConnParam("User", "Description.").WithDefault("").WithValidator( 34 SetValidator{Set: []string{"", "supervisor", "admin", "guest"}}) 35 paramPassword = NewConnParam("Password", "Description.").WithDefault("") 36 paramGeneral = NewParam("GeneralParam", "Description.") 37) 38 39var metricSet = MetricSet{ 40 "metric.foo": New("Foo description.", 41 []*Param{paramURI, paramUsername, paramPassword, 42 NewParam("Param1", "Description.").WithDefault("60").WithValidator(SetValidator{Set: []string{"15", "60"}}), 43 }, false), 44 "metric.query": New("Query description.", 45 []*Param{paramURI, paramUsername, paramPassword, 46 NewParam("QueryName", "Description.").SetRequired(), 47 }, true), 48 "metric.requiredSessionParam": New("RequiredSessionParam description.", 49 []*Param{paramURI, paramRequiredUsername, paramPassword}, false), 50 "metric.withoutPassword": New("WithoutPassword description.", 51 []*Param{paramURI, paramUsername}, false), 52 "metric.userValidation": New("UserValidation description.", 53 []*Param{paramURI, paramUserValidation, paramPassword}, false), 54} 55 56func TestMetric_EvalParams(t *testing.T) { 57 type args struct { 58 rawParams []string 59 sessions interface{} 60 } 61 tests := []struct { 62 name string 63 m *Metric 64 args args 65 want map[string]string 66 wantErr bool 67 wantPanic bool 68 }{ 69 { 70 name: "Must fail if too many parameters passed", 71 m: metricSet["metric.foo"], 72 args: args{ 73 rawParams: []string{"localhost", "user", "password", "15", "excessParam"}, 74 sessions: map[string]conf.Session{}, 75 }, 76 want: nil, 77 wantErr: true, 78 wantPanic: false, 79 }, 80 { 81 name: "Must not fail if passed more parameters than described, but the metric has the varParam enabled", 82 m: metricSet["metric.query"], 83 args: args{ 84 rawParams: []string{"localhost", "user", "password", "queryName", "queryParam1", "queryParam2"}, 85 sessions: map[string]conf.Session{}, 86 }, 87 want: map[string]string{"Password": "password", "QueryName": "queryName", "URI": "localhost", "User": "user"}, 88 wantErr: false, 89 wantPanic: false, 90 }, 91 { 92 name: "Must fail if a required parameter is not specified", 93 m: metricSet["metric.query"], 94 args: args{ 95 rawParams: []string{"localhost", "user", "password", "", "queryParam1"}, 96 sessions: map[string]conf.Session{}, 97 }, 98 want: nil, 99 wantErr: true, 100 wantPanic: false, 101 }, 102 { 103 name: "Must fail if validation failed", 104 m: metricSet["metric.foo"], 105 args: args{ 106 rawParams: []string{"localhost", "user", "password", "wrongValue"}, 107 sessions: map[string]conf.Session{}, 108 }, 109 want: nil, 110 wantErr: true, 111 wantPanic: false, 112 }, 113 { 114 name: "Must fail if a session parameter did not pass validation", 115 m: metricSet["metric.userValidation"], 116 args: args{ 117 rawParams: []string{"Session1"}, 118 sessions: map[string]conf.Session{ 119 "Session1": {URI: "localhost", User: "bob", Password: "password"}, 120 }, 121 }, 122 want: nil, 123 wantErr: true, 124 wantPanic: false, 125 }, 126 { 127 name: "Must fail if a connection parameter passed along with a session", 128 m: metricSet["metric.foo"], 129 args: args{ 130 rawParams: []string{"Session1", "", "password"}, 131 sessions: map[string]conf.Session{ 132 "Session1": {URI: "localhost", User: "user", Password: "password"}, 133 }, 134 }, 135 want: nil, 136 wantErr: true, 137 wantPanic: false, 138 }, 139 { 140 name: "Must fail if a required parameter is omitted in a session", 141 m: metricSet["metric.requiredSessionParam"], 142 args: args{ 143 rawParams: []string{"Session1"}, 144 sessions: map[string]conf.Session{ 145 "Session1": {URI: "localhost", Password: "password"}, 146 }, 147 }, 148 want: nil, 149 wantErr: true, 150 wantPanic: false, 151 }, 152 { 153 name: "Must panic if cannot find any session's parameter in a schema", 154 m: metricSet["metric.withoutPassword"], 155 args: args{ 156 rawParams: []string{"Session1"}, 157 sessions: map[string]conf.Session{ 158 "Session1": {URI: "localhost", User: "user", Password: "password"}, 159 }, 160 }, 161 want: nil, 162 wantErr: false, 163 wantPanic: true, 164 }, 165 { 166 name: "Must successfully return parsed parameters (without session)", 167 m: metricSet["metric.foo"], 168 args: args{ 169 rawParams: []string{"localhost", "user", "password", "15"}, 170 sessions: map[string]conf.Session{}, 171 }, 172 want: map[string]string{"URI": "localhost", "User": "user", "Password": "password", "Param1": "15"}, 173 wantErr: false, 174 wantPanic: false, 175 }, 176 { 177 name: "Must successfully return parsed parameters (with session)", 178 m: metricSet["metric.foo"], 179 args: args{ 180 rawParams: []string{"Session1", "", "", "15"}, 181 sessions: map[string]conf.Session{ 182 "Session1": {URI: "localhost", User: "user", Password: "password"}, 183 }, 184 }, 185 want: map[string]string{ 186 "URI": "localhost", "User": "user", "Password": "password", "Param1": "15", "sessionName": "Session1", 187 }, 188 wantErr: false, 189 wantPanic: false, 190 }, 191 } 192 for _, tt := range tests { 193 t.Run(tt.name, func(t *testing.T) { 194 if tt.wantPanic { 195 defer func() { 196 if r := recover(); r == nil { 197 t.Error("Metric.EvalParams() must panic with runtime error") 198 } 199 }() 200 } 201 202 gotParams, err := tt.m.EvalParams(tt.args.rawParams, tt.args.sessions) 203 if (err != nil) != tt.wantErr { 204 t.Errorf("EvalParams() error = %v, wantErr %v", err, tt.wantErr) 205 return 206 } 207 if !reflect.DeepEqual(gotParams, tt.want) { 208 t.Errorf("EvalParams() got = %v, want %v", gotParams, tt.want) 209 } 210 }) 211 } 212} 213 214func TestNew(t *testing.T) { 215 type args struct { 216 description string 217 params []*Param 218 varParam bool 219 } 220 tests := []struct { 221 name string 222 args args 223 want *Metric 224 wantPanic bool 225 }{ 226 { 227 name: "Must fail if a parameter has a non-unique name", 228 args: args{ 229 "Metric description.", 230 []*Param{paramURI, paramUsername, paramUsername, paramPassword, NewParam("Param", "Description.")}, 231 false, 232 }, 233 want: nil, 234 wantPanic: true, 235 }, 236 { 237 name: "Must fail if a session placed not first", 238 args: args{ 239 "Metric description.", 240 []*Param{paramUsername, paramPassword, paramURI, NewParam("Param", "Description.")}, 241 false, 242 }, 243 want: nil, 244 wantPanic: true, 245 }, 246 { 247 name: "Must fail if parameters describing a connection placed not in a row", 248 args: args{ 249 "Metric description.", 250 []*Param{paramURI, paramUsername, NewParam("Param", "Description."), paramPassword}, 251 false, 252 }, 253 want: nil, 254 wantPanic: true, 255 }, 256 { 257 name: "Must successfully return a new metric", 258 args: args{ 259 "Metric description.", 260 []*Param{paramURI, paramUsername, paramPassword, paramGeneral}, 261 false, 262 }, 263 want: &Metric{ 264 description: "Metric description.", 265 params: []*Param{paramURI, paramUsername, paramPassword, paramGeneral}, 266 varParam: false, 267 }, 268 wantPanic: false, 269 }, 270 } 271 for _, tt := range tests { 272 t.Run(tt.name, func(t *testing.T) { 273 if tt.wantPanic { 274 defer func() { 275 if r := recover(); r == nil { 276 t.Error("New() must panic with runtime error") 277 } 278 }() 279 } 280 281 if got := New(tt.args.description, tt.args.params, tt.args.varParam); !reflect.DeepEqual(got, tt.want) { 282 t.Errorf("New() = %v, want %v", got, tt.want) 283 } 284 }) 285 } 286} 287