/* ** Copyright 2001-2024 Zabbix SIA ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. **/ package handlers import ( "context" "errors" "sync" "testing" "github.com/google/go-cmp/cmp" "golang.zabbix.com/plugin/nvidia/internal/plugin/params" "golang.zabbix.com/plugin/nvidia/pkg/nvml" nvmlmock "golang.zabbix.com/plugin/nvidia/pkg/nvml-mock" "golang.zabbix.com/sdk/errs" ) func TestNew(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls() h := New(runner) if h.nvmlRunner != runner { t.Fatal("New() runner not as expected") } if h.deviceCache == nil { t.Fatal("New() device cache not set") } if h.deviceCacheMux == nil { t.Fatal("New() device cache mutex not set") } } func TestHandler_GetNVMLVersion(t *testing.T) { t.Parallel() type expect struct { expectations []*nvmlmock.Expectation } tests := []struct { name string expect expect want any wantErr bool }{ { "+valid", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetNVMLVersion").ProvideOutput("Mock NVML Version"), }, }, "Mock NVML Version", false, }, { "-nvmlRunnerGetNVMLVersionError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetNVMLVersion").ProvideOutput("").ProvideError(errors.New("fail")), }, }, "", true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.expectations...) // Initialize Handler with the mocked nvmlRunner h := &Handler{ nvmlRunner: runner, } // Call the method being tested got, err := h.GetNVMLVersion(context.Background(), nil, nil...) // Check for error match if (err != nil) != tt.wantErr { t.Fatalf("Handler.DriverVersion() error = %v, wantErr %v", err, tt.wantErr) } // Check for result match if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.DriverVersion() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.DriverVersion() expected amount of calls not done") } }) } } func TestHandler_GetDriverVersion(t *testing.T) { t.Parallel() type expect struct { expectations []*nvmlmock.Expectation } tests := []struct { name string expect expect want any wantErr bool }{ { "+valid", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDriverVersion").ProvideOutput("Mock Driver Version"), }, }, "Mock Driver Version", false, }, { "-nvmlRunnerGetDriverVersionError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDriverVersion").ProvideOutput("").ProvideError(errors.New("fail")), }, }, "", true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.expectations...) // Initialize Handler with the mocked nvmlRunner h := &Handler{ nvmlRunner: runner, } // Call the method being tested got, err := h.GetDriverVersion(context.Background(), nil, nil...) // Check for error match if (err != nil) != tt.wantErr { t.Fatalf("Handler.DriverVersion() error = %v, wantErr %v", err, tt.wantErr) } // Check for result match if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.DriverVersion() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.DriverVersion() expected amount of calls not done") } }) } } func TestHandler_DeviceDiscovery(t *testing.T) { t.Parallel() type expect struct { expectations []*nvmlmock.Expectation } tests := []struct { name string expect expect want any wantErr bool }{ { "+valid", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2"). ProvideOutput(uint(2)), nvmlmock.NewExpectation("GetDeviceByIndexV2"). WithExpextedArgs(uint(0)). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUUID").ProvideOutput("UUID1"), nvmlmock.NewExpectation("GetName").ProvideOutput("Name1"), ), ), nvmlmock.NewExpectation("GetDeviceByIndexV2"). WithExpextedArgs(uint(1)). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUUID").ProvideOutput("UUID2"), nvmlmock.NewExpectation("GetName").ProvideOutput("Name2"), ), ), }, }, []DiscoveryDevice{{"UUID1", "Name1"}, {"UUID2", "Name2"}}, false, }, { "-getCountError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2"). ProvideOutput(uint(0)).ProvideError(errors.New("fail")), }, }, nil, true, }, { "-getDeviceByIndexError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2"). ProvideOutput(uint(2)), nvmlmock.NewExpectation("GetDeviceByIndexV2"). WithExpextedArgs(uint(0)). ProvideOutput(nil). ProvideError(errors.New("fail")), }, }, nil, true, }, { "-getUUIDError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2"). ProvideOutput(uint(2)), nvmlmock.NewExpectation("GetDeviceByIndexV2"). WithExpextedArgs(uint(0)). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUUID"). ProvideOutput(""). ProvideError(errors.New("fail")), ), ), }, }, nil, true, }, { "-getNameError", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2"). ProvideOutput(uint(2)), nvmlmock.NewExpectation("GetDeviceByIndexV2"). WithExpextedArgs(uint(0)). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUUID"). ProvideOutput("123"), nvmlmock.NewExpectation("GetName"). ProvideOutput(""). ProvideError(errors.New("fail")), ), ), }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.expectations...) h := &Handler{ concurrentDeviceDiscoveries: 1, nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.DeviceDiscovery(context.Background(), nil, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.DeviceDiscovery() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.DeviceDiscovery() = %s", diff) } done := runner.ExpectedCallsDone() if !done { t.Fatal("Handler.DeviceDiscovery() expected calls not done") } }) } } func TestHandler_GetDeviceCount(t *testing.T) { t.Parallel() type expect struct { expectations []*nvmlmock.Expectation } tests := []struct { name string expect expect want any wantErr bool }{ { "+valid", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2").ProvideOutput(uint(1)), }, }, uint(1), false, }, { "-nvmlRunnerGetDeviceCountV2Error", expect{ expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceCountV2").ProvideOutput(uint(1)).ProvideError(errors.New("fail")), }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.expectations...) // Initialize Handler with the mocked nvmlRunner h := &Handler{ nvmlRunner: runner, } // Call the method being tested got, err := h.GetDeviceCount(context.Background(), nil, nil...) // Check for error match if (err != nil) != tt.wantErr { t.Fatalf("Handler.DriverVersion() error = %v, wantErr %v", err, tt.wantErr) } // Check for result match if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.DriverVersion() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.DriverVersion() expected amount of calls not done") } }) } } func TestHandler_GetDeviceTemperature(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetTemperature"). ProvideOutput(int(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, int(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetTemperatureError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetTemperature"). ProvideOutput(int(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDeviceTemperature(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDeviceTemperature() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDeviceTemperature() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDeviceTemperature() expected calls not done") } }) } } func TestHandler_GetDeviceSerial(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetSerial"). ProvideOutput("12345"), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, "12345", false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorGettingSerial", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetSerial"). ProvideOutput(""). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDeviceSerial(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDeviceSerial() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDeviceSerial() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDeviceSerial() expected calls not done") } }) } } func TestHandler_GetDeviceFanSpeed(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetFanSpeed"). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetFanSpeedError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetFanSpeed"). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDeviceFanSpeed(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDeviceFanSpeed() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDeviceFanSpeed() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDeviceFanSpeed() expected calls not done") } }) } } func TestHandler_GetDevicePerfState(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPerformanceState"). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetPerformanceStateError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPerformanceState"). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDevicePerfState(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDevicePerfState() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDevicePerfState() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDevicePerfState() expected calls not done") } }) } } func TestHandler_GetDeviceEnergyConsumption(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetTotalEnergyConsumption"). ProvideOutput(uint64(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint64(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetTotalEnergyConsumptionError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetTotalEnergyConsumption"). ProvideOutput(uint64(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDeviceEnergyConsumption(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDeviceEnergyConsumption() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDeviceEnergyConsumption() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDeviceEnergyConsumption() expected calls not done") } }) } } func TestHandler_GetDevicePowerLimit(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPowerManagementLimit"). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetPowerManagementLimitError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPowerManagementLimit"). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDevicePowerLimit(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDevicePowerLimit() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDevicePowerLimit() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDevicePowerLimit() expected calls not done") } }) } } func TestHandler_GetDevicePowerUsage(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPowerUsage"). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetPowerUsageError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPowerUsage"). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDevicePowerUsage(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDevicePowerUsage() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDevicePowerUsage() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDevicePowerUsage() expected calls not done") } }) } } func TestHandler_GetBAR1MemoryInfo(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetBAR1MemoryInfo"). ProvideOutput(&nvml.MemoryInfo{ Total: 10, Used: 8, Free: 2, }), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, &nvml.MemoryInfo{ Total: 10, Used: 8, Free: 2, }, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetBAR1MemoryInfoError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetBAR1MemoryInfo"). ProvideOutput(&nvml.MemoryInfo{ Total: 10, Used: 8, Free: 2, }). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetBAR1MemoryInfo(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetBAR1MemoryInfo() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetBAR1MemoryInfo() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetBAR1MemoryInfo() expected calls not done") } }) } } func TestHandler_GetFBMemoryInfo(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryInfoV2"). ProvideOutput(&nvml.MemoryInfoV2{ Total: 10, Used: 8, Free: 2, Reserved: 1, }), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, &nvml.MemoryInfoV2{ Total: 10, Used: 8, Free: 2, Reserved: 1, }, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { name: "-nvmlDeviceGetMemoryInfoV2Error", expect: expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryInfoV2"). ProvideOutput(&nvml.MemoryInfoV2{ Total: 10, Used: 8, Free: 2, Reserved: 1, }). ProvideError(errors.New("fail")), ), ), }, }, }, args: args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, want: nil, wantErr: true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetFBMemoryInfo(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetFBMemoryInfo() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetFBMemoryInfo() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetFBMemoryInfo() expected calls not done") } }) } } func TestHandler_GetMemoryErrors(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationDevice, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(55)), nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeUncorrected, nvml.MemoryLocationDevice, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(25)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, ECCErrors{Corrected: 55, Uncorrected: 25}, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInFirstNVMLResponse", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationDevice, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInSecondNVMLResponse", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationDevice, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(55)), nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeUncorrected, nvml.MemoryLocationDevice, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetMemoryErrors(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetMemoryErrors() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetMemoryErrors() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetMemoryErrors() expected calls not done") } }) } } func TestHandler_GetRegistryErrors(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationRegisterFile, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(55)), nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeUncorrected, nvml.MemoryLocationRegisterFile, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(25)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, ECCErrors{Corrected: 55, Uncorrected: 25}, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInFirstNVMLGetMemoryErrorCounter", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationRegisterFile, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInSecondNVMLGetMemoryErrorCounter", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeCorrected, nvml.MemoryLocationRegisterFile, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(55)), nvmlmock.NewExpectation("GetMemoryErrorCounter"). WithExpextedArgs( nvml.MemoryErrorTypeUncorrected, nvml.MemoryLocationRegisterFile, nvml.EccCounterTypeAggregate, ).ProvideOutput(uint64(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetRegisterErrors(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetRegisterErrors() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetRegisterErrors() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetRegisterErrors() expected calls not done") } }) } } func TestHandler_GetPCIeThroughput(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPCIeThroughput"). WithExpextedArgs(nvml.RX). ProvideOutput(uint(55)), nvmlmock.NewExpectation("GetPCIeThroughput"). WithExpextedArgs(nvml.TX). ProvideOutput(uint(25)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, PCIeUtil{Receive: 55, Transmit: 25}, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInFirstNVMLGetPCIeThroughput", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPCIeThroughput"). WithExpextedArgs(nvml.RX). ProvideOutput(uint(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-errorInSecondNVMLGetPCIeThroughput", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetPCIeThroughput"). WithExpextedArgs(nvml.RX). ProvideOutput(uint(55)), nvmlmock.NewExpectation("GetPCIeThroughput"). WithExpextedArgs(nvml.TX). ProvideOutput(uint(0)).ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetPCIeThroughput(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetPCIeThroughput() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetPCIeThroughput() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetPCIeThroughput() expected calls not done") } }) } } func TestHandler_GetEncoderStats(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEncoderStats"). ProvideOutput(uint(1), uint(2), uint(3)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, EncoderStats{ SessionCount: 1, FPS: 2, Latency: 3, }, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetEncoderStatsError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEncoderStats"). ProvideOutput(uint(0), uint(0), uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetEncoderStats(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetEncoderStats() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetEncoderStats() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetEncoderStats() expected calls not done") } }) } } func TestHandler_GetVideoFrequency(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Video). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetClockInfoError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Video). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetVideoFrequency(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetVideoFrequency() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetVideoFrequency() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetVideoFrequency() expected calls not done") } }) } } func TestHandler_GetGraphicsFrequency(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Graphics). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetClockInfoError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Graphics). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetGraphicsFrequency(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetGraphicsFrequency() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetGraphicsFrequency() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetGraphicsFrequency() expected calls not done") } }) } } func TestHandler_GetSMFrequency(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.SM). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetClockInfoError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.SM). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetSMFrequency(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetSMFrequency() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetSMFrequency() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetSMFrequency() expected calls not done") } }) } } func TestHandler_GetMemoryFrequency(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Memory). ProvideOutput(uint(55)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetClockInfoError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetClockInfo"). WithExpextedArgs(nvml.Memory). ProvideOutput(uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetMemoryFrequency(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetMemoryFrequency() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetMemoryFrequency() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetMemoryFrequency() expected calls not done") } }) } } func TestHandler_GetEncoderUtilization(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEncoderUtilization"). ProvideOutput(uint(55), uint(99)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetEncoderUtilizationError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEncoderUtilization"). ProvideOutput(uint(0), uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetEncoderUtilization(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetEncoderUtilization() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetEncoderUtilization() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetEncoderUtilization() expected calls not done") } }) } } func TestHandler_GetDecoderUtilization(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetDecoderUtilization"). ProvideOutput(uint(55), uint(99)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, uint(55), false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetDecoderUtilizationError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetDecoderUtilization"). ProvideOutput(uint(0), uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDecoderUtilization(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetDecoderUtilization() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetDecoderUtilization() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetDecoderUtilization() expected calls not done") } }) } } func TestHandler_GetDeviceUtilisation(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUtilizationRates"). ProvideOutput(uint(55), uint(99)), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, UtilisationRates{Device: 55, Memory: 99}, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetUtilizationRatesError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetUtilizationRates"). ProvideOutput(uint(0), uint(0)). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetDeviceUtilisation(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetUtilizationRates() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetUtilizationRates() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetUtilizationRates() expected calls not done") } }) } } func TestHandler_GetECCMode(t *testing.T) { t.Parallel() type device struct { deviceUUID string expectations []*nvmlmock.Expectation } type expect struct { device device } type args struct { metricParams map[string]string } tests := []struct { name string expect expect args args want any wantErr bool }{ { "+valid", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEccMode"). ProvideOutput(true, false), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, ECCMode{Current: true, Pending: false}, false, }, { "-noInMetricParams", expect{}, args{ map[string]string{}, }, nil, true, }, { "-deviceNotFound", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput(nil).ProvideError(errors.New("fail")), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, { "-nvmlDeviceGetEccModeError", expect{ device: device{ deviceUUID: "test-uuid", expectations: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-uuid"). ProvideOutput( nvmlmock.NewMockDevice(t).ExpectCalls( nvmlmock.NewExpectation("GetEccMode"). ProvideOutput(false, false). ProvideError(errors.New("fail")), ), ), }, }, }, args{ metricParams: map[string]string{ params.DeviceUUIDParamName: "test-uuid", }, }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.expect.device.expectations...) h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: make(map[string]nvml.Device), } got, err := h.GetECCMode(context.Background(), tt.args.metricParams, nil...) if (err != nil) != tt.wantErr { t.Fatalf("Handler.GetECCMode() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.GetECCMode() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.GetECCMode() expected calls not done") } }) } } func TestWithJSONResponse(t *testing.T) { t.Parallel() type args struct { value any gotErr bool } tests := []struct { name string args args want any wantErr bool }{ { "+valid", args{ value: "foobar", }, `"foobar"`, false, }, { "+jsonObject", args{ value: map[string]string{ "foo": "bar", "test": "true", }, }, `{"foo":"bar","test":"true"}`, false, }, { "-jsonMarshalError", args{ value: map[struct{ test string }]string{ {test: "1"}: "bar", {test: "2"}: "foo", }, }, nil, true, }, { "-handlerError", args{gotErr: true}, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := WithJSONResponse( func(ctx context.Context, metricParams map[string]string, extraParams ...string) (any, error) { if tt.args.gotErr { return nil, errs.New("fail") } return tt.args.value, nil }, )(context.Background(), nil) if (err != nil) != tt.wantErr { t.Fatalf("WithJSONResponse() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("WithJSONResponse() = %s", diff) } }) } } func TestHandler_getDeviceByUUID(t *testing.T) { t.Parallel() type TestDevice struct { nvml.Device UUID string } type fields struct { runnerExpect []*nvmlmock.Expectation deviceInCache map[string]TestDevice } type args struct { uuid string } tests := []struct { name string fields fields args args want any wantErr bool }{ { "+deviceFromCache", fields{ runnerExpect: []*nvmlmock.Expectation{}, deviceInCache: map[string]TestDevice{ "test-1": {UUID: "test-1"}, "test-2": {UUID: "test-2"}, "test-3": {UUID: "test-3"}, }, }, args{ uuid: "test-2", }, TestDevice{UUID: "test-2"}, false, }, { "+deviceFromNVML", fields{ runnerExpect: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-2"). ProvideOutput(TestDevice{UUID: "test-2"}). ProvideError(nil), }, deviceInCache: map[string]TestDevice{ "test-1": {UUID: "test-1"}, "test-3": {UUID: "test-3"}, }, }, args{ uuid: "test-2", }, TestDevice{UUID: "test-2"}, false, }, { "-noDeviceFound", fields{ runnerExpect: []*nvmlmock.Expectation{ nvmlmock.NewExpectation("GetDeviceByUUID"). WithExpextedArgs("test-2"). ProvideOutput(nil). ProvideError(errors.New("fail")), }, deviceInCache: map[string]TestDevice{ "test-1": {UUID: "test-1"}, "test-3": {UUID: "test-3"}, }, }, args{ uuid: "test-2", }, nil, true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() runner := nvmlmock.NewMockRunner(t).ExpectCalls(tt.fields.runnerExpect...) deviceCache := make(map[string]nvml.Device) for key, device := range tt.fields.deviceInCache { device := device deviceCache[key] = device } h := &Handler{ nvmlRunner: runner, deviceCacheMux: &sync.Mutex{}, deviceCache: deviceCache, } got, err := h.getDeviceByUUID(tt.args.uuid) if (err != nil) != tt.wantErr { t.Fatalf("Handler.getDeviceByUUID() error = %v, wantErr %v", err, tt.wantErr) } if diff := cmp.Diff(tt.want, got); diff != "" { t.Fatalf("Handler.getDeviceByUUID() = %s", diff) } if !runner.ExpectedCallsDone() { t.Fatal("Handler.getDeviceByUUID() expected calls not done") } }) } }