taffybar-7.2.7: test/unit/System/Taffybar/Information/NvidiaSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module System.Taffybar.Information.NvidiaSpec (spec) where
import Data.Text qualified as T
import System.Taffybar.Information.Nvidia
import Test.Hspec
spec :: Spec
spec = do
describe "NVIDIA information parsing" $ do
it "parses rich nvidia-smi XML snapshots and optional readings" $ do
let info = parseNvidiaGpuInfo sampleXml
map nvidiaInfoIndex info `shouldBe` [0, 2]
case info of
firstGpu : _ -> do
nvidiaInfoName firstGpu `shouldBe` "NVIDIA Test GPU"
nvidiaInfoTemperatureCelsius firstGpu `shouldBe` Just 61
nvidiaInfoMemoryTemperatureCelsius firstGpu `shouldBe` Nothing
nvidiaInfoTargetTemperatureCelsius firstGpu `shouldBe` Just 87
nvidiaInfoThermalHeadroomCelsius firstGpu `shouldBe` Just 26
nvidiaInfoGpuUtilizationPercent firstGpu `shouldBe` Just 37
nvidiaInfoMemoryUsedMiB firstGpu `shouldBe` Just 2048
nvidiaInfoPowerDrawWatts firstGpu `shouldBe` Just 34.5
nvidiaInfoPowerLimitWatts firstGpu `shouldBe` Just 80
[] -> expectationFailure "expected parsed GPU information"
it "rejects malformed XML" $
parseNvidiaGpuInfo "not xml" `shouldBe` []
describe "NVIDIA runtime power states" $ do
it "preserves querying when no NVIDIA PCI devices are detected" $
shouldQueryNvidiaForRuntimeStatuses [] `shouldBe` True
it "skips querying when every device is suspended or suspending" $
shouldQueryNvidiaForRuntimeStatuses
[Just "suspended", Just "suspending"]
`shouldBe` False
it "preserves querying when any device is active" $
shouldQueryNvidiaForRuntimeStatuses
[Just "suspended", Just "active"]
`shouldBe` True
it "preserves querying when any runtime status is missing" $
shouldQueryNvidiaForRuntimeStatuses
[Just "suspended", Nothing]
`shouldBe` True
it "preserves querying for unknown runtime states" $
shouldQueryNvidiaForRuntimeStatuses [Just "unsupported"] `shouldBe` True
describe "NVIDIA temperature parsing" $ do
it "parses and sorts nvidia-smi temperature rows" $
parseNvidiaGpuTemperatures "2, 73\n0, 56\n"
`shouldBe` [ NvidiaGpuTemperature 0 56,
NvidiaGpuTemperature 2 73
]
it "ignores malformed and unavailable rows" $
parseNvidiaGpuTemperatures "0, N/A\nbad row\n1, 64\n"
`shouldBe` [NvidiaGpuTemperature 1 64]
sampleXml :: T.Text
sampleXml =
T.unlines
[ "<nvidia_smi_log>",
" <gpu>",
" <product_name>NVIDIA Second GPU</product_name>",
" <minor_number>2</minor_number>",
" <temperature><gpu_temp>55 C</gpu_temp></temperature>",
" </gpu>",
" <gpu>",
" <product_name>NVIDIA Test GPU</product_name>",
" <minor_number>0</minor_number>",
" <fan_speed>N/A</fan_speed>",
" <performance_state>P2</performance_state>",
" <utilization><gpu_util>37 %</gpu_util><memory_util>3 %</memory_util></utilization>",
" <fb_memory_usage><used>2048 MiB</used><total>12282 MiB</total></fb_memory_usage>",
" <temperature>",
" <gpu_temp>61 C</gpu_temp>",
" <gpu_temp_tlimit>26 C</gpu_temp_tlimit>",
" <gpu_target_temperature>87 C</gpu_target_temperature>",
" <memory_temp>N/A</memory_temp>",
" </temperature>",
" <gpu_power_readings>",
" <average_power_draw>34.50 W</average_power_draw>",
" <current_power_limit>80.00 W</current_power_limit>",
" </gpu_power_readings>",
" </gpu>",
"</nvidia_smi_log>"
]