| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package nvme |
| 4 | |
| 5 | import ( |
| 6 | "context" |
| 7 | "encoding/json" |
| 8 | "errors" |
| 9 | "fmt" |
| 10 | "os" |
| 11 | "strings" |
| 12 | "testing" |
| 13 | |
| 14 | "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest" |
| 15 | |
| 16 | "github.com/stretchr/testify/assert" |
| 17 | "github.com/stretchr/testify/require" |
| 18 | ) |
| 19 | |
| 20 | var ( |
| 21 | dataConfigJSON, _ = os.ReadFile("testdata/config.json") |
| 22 | dataConfigYAML, _ = os.ReadFile("testdata/config.yaml") |
| 23 | |
| 24 | dataNVMeListEmptyJson, _ = os.ReadFile("testdata/nvme-list-empty.json") |
| 25 | |
| 26 | dataVer23NVMeListJson, _ = os.ReadFile("testdata/v2.3/nvme-list.json") |
| 27 | dataVer23NVMeSmartLogJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log.json") |
| 28 | dataVer23NVMeSmartLogStringJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log-string.json") |
| 29 | dataVer23NVMeSmartLogFloatJson, _ = os.ReadFile("testdata/v2.3/nvme-smart-log-float.json") |
| 30 | |
| 31 | dataVer211NVMeListJson, _ = os.ReadFile("testdata/v2.11/nvme-list.json") |
| 32 | dataVer211NVMeSmartLogJson, _ = os.ReadFile("testdata/v2.11/nvme-smart-log.json") |
| 33 | ) |
| 34 | |
| 35 | func Test_testDataIsValid(t *testing.T) { |
| 36 | for name, data := range map[string][]byte{ |
| 37 | "dataConfigJSON": dataConfigJSON, |
| 38 | "dataConfigYAML": dataConfigYAML, |
| 39 | "dataNVMeListEmptyJSON": dataNVMeListEmptyJson, |
| 40 | "dataNVMeListJSON": dataVer23NVMeListJson, |
| 41 | "dataNVMeSmartLogStringJSON": dataVer23NVMeSmartLogStringJson, |
| 42 | "dataNVMeSmartLogFloatJSON": dataVer23NVMeSmartLogFloatJson, |
| 43 | "dataVer211NVMeListJson": dataVer211NVMeListJson, |
| 44 | "dataVer211NVMeSmartLogJson": dataVer211NVMeSmartLogJson, |
| 45 | } { |
| 46 | require.NotNil(t, data, name) |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | func TestCollector_ConfigurationSerialize(t *testing.T) { |
| 51 | collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML) |
| 52 | } |
| 53 | |
| 54 | func TestCollector_Init(t *testing.T) { |
| 55 | tests := map[string]struct { |
| 56 | config Config |
| 57 | wantFail bool |
| 58 | }{ |
| 59 | "success with default config": { |
| 60 | wantFail: false, |
| 61 | config: New().Config, |
| 62 | }, |
| 63 | } |
| 64 | |
| 65 | for name, test := range tests { |
| 66 | t.Run(name, func(t *testing.T) { |
| 67 | collr := New() |
| 68 | |
| 69 | if test.wantFail { |
| 70 | assert.Error(t, collr.Init(context.Background())) |
| 71 | } else { |
| 72 | assert.NoError(t, collr.Init(context.Background())) |
| 73 | } |
| 74 | }) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | func TestCollector_Charts(t *testing.T) { |
| 79 | assert.NotNil(t, New().Charts()) |
| 80 | } |
| 81 | |
| 82 | func TestCollector_Cleanup(t *testing.T) { |
| 83 | assert.NotPanics(t, func() { New().Cleanup(context.Background()) }) |
| 84 | } |
| 85 | |
| 86 | func TestCollector_Check(t *testing.T) { |
| 87 | tests := map[string]struct { |
| 88 | wantFail bool |
| 89 | prepare func(*Collector) |
| 90 | }{ |
| 91 | "success if all calls successful": { |
| 92 | wantFail: false, |
| 93 | prepare: prepareCaseVer23OK, |
| 94 | }, |
| 95 | "fails if 'nvme list' returns an empty list": { |
| 96 | wantFail: true, |
| 97 | prepare: prepareCaseEmptyList, |
| 98 | }, |
| 99 | "fails if 'nvme list' returns an error": { |
| 100 | wantFail: true, |
| 101 | prepare: prepareCaseErrOnList, |
| 102 | }, |
| 103 | "fails if 'nvme smart-log' returns an error": { |
| 104 | wantFail: true, |
| 105 | prepare: prepareCaseErrOnSmartLog, |
| 106 | }, |
| 107 | } |
| 108 | |
| 109 | for name, test := range tests { |
| 110 | t.Run(name, func(t *testing.T) { |
| 111 | collr := New() |
| 112 | |
| 113 | test.prepare(collr) |
| 114 | |
| 115 | if test.wantFail { |
| 116 | assert.Error(t, collr.Check(context.Background())) |
| 117 | } else { |
| 118 | assert.NoError(t, collr.Check(context.Background())) |
| 119 | } |
| 120 | }) |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | func TestCollector_Collect(t *testing.T) { |
| 125 | type testCaseStep struct { |
| 126 | prepare func(*Collector) |
| 127 | check func(*testing.T, *Collector) |
| 128 | } |
| 129 | |
| 130 | tests := map[string][]testCaseStep{ |
| 131 | "v2.11: success if all calls successful": { |
| 132 | { |
| 133 | prepare: prepareCaseVer211OK, |
| 134 | check: func(t *testing.T, collr *Collector) { |
| 135 | mx := collr.Collect(context.Background()) |
| 136 | |
| 137 | expected := map[string]int64{ |
| 138 | "device_nvme0_available_spare": 100, |
| 139 | "device_nvme0_controller_busy_time": 4172940, |
| 140 | "device_nvme0_critical_comp_time": 0, |
| 141 | "device_nvme0_critical_warning_available_spare": 0, |
| 142 | "device_nvme0_critical_warning_nvm_subsystem_reliability": 0, |
| 143 | "device_nvme0_critical_warning_persistent_memory_read_only": 0, |
| 144 | "device_nvme0_critical_warning_read_only": 0, |
| 145 | "device_nvme0_critical_warning_temp_threshold": 0, |
| 146 | "device_nvme0_critical_warning_volatile_mem_backup_failed": 0, |
| 147 | "device_nvme0_data_units_read": 91155062272000, |
| 148 | "device_nvme0_data_units_written": 987485941760000, |
| 149 | "device_nvme0_host_read_commands": 5808178366, |
| 150 | "device_nvme0_host_write_commands": 24273507789, |
| 151 | "device_nvme0_media_errors": 0, |
| 152 | "device_nvme0_num_err_log_entries": 212, |
| 153 | "device_nvme0_percentage_used": 30, |
| 154 | "device_nvme0_power_cycles": 99, |
| 155 | "device_nvme0_power_on_time": 87926400, |
| 156 | "device_nvme0_temperature": 50, |
| 157 | "device_nvme0_thm_temp1_total_time": 1474, |
| 158 | "device_nvme0_thm_temp1_trans_count": 3, |
| 159 | "device_nvme0_thm_temp2_total_time": 0, |
| 160 | "device_nvme0_thm_temp2_trans_count": 0, |
| 161 | "device_nvme0_unsafe_shutdowns": 49, |
| 162 | "device_nvme0_warning_temp_time": 0, |
| 163 | "device_nvme1_available_spare": 100, |
| 164 | "device_nvme1_controller_busy_time": 4172940, |
| 165 | "device_nvme1_critical_comp_time": 0, |
| 166 | "device_nvme1_critical_warning_available_spare": 0, |
| 167 | "device_nvme1_critical_warning_nvm_subsystem_reliability": 0, |
| 168 | "device_nvme1_critical_warning_persistent_memory_read_only": 0, |
| 169 | "device_nvme1_critical_warning_read_only": 0, |
| 170 | "device_nvme1_critical_warning_temp_threshold": 0, |
| 171 | "device_nvme1_critical_warning_volatile_mem_backup_failed": 0, |
| 172 | "device_nvme1_data_units_read": 91155062272000, |
| 173 | "device_nvme1_data_units_written": 987485941760000, |
| 174 | "device_nvme1_host_read_commands": 5808178366, |
| 175 | "device_nvme1_host_write_commands": 24273507789, |
| 176 | "device_nvme1_media_errors": 0, |
| 177 | "device_nvme1_num_err_log_entries": 212, |
| 178 | "device_nvme1_percentage_used": 30, |
| 179 | "device_nvme1_power_cycles": 99, |
| 180 | "device_nvme1_power_on_time": 87926400, |
| 181 | "device_nvme1_temperature": 50, |
| 182 | "device_nvme1_thm_temp1_total_time": 1474, |
| 183 | "device_nvme1_thm_temp1_trans_count": 3, |
| 184 | "device_nvme1_thm_temp2_total_time": 0, |
| 185 | "device_nvme1_thm_temp2_trans_count": 0, |
| 186 | "device_nvme1_unsafe_shutdowns": 49, |
| 187 | "device_nvme1_warning_temp_time": 0, |
| 188 | "device_nvme2_available_spare": 100, |
| 189 | "device_nvme2_controller_busy_time": 4172940, |
| 190 | "device_nvme2_critical_comp_time": 0, |
| 191 | "device_nvme2_critical_warning_available_spare": 0, |
| 192 | "device_nvme2_critical_warning_nvm_subsystem_reliability": 0, |
| 193 | "device_nvme2_critical_warning_persistent_memory_read_only": 0, |
| 194 | "device_nvme2_critical_warning_read_only": 0, |
| 195 | "device_nvme2_critical_warning_temp_threshold": 0, |
| 196 | "device_nvme2_critical_warning_volatile_mem_backup_failed": 0, |
| 197 | "device_nvme2_data_units_read": 91155062272000, |
| 198 | "device_nvme2_data_units_written": 987485941760000, |
| 199 | "device_nvme2_host_read_commands": 5808178366, |
| 200 | "device_nvme2_host_write_commands": 24273507789, |
| 201 | "device_nvme2_media_errors": 0, |
| 202 | "device_nvme2_num_err_log_entries": 212, |
| 203 | "device_nvme2_percentage_used": 30, |
| 204 | "device_nvme2_power_cycles": 99, |
| 205 | "device_nvme2_power_on_time": 87926400, |
| 206 | "device_nvme2_temperature": 50, |
| 207 | "device_nvme2_thm_temp1_total_time": 1474, |
| 208 | "device_nvme2_thm_temp1_trans_count": 3, |
| 209 | "device_nvme2_thm_temp2_total_time": 0, |
| 210 | "device_nvme2_thm_temp2_trans_count": 0, |
| 211 | "device_nvme2_unsafe_shutdowns": 49, |
| 212 | "device_nvme2_warning_temp_time": 0, |
| 213 | } |
| 214 | |
| 215 | assert.Equal(t, expected, mx) |
| 216 | }, |
| 217 | }, |
| 218 | }, |
| 219 | "v2.3: success if all calls successful": { |
| 220 | { |
| 221 | prepare: prepareCaseVer23OK, |
| 222 | check: func(t *testing.T, collr *Collector) { |
| 223 | mx := collr.Collect(context.Background()) |
| 224 | |
| 225 | expected := map[string]int64{ |
| 226 | "device_nvme0_available_spare": 100, |
| 227 | "device_nvme0_controller_busy_time": 497040, |
| 228 | "device_nvme0_critical_comp_time": 0, |
| 229 | "device_nvme0_critical_warning_available_spare": 0, |
| 230 | "device_nvme0_critical_warning_nvm_subsystem_reliability": 0, |
| 231 | "device_nvme0_critical_warning_persistent_memory_read_only": 0, |
| 232 | "device_nvme0_critical_warning_read_only": 0, |
| 233 | "device_nvme0_critical_warning_temp_threshold": 0, |
| 234 | "device_nvme0_critical_warning_volatile_mem_backup_failed": 0, |
| 235 | "device_nvme0_data_units_read": 5068041216000, |
| 236 | "device_nvme0_data_units_written": 69712734208000, |
| 237 | "device_nvme0_host_read_commands": 313528805, |
| 238 | "device_nvme0_host_write_commands": 1928062610, |
| 239 | "device_nvme0_media_errors": 0, |
| 240 | "device_nvme0_num_err_log_entries": 110, |
| 241 | "device_nvme0_percentage_used": 2, |
| 242 | "device_nvme0_power_cycles": 64, |
| 243 | "device_nvme0_power_on_time": 17906400, |
| 244 | "device_nvme0_temperature": 36, |
| 245 | "device_nvme0_thm_temp1_total_time": 0, |
| 246 | "device_nvme0_thm_temp1_trans_count": 0, |
| 247 | "device_nvme0_thm_temp2_total_time": 0, |
| 248 | "device_nvme0_thm_temp2_trans_count": 0, |
| 249 | "device_nvme0_unsafe_shutdowns": 39, |
| 250 | "device_nvme0_warning_temp_time": 0, |
| 251 | "device_nvme1_available_spare": 100, |
| 252 | "device_nvme1_controller_busy_time": 497040, |
| 253 | "device_nvme1_critical_comp_time": 0, |
| 254 | "device_nvme1_critical_warning_available_spare": 0, |
| 255 | "device_nvme1_critical_warning_nvm_subsystem_reliability": 0, |
| 256 | "device_nvme1_critical_warning_persistent_memory_read_only": 0, |
| 257 | "device_nvme1_critical_warning_read_only": 0, |
| 258 | "device_nvme1_critical_warning_temp_threshold": 0, |
| 259 | "device_nvme1_critical_warning_volatile_mem_backup_failed": 0, |
| 260 | "device_nvme1_data_units_read": 5068041216000, |
| 261 | "device_nvme1_data_units_written": 69712734208000, |
| 262 | "device_nvme1_host_read_commands": 313528805, |
| 263 | "device_nvme1_host_write_commands": 1928062610, |
| 264 | "device_nvme1_media_errors": 0, |
| 265 | "device_nvme1_num_err_log_entries": 110, |
| 266 | "device_nvme1_percentage_used": 2, |
| 267 | "device_nvme1_power_cycles": 64, |
| 268 | "device_nvme1_power_on_time": 17906400, |
| 269 | "device_nvme1_temperature": 36, |
| 270 | "device_nvme1_thm_temp1_total_time": 0, |
| 271 | "device_nvme1_thm_temp1_trans_count": 0, |
| 272 | "device_nvme1_thm_temp2_total_time": 0, |
| 273 | "device_nvme1_thm_temp2_trans_count": 0, |
| 274 | "device_nvme1_unsafe_shutdowns": 39, |
| 275 | "device_nvme1_warning_temp_time": 0, |
| 276 | } |
| 277 | |
| 278 | assert.Equal(t, expected, mx) |
| 279 | }, |
| 280 | }, |
| 281 | }, |
| 282 | "v2.3: success if all calls successful with string values": { |
| 283 | { |
| 284 | prepare: prepareCaseVer23StringValuesOK, |
| 285 | check: func(t *testing.T, collr *Collector) { |
| 286 | mx := collr.Collect(context.Background()) |
| 287 | |
| 288 | expected := map[string]int64{ |
| 289 | "device_nvme0_available_spare": 100, |
| 290 | "device_nvme0_controller_busy_time": 497040, |
| 291 | "device_nvme0_critical_comp_time": 0, |
| 292 | "device_nvme0_critical_warning_available_spare": 0, |
| 293 | "device_nvme0_critical_warning_nvm_subsystem_reliability": 0, |
| 294 | "device_nvme0_critical_warning_persistent_memory_read_only": 0, |
| 295 | "device_nvme0_critical_warning_read_only": 0, |
| 296 | "device_nvme0_critical_warning_temp_threshold": 0, |
| 297 | "device_nvme0_critical_warning_volatile_mem_backup_failed": 0, |
| 298 | "device_nvme0_data_units_read": 5068041216000, |
| 299 | "device_nvme0_data_units_written": 69712734208000, |
| 300 | "device_nvme0_host_read_commands": 313528805, |
| 301 | "device_nvme0_host_write_commands": 1928062610, |
| 302 | "device_nvme0_media_errors": 0, |
| 303 | "device_nvme0_num_err_log_entries": 110, |
| 304 | "device_nvme0_percentage_used": 2, |
| 305 | "device_nvme0_power_cycles": 64, |
| 306 | "device_nvme0_power_on_time": 17906400, |
| 307 | "device_nvme0_temperature": 36, |
| 308 | "device_nvme0_thm_temp1_total_time": 0, |
| 309 | "device_nvme0_thm_temp1_trans_count": 0, |
| 310 | "device_nvme0_thm_temp2_total_time": 0, |
| 311 | "device_nvme0_thm_temp2_trans_count": 0, |
| 312 | "device_nvme0_unsafe_shutdowns": 39, |
| 313 | "device_nvme0_warning_temp_time": 0, |
| 314 | "device_nvme1_available_spare": 100, |
| 315 | "device_nvme1_controller_busy_time": 497040, |
| 316 | "device_nvme1_critical_comp_time": 0, |
| 317 | "device_nvme1_critical_warning_available_spare": 0, |
| 318 | "device_nvme1_critical_warning_nvm_subsystem_reliability": 0, |
| 319 | "device_nvme1_critical_warning_persistent_memory_read_only": 0, |
| 320 | "device_nvme1_critical_warning_read_only": 0, |
| 321 | "device_nvme1_critical_warning_temp_threshold": 0, |
| 322 | "device_nvme1_critical_warning_volatile_mem_backup_failed": 0, |
| 323 | "device_nvme1_data_units_read": 5068041216000, |
| 324 | "device_nvme1_data_units_written": 69712734208000, |
| 325 | "device_nvme1_host_read_commands": 313528805, |
| 326 | "device_nvme1_host_write_commands": 1928062610, |
| 327 | "device_nvme1_media_errors": 0, |
| 328 | "device_nvme1_num_err_log_entries": 110, |
| 329 | "device_nvme1_percentage_used": 2, |
| 330 | "device_nvme1_power_cycles": 64, |
| 331 | "device_nvme1_power_on_time": 17906400, |
| 332 | "device_nvme1_temperature": 36, |
| 333 | "device_nvme1_thm_temp1_total_time": 0, |
| 334 | "device_nvme1_thm_temp1_trans_count": 0, |
| 335 | "device_nvme1_thm_temp2_total_time": 0, |
| 336 | "device_nvme1_thm_temp2_trans_count": 0, |
| 337 | "device_nvme1_unsafe_shutdowns": 39, |
| 338 | "device_nvme1_warning_temp_time": 0, |
| 339 | } |
| 340 | |
| 341 | assert.Equal(t, expected, mx) |
| 342 | }, |
| 343 | }, |
| 344 | }, |
| 345 | "v2.3: success if all calls successful with float values": { |
| 346 | { |
| 347 | prepare: prepareCaseVer23FloatValuesOK, |
| 348 | check: func(t *testing.T, collr *Collector) { |
| 349 | mx := collr.Collect(context.Background()) |
| 350 | |
| 351 | expected := map[string]int64{ |
| 352 | "device_nvme0_available_spare": 100, |
| 353 | "device_nvme0_controller_busy_time": 497040, |
| 354 | "device_nvme0_critical_comp_time": 0, |
| 355 | "device_nvme0_critical_warning_available_spare": 0, |
| 356 | "device_nvme0_critical_warning_nvm_subsystem_reliability": 0, |
| 357 | "device_nvme0_critical_warning_persistent_memory_read_only": 0, |
| 358 | "device_nvme0_critical_warning_read_only": 0, |
| 359 | "device_nvme0_critical_warning_temp_threshold": 0, |
| 360 | "device_nvme0_critical_warning_volatile_mem_backup_failed": 0, |
| 361 | "device_nvme0_data_units_read": 5068041216000, |
| 362 | "device_nvme0_data_units_written": 69712734208000, |
| 363 | "device_nvme0_host_read_commands": 313528805, |
| 364 | "device_nvme0_host_write_commands": 1928062610, |
| 365 | "device_nvme0_media_errors": 0, |
| 366 | "device_nvme0_num_err_log_entries": 110, |
| 367 | "device_nvme0_percentage_used": 2, |
| 368 | "device_nvme0_power_cycles": 64, |
| 369 | "device_nvme0_power_on_time": 17906400, |
| 370 | "device_nvme0_temperature": 36, |
| 371 | "device_nvme0_thm_temp1_total_time": 0, |
| 372 | "device_nvme0_thm_temp1_trans_count": 0, |
| 373 | "device_nvme0_thm_temp2_total_time": 0, |
| 374 | "device_nvme0_thm_temp2_trans_count": 0, |
| 375 | "device_nvme0_unsafe_shutdowns": 39, |
| 376 | "device_nvme0_warning_temp_time": 0, |
| 377 | "device_nvme1_available_spare": 100, |
| 378 | "device_nvme1_controller_busy_time": 497040, |
| 379 | "device_nvme1_critical_comp_time": 0, |
| 380 | "device_nvme1_critical_warning_available_spare": 0, |
| 381 | "device_nvme1_critical_warning_nvm_subsystem_reliability": 0, |
| 382 | "device_nvme1_critical_warning_persistent_memory_read_only": 0, |
| 383 | "device_nvme1_critical_warning_read_only": 0, |
| 384 | "device_nvme1_critical_warning_temp_threshold": 0, |
| 385 | "device_nvme1_critical_warning_volatile_mem_backup_failed": 0, |
| 386 | "device_nvme1_data_units_read": 5068041216000, |
| 387 | "device_nvme1_data_units_written": 69712734208000, |
| 388 | "device_nvme1_host_read_commands": 313528805, |
| 389 | "device_nvme1_host_write_commands": 1928062610, |
| 390 | "device_nvme1_media_errors": 0, |
| 391 | "device_nvme1_num_err_log_entries": 110, |
| 392 | "device_nvme1_percentage_used": 2, |
| 393 | "device_nvme1_power_cycles": 64, |
| 394 | "device_nvme1_power_on_time": 17906400, |
| 395 | "device_nvme1_temperature": 36, |
| 396 | "device_nvme1_thm_temp1_total_time": 0, |
| 397 | "device_nvme1_thm_temp1_trans_count": 0, |
| 398 | "device_nvme1_thm_temp2_total_time": 0, |
| 399 | "device_nvme1_thm_temp2_trans_count": 0, |
| 400 | "device_nvme1_unsafe_shutdowns": 39, |
| 401 | "device_nvme1_warning_temp_time": 0, |
| 402 | } |
| 403 | |
| 404 | assert.Equal(t, expected, mx) |
| 405 | }, |
| 406 | }, |
| 407 | }, |
| 408 | "fail if 'nvme list' returns an empty list": { |
| 409 | { |
| 410 | prepare: prepareCaseEmptyList, |
| 411 | check: func(t *testing.T, collr *Collector) { |
| 412 | mx := collr.Collect(context.Background()) |
| 413 | |
| 414 | assert.Equal(t, (map[string]int64)(nil), mx) |
| 415 | }, |
| 416 | }, |
| 417 | }, |
| 418 | "fail if 'nvme list' returns an error": { |
| 419 | { |
| 420 | prepare: prepareCaseErrOnList, |
| 421 | check: func(t *testing.T, collr *Collector) { |
| 422 | mx := collr.Collect(context.Background()) |
| 423 | |
| 424 | assert.Equal(t, (map[string]int64)(nil), mx) |
| 425 | }, |
| 426 | }, |
| 427 | }, |
| 428 | "fail if 'nvme smart-log' returns an error": { |
| 429 | { |
| 430 | prepare: prepareCaseErrOnSmartLog, |
| 431 | check: func(t *testing.T, collr *Collector) { |
| 432 | mx := collr.Collect(context.Background()) |
| 433 | |
| 434 | assert.Equal(t, (map[string]int64)(nil), mx) |
| 435 | }, |
| 436 | }, |
| 437 | }, |
| 438 | } |
| 439 | |
| 440 | for name, test := range tests { |
| 441 | t.Run(name, func(t *testing.T) { |
| 442 | collr := New() |
| 443 | |
| 444 | for i, step := range test { |
| 445 | t.Run(fmt.Sprintf("step[%d]", i), func(t *testing.T) { |
| 446 | step.prepare(collr) |
| 447 | step.check(t, collr) |
| 448 | }) |
| 449 | } |
| 450 | }) |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | func prepareCaseVer211OK(collr *Collector) { |
| 455 | collr.exec = &mockNVMeCLIExec{ |
| 456 | dataList: dataVer211NVMeListJson, |
| 457 | dataSmartLog: dataVer211NVMeSmartLogJson, |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | func prepareCaseVer23OK(collr *Collector) { |
| 462 | collr.exec = &mockNVMeCLIExec{ |
| 463 | dataList: dataVer23NVMeListJson, |
| 464 | dataSmartLog: dataVer23NVMeSmartLogJson, |
| 465 | } |
| 466 | } |
| 467 | |
| 468 | func prepareCaseVer23StringValuesOK(collr *Collector) { |
| 469 | collr.exec = &mockNVMeCLIExec{ |
| 470 | dataList: dataVer23NVMeListJson, |
| 471 | dataSmartLog: dataVer23NVMeSmartLogStringJson, |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | func prepareCaseVer23FloatValuesOK(collr *Collector) { |
| 476 | collr.exec = &mockNVMeCLIExec{ |
| 477 | dataList: dataVer23NVMeListJson, |
| 478 | dataSmartLog: dataVer23NVMeSmartLogFloatJson, |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | func prepareCaseEmptyList(collr *Collector) { |
| 483 | collr.exec = &mockNVMeCLIExec{ |
| 484 | dataList: dataNVMeListEmptyJson, |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | func prepareCaseErrOnList(collr *Collector) { |
| 489 | collr.exec = &mockNVMeCLIExec{errOnList: true} |
| 490 | } |
| 491 | |
| 492 | func prepareCaseErrOnSmartLog(collr *Collector) { |
| 493 | collr.exec = &mockNVMeCLIExec{errOnSmartLog: true} |
| 494 | } |
| 495 | |
| 496 | type mockNVMeCLIExec struct { |
| 497 | errOnList bool |
| 498 | errOnSmartLog bool |
| 499 | |
| 500 | dataList []byte |
| 501 | dataSmartLog []byte |
| 502 | } |
| 503 | |
| 504 | func (m *mockNVMeCLIExec) list() (*nvmeDeviceList, error) { |
| 505 | if m.errOnList { |
| 506 | return nil, errors.New("mock.list() error") |
| 507 | } |
| 508 | |
| 509 | var v nvmeDeviceList |
| 510 | if err := json.Unmarshal(m.dataList, &v); err != nil { |
| 511 | return nil, err |
| 512 | } |
| 513 | |
| 514 | return &v, nil |
| 515 | } |
| 516 | |
| 517 | func (m *mockNVMeCLIExec) smartLog(device string) (*nvmeDeviceSmartLog, error) { |
| 518 | if m.errOnSmartLog { |
| 519 | return nil, errors.New("mock.smartLog() error") |
| 520 | } |
| 521 | if !strings.HasPrefix(device, "/dev/") { |
| 522 | return nil, errors.New("mock.smartLog() expects device path /dev/") |
| 523 | } |
| 524 | |
| 525 | var v nvmeDeviceSmartLog |
| 526 | if err := json.Unmarshal(m.dataSmartLog, &v); err != nil { |
| 527 | return nil, err |
| 528 | } |
| 529 | |
| 530 | return &v, nil |
| 531 | } |