github.com/netdata/go.d.plugin@v0.58.1/modules/nvidia_smi/nvidia_smi_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package nvidia_smi
     4  
     5  import (
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  var (
    16  	dataXMLRTX2080Win, _       = os.ReadFile("testdata/rtx-2080-win.xml")
    17  	dataXMLRTX4090Driver535, _ = os.ReadFile("testdata/rtx-4090-driver-535.xml")
    18  	dataXMLRTX3060, _          = os.ReadFile("testdata/rtx-3060.xml")
    19  	dataXMLTeslaP100, _        = os.ReadFile("testdata/tesla-p100.xml")
    20  
    21  	dataXMLA100SXM4MIG, _ = os.ReadFile("testdata/a100-sxm4-mig.xml")
    22  
    23  	dataHelpQueryGPU, _ = os.ReadFile("testdata/help-query-gpu.txt")
    24  	dataCSVTeslaP100, _ = os.ReadFile("testdata/tesla-p100.csv")
    25  )
    26  
    27  func Test_testDataIsValid(t *testing.T) {
    28  	for name, data := range map[string][]byte{
    29  		"dataXMLRTX2080Win":       dataXMLRTX2080Win,
    30  		"dataXMLRTX4090Driver535": dataXMLRTX4090Driver535,
    31  		"dataXMLRTX3060":          dataXMLRTX3060,
    32  		"dataXMLTeslaP100":        dataXMLTeslaP100,
    33  
    34  		"dataXMLA100SXM4MIG": dataXMLA100SXM4MIG,
    35  
    36  		"dataHelpQueryGPU": dataHelpQueryGPU,
    37  		"dataCSVTeslaP100": dataCSVTeslaP100,
    38  	} {
    39  		require.NotNilf(t, data, name)
    40  	}
    41  }
    42  
    43  func TestNvidiaSMI_Init(t *testing.T) {
    44  	tests := map[string]struct {
    45  		prepare  func(nv *NvidiaSMI)
    46  		wantFail bool
    47  	}{
    48  		"fails if can't local nvidia-smi": {
    49  			wantFail: true,
    50  			prepare: func(nv *NvidiaSMI) {
    51  				nv.binName += "!!!"
    52  			},
    53  		},
    54  	}
    55  
    56  	for name, test := range tests {
    57  		t.Run(name, func(t *testing.T) {
    58  			nv := New()
    59  
    60  			test.prepare(nv)
    61  
    62  			if test.wantFail {
    63  				assert.False(t, nv.Init())
    64  			} else {
    65  				assert.True(t, nv.Init())
    66  			}
    67  		})
    68  	}
    69  }
    70  
    71  func TestNvidiaSMI_Charts(t *testing.T) {
    72  	assert.NotNil(t, New().Charts())
    73  }
    74  
    75  func TestNvidiaSMI_Check(t *testing.T) {
    76  	tests := map[string]struct {
    77  		prepare  func(nv *NvidiaSMI)
    78  		wantFail bool
    79  	}{
    80  		"success A100-SXM4 MIG [XML]": {
    81  			wantFail: false,
    82  			prepare:  prepareCaseMIGA100formatXML,
    83  		},
    84  		"success RTX 3060 [XML]": {
    85  			wantFail: false,
    86  			prepare:  prepareCaseRTX3060formatXML,
    87  		},
    88  		"success Tesla P100 [XML]": {
    89  			wantFail: false,
    90  			prepare:  prepareCaseTeslaP100formatXML,
    91  		},
    92  		"success Tesla P100 [CSV]": {
    93  			wantFail: false,
    94  			prepare:  prepareCaseTeslaP100formatCSV,
    95  		},
    96  		"success RTX 2080 Win [XML]": {
    97  			wantFail: false,
    98  			prepare:  prepareCaseRTX2080WinFormatXML,
    99  		},
   100  		"fail on queryGPUInfoXML error": {
   101  			wantFail: true,
   102  			prepare:  prepareCaseErrOnQueryGPUInfoXML,
   103  		},
   104  		"fail on queryGPUInfoCSV error": {
   105  			wantFail: true,
   106  			prepare:  prepareCaseErrOnQueryGPUInfoCSV,
   107  		},
   108  		"fail on queryHelpQueryGPU error": {
   109  			wantFail: true,
   110  			prepare:  prepareCaseErrOnQueryHelpQueryGPU,
   111  		},
   112  	}
   113  
   114  	for name, test := range tests {
   115  		t.Run(name, func(t *testing.T) {
   116  			nv := New()
   117  
   118  			test.prepare(nv)
   119  
   120  			if test.wantFail {
   121  				assert.False(t, nv.Check())
   122  			} else {
   123  				assert.True(t, nv.Check())
   124  			}
   125  		})
   126  	}
   127  }
   128  
   129  func TestNvidiaSMI_Collect(t *testing.T) {
   130  	type testCaseStep struct {
   131  		prepare func(nv *NvidiaSMI)
   132  		check   func(t *testing.T, nv *NvidiaSMI)
   133  	}
   134  	tests := map[string][]testCaseStep{
   135  		"success A100-SXM4 MIG [XML]": {
   136  			{
   137  				prepare: prepareCaseMIGA100formatXML,
   138  				check: func(t *testing.T, nv *NvidiaSMI) {
   139  					mx := nv.Collect()
   140  
   141  					expected := map[string]int64{
   142  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_free":                            68718428160,
   143  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_used":                            1048576,
   144  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_free":                    42273341440,
   145  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_reserved":                634388480,
   146  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_used":                    39845888,
   147  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_graphics_clock":                                    1410,
   148  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_mem_clock":                                         1215,
   149  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_mig_current_mode_disabled":                         0,
   150  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_mig_current_mode_enabled":                          1,
   151  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_mig_devices_count":                                 2,
   152  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_pcie_bandwidth_usage_rx":                           0,
   153  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_pcie_bandwidth_usage_tx":                           0,
   154  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_pcie_bandwidth_utilization_rx":                     0,
   155  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_pcie_bandwidth_utilization_tx":                     0,
   156  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P0":                              1,
   157  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P1":                              0,
   158  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P10":                             0,
   159  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P11":                             0,
   160  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P12":                             0,
   161  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P13":                             0,
   162  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P14":                             0,
   163  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P15":                             0,
   164  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P2":                              0,
   165  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P3":                              0,
   166  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P4":                              0,
   167  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P5":                              0,
   168  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P6":                              0,
   169  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P7":                              0,
   170  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P8":                              0,
   171  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_performance_state_P9":                              0,
   172  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_power_draw":                                        66,
   173  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_sm_clock":                                          1410,
   174  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_temperature":                                       36,
   175  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_video_clock":                                       1275,
   176  						"gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_voltage":                                           881,
   177  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_free":             34358689792,
   178  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_used":             0,
   179  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_ecc_error_sram_uncorrectable":       0,
   180  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_free":     20916994048,
   181  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_reserved": 0,
   182  						"mig_instance_1_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_used":     19922944,
   183  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_free":             34358689792,
   184  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_bar1_memory_usage_used":             0,
   185  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_ecc_error_sram_uncorrectable":       0,
   186  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_free":     20916994048,
   187  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_reserved": 0,
   188  						"mig_instance_2_gpu_GPU-27b94a00-ed54-5c24-b1fd-1054085de32a_frame_buffer_memory_usage_used":     19922944,
   189  					}
   190  
   191  					assert.Equal(t, expected, mx)
   192  				},
   193  			},
   194  		},
   195  		"success RTX 4090 Driver 535 [XML]": {
   196  			{
   197  				prepare: prepareCaseRTX4090Driver535formatXML,
   198  				check: func(t *testing.T, nv *NvidiaSMI) {
   199  					mx := nv.Collect()
   200  
   201  					expected := map[string]int64{
   202  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_bar1_memory_usage_free":             267386880,
   203  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_bar1_memory_usage_used":             1048576,
   204  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_decoder_utilization":                0,
   205  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_encoder_utilization":                0,
   206  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_fan_speed_perc":                     0,
   207  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_frame_buffer_memory_usage_free":     25390219264,
   208  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_frame_buffer_memory_usage_reserved": 362807296,
   209  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_frame_buffer_memory_usage_used":     2097152,
   210  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_gpu_utilization":                    0,
   211  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_graphics_clock":                     210,
   212  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_mem_clock":                          405,
   213  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_mem_utilization":                    0,
   214  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_pcie_bandwidth_usage_rx":            0,
   215  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_pcie_bandwidth_usage_tx":            0,
   216  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_pcie_bandwidth_utilization_rx":      0,
   217  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_pcie_bandwidth_utilization_tx":      0,
   218  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P0":               0,
   219  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P1":               0,
   220  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P10":              0,
   221  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P11":              0,
   222  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P12":              0,
   223  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P13":              0,
   224  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P14":              0,
   225  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P15":              0,
   226  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P2":               0,
   227  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P3":               0,
   228  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P4":               0,
   229  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P5":               0,
   230  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P6":               0,
   231  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P7":               0,
   232  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P8":               1,
   233  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_performance_state_P9":               0,
   234  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_power_draw":                         26,
   235  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_sm_clock":                           210,
   236  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_temperature":                        40,
   237  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_video_clock":                        1185,
   238  						"gpu_GPU-71d1acc2-662d-2166-bf9f-65272d2fc437_voltage":                            880,
   239  					}
   240  
   241  					assert.Equal(t, expected, mx)
   242  				},
   243  			},
   244  		},
   245  		"success RTX 3060 [XML]": {
   246  			{
   247  				prepare: prepareCaseRTX3060formatXML,
   248  				check: func(t *testing.T, nv *NvidiaSMI) {
   249  					mx := nv.Collect()
   250  
   251  					expected := map[string]int64{
   252  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_bar1_memory_usage_free":             8586788864,
   253  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_bar1_memory_usage_used":             3145728,
   254  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_decoder_utilization":                0,
   255  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_encoder_utilization":                0,
   256  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_frame_buffer_memory_usage_free":     6228541440,
   257  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_frame_buffer_memory_usage_reserved": 206569472,
   258  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_frame_buffer_memory_usage_used":     5242880,
   259  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_gpu_utilization":                    0,
   260  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_graphics_clock":                     210,
   261  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_mem_clock":                          405,
   262  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_mem_utilization":                    0,
   263  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_pcie_bandwidth_usage_rx":            0,
   264  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_pcie_bandwidth_usage_tx":            0,
   265  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_pcie_bandwidth_utilization_rx":      0,
   266  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_pcie_bandwidth_utilization_tx":      0,
   267  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P0":               0,
   268  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P1":               0,
   269  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P10":              0,
   270  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P11":              0,
   271  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P12":              0,
   272  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P13":              0,
   273  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P14":              0,
   274  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P15":              0,
   275  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P2":               0,
   276  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P3":               0,
   277  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P4":               0,
   278  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P5":               0,
   279  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P6":               0,
   280  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P7":               0,
   281  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P8":               1,
   282  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_performance_state_P9":               0,
   283  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_power_draw":                         8,
   284  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_sm_clock":                           210,
   285  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_temperature":                        45,
   286  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_video_clock":                        555,
   287  						"gpu_GPU-473d8d0f-d462-185c-6b36-6fc23e23e571_voltage":                            631,
   288  					}
   289  
   290  					assert.Equal(t, expected, mx)
   291  				},
   292  			},
   293  		},
   294  		"success Tesla P100 [XML]": {
   295  			{
   296  				prepare: prepareCaseTeslaP100formatXML,
   297  				check: func(t *testing.T, nv *NvidiaSMI) {
   298  					mx := nv.Collect()
   299  
   300  					expected := map[string]int64{
   301  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_bar1_memory_usage_free":             17177772032,
   302  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_bar1_memory_usage_used":             2097152,
   303  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_decoder_utilization":                0,
   304  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_encoder_utilization":                0,
   305  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_frame_buffer_memory_usage_free":     17070817280,
   306  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_frame_buffer_memory_usage_reserved": 108003328,
   307  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_frame_buffer_memory_usage_used":     0,
   308  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_gpu_utilization":                    0,
   309  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_graphics_clock":                     405,
   310  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_mem_clock":                          715,
   311  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_mem_utilization":                    0,
   312  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_pcie_bandwidth_usage_rx":            0,
   313  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_pcie_bandwidth_usage_tx":            0,
   314  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_pcie_bandwidth_utilization_rx":      0,
   315  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_pcie_bandwidth_utilization_tx":      0,
   316  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P0":               1,
   317  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P1":               0,
   318  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P10":              0,
   319  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P11":              0,
   320  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P12":              0,
   321  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P13":              0,
   322  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P14":              0,
   323  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P15":              0,
   324  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P2":               0,
   325  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P3":               0,
   326  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P4":               0,
   327  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P5":               0,
   328  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P6":               0,
   329  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P7":               0,
   330  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P8":               0,
   331  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_performance_state_P9":               0,
   332  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_power_draw":                         26,
   333  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_sm_clock":                           405,
   334  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_temperature":                        38,
   335  						"gpu_GPU-d3da8716-eaab-75db-efc1-60e88e1cd55e_video_clock":                        835,
   336  					}
   337  
   338  					assert.Equal(t, expected, mx)
   339  				},
   340  			},
   341  		},
   342  		"success Tesla P100 [CSV]": {
   343  			{
   344  				prepare: prepareCaseTeslaP100formatCSV,
   345  				check: func(t *testing.T, nv *NvidiaSMI) {
   346  					mx := nv.Collect()
   347  
   348  					expected := map[string]int64{
   349  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_free":     17070817280,
   350  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_reserved": 108003328,
   351  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_used":     0,
   352  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_gpu_utilization":                    0,
   353  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_graphics_clock":                     405,
   354  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_mem_clock":                          715,
   355  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_mem_utilization":                    0,
   356  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P0":               1,
   357  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P1":               0,
   358  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P10":              0,
   359  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P11":              0,
   360  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P12":              0,
   361  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P13":              0,
   362  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P14":              0,
   363  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P15":              0,
   364  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P2":               0,
   365  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P3":               0,
   366  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P4":               0,
   367  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P5":               0,
   368  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P6":               0,
   369  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P7":               0,
   370  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P8":               0,
   371  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P9":               0,
   372  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_power_draw":                         28,
   373  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_sm_clock":                           405,
   374  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_temperature":                        37,
   375  						"gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_video_clock":                        835,
   376  					}
   377  
   378  					assert.Equal(t, expected, mx)
   379  				},
   380  			},
   381  		},
   382  		"success RTX 2080 Win [XML]": {
   383  			{
   384  				prepare: prepareCaseRTX2080WinFormatXML,
   385  				check: func(t *testing.T, nv *NvidiaSMI) {
   386  					mx := nv.Collect()
   387  
   388  					expected := map[string]int64{
   389  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_bar1_memory_usage_free":             266338304,
   390  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_bar1_memory_usage_used":             2097152,
   391  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_decoder_utilization":                0,
   392  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_encoder_utilization":                0,
   393  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_fan_speed_perc":                     37,
   394  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_frame_buffer_memory_usage_free":     7494172672,
   395  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_frame_buffer_memory_usage_reserved": 190840832,
   396  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_frame_buffer_memory_usage_used":     903872512,
   397  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_gpu_utilization":                    2,
   398  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_graphics_clock":                     193,
   399  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_mem_clock":                          403,
   400  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_mem_utilization":                    7,
   401  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_pcie_bandwidth_usage_rx":            93184000,
   402  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_pcie_bandwidth_usage_tx":            13312000,
   403  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_pcie_bandwidth_utilization_rx":      58,
   404  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_pcie_bandwidth_utilization_tx":      8,
   405  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P0":               0,
   406  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P1":               0,
   407  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P10":              0,
   408  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P11":              0,
   409  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P12":              0,
   410  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P13":              0,
   411  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P14":              0,
   412  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P15":              0,
   413  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P2":               0,
   414  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P3":               0,
   415  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P4":               0,
   416  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P5":               0,
   417  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P6":               0,
   418  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P7":               0,
   419  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P8":               1,
   420  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_performance_state_P9":               0,
   421  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_power_draw":                         14,
   422  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_sm_clock":                           193,
   423  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_temperature":                        29,
   424  						"gpu_GPU-fbd55ed4-1eec-4423-0a47-ad594b4333e3_video_clock":                        539,
   425  					}
   426  
   427  					assert.Equal(t, expected, mx)
   428  				},
   429  			},
   430  		},
   431  		"fail on queryGPUInfoXML error [XML]": {
   432  			{
   433  				prepare: prepareCaseErrOnQueryGPUInfoXML,
   434  				check: func(t *testing.T, nv *NvidiaSMI) {
   435  					mx := nv.Collect()
   436  
   437  					assert.Equal(t, map[string]int64(nil), mx)
   438  				},
   439  			},
   440  		},
   441  		"fail on queryGPUInfoCSV error [CSV]": {
   442  			{
   443  				prepare: prepareCaseErrOnQueryGPUInfoCSV,
   444  				check: func(t *testing.T, nv *NvidiaSMI) {
   445  					mx := nv.Collect()
   446  
   447  					assert.Equal(t, map[string]int64(nil), mx)
   448  				},
   449  			},
   450  		},
   451  		"fail on queryHelpQueryGPU error": {
   452  			{
   453  				prepare: prepareCaseErrOnQueryHelpQueryGPU,
   454  				check: func(t *testing.T, nv *NvidiaSMI) {
   455  					mx := nv.Collect()
   456  
   457  					assert.Equal(t, map[string]int64(nil), mx)
   458  				},
   459  			},
   460  		},
   461  	}
   462  
   463  	for name, test := range tests {
   464  		t.Run(name, func(t *testing.T) {
   465  			nv := New()
   466  
   467  			for i, step := range test {
   468  				t.Run(fmt.Sprintf("step[%d]", i), func(t *testing.T) {
   469  					step.prepare(nv)
   470  					step.check(t, nv)
   471  				})
   472  			}
   473  		})
   474  	}
   475  }
   476  
   477  type mockNvidiaSMI struct {
   478  	gpuInfoXML           []byte
   479  	errOnQueryGPUInfoXML bool
   480  
   481  	gpuInfoCSV           []byte
   482  	errOnQueryGPUInfoCSV bool
   483  
   484  	helpQueryGPU           []byte
   485  	errOnQueryHelpQueryGPU bool
   486  }
   487  
   488  func (m *mockNvidiaSMI) queryGPUInfoXML() ([]byte, error) {
   489  	if m.errOnQueryGPUInfoXML {
   490  		return nil, errors.New("error on mock.queryGPUInfoXML()")
   491  	}
   492  	return m.gpuInfoXML, nil
   493  }
   494  
   495  func (m *mockNvidiaSMI) queryGPUInfoCSV(_ []string) ([]byte, error) {
   496  	if m.errOnQueryGPUInfoCSV {
   497  		return nil, errors.New("error on mock.queryGPUInfoCSV()")
   498  	}
   499  	return m.gpuInfoCSV, nil
   500  }
   501  
   502  func (m *mockNvidiaSMI) queryHelpQueryGPU() ([]byte, error) {
   503  	if m.errOnQueryHelpQueryGPU {
   504  		return nil, errors.New("error on mock.queryHelpQueryGPU()")
   505  	}
   506  	return m.helpQueryGPU, nil
   507  }
   508  
   509  func prepareCaseMIGA100formatXML(nv *NvidiaSMI) {
   510  	nv.UseCSVFormat = false
   511  	nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLA100SXM4MIG}
   512  }
   513  
   514  func prepareCaseRTX3060formatXML(nv *NvidiaSMI) {
   515  	nv.UseCSVFormat = false
   516  	nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX3060}
   517  }
   518  
   519  func prepareCaseRTX4090Driver535formatXML(nv *NvidiaSMI) {
   520  	nv.UseCSVFormat = false
   521  	nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX4090Driver535}
   522  }
   523  
   524  func prepareCaseTeslaP100formatXML(nv *NvidiaSMI) {
   525  	nv.UseCSVFormat = false
   526  	nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLTeslaP100}
   527  }
   528  
   529  func prepareCaseRTX2080WinFormatXML(nv *NvidiaSMI) {
   530  	nv.UseCSVFormat = false
   531  	nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX2080Win}
   532  }
   533  
   534  func prepareCaseErrOnQueryGPUInfoXML(nv *NvidiaSMI) {
   535  	nv.UseCSVFormat = false
   536  	nv.exec = &mockNvidiaSMI{errOnQueryGPUInfoXML: true}
   537  }
   538  
   539  func prepareCaseTeslaP100formatCSV(nv *NvidiaSMI) {
   540  	nv.UseCSVFormat = true
   541  	nv.exec = &mockNvidiaSMI{helpQueryGPU: dataHelpQueryGPU, gpuInfoCSV: dataCSVTeslaP100}
   542  }
   543  
   544  func prepareCaseErrOnQueryHelpQueryGPU(nv *NvidiaSMI) {
   545  	nv.UseCSVFormat = true
   546  	nv.exec = &mockNvidiaSMI{errOnQueryHelpQueryGPU: true}
   547  }
   548  
   549  func prepareCaseErrOnQueryGPUInfoCSV(nv *NvidiaSMI) {
   550  	nv.UseCSVFormat = true
   551  	nv.exec = &mockNvidiaSMI{helpQueryGPU: dataHelpQueryGPU, errOnQueryGPUInfoCSV: true}
   552  }