11import subprocess
22import unittest
3+ from os import environ
4+
5+ import pyfakefs .fake_filesystem_unittest # type: ignore[import]
36from mock import patch , Mock
47
58from xcp .pci import PCI , PCIIds , PCIDevices
@@ -66,7 +69,23 @@ def tests_nodb(self):
6669 PCIIds .read ()
6770 exists_mock .assert_called_once_with ("/usr/share/hwdata/pci.ids" )
6871
69- def tests_videoclass (self ):
72+ def test_videoclass_without_mock (self ):
73+ """
74+ Verifies that xcp.pci uses the open() and Popen() correctly across versions.
75+ Tests PCIIds.read() and PCIDevices() without mock for verifying compatibility
76+ with all Python versions.
77+ (The old test using moc could not detect a missing step in the Py3 migration)
78+ """
79+ with pyfakefs .fake_filesystem_unittest .Patcher () as p :
80+ assert p .fs
81+ p .fs .add_real_file ("tests/data/pci.ids" , target_path = "/usr/share/hwdata/pci.ids" )
82+ ids = PCIIds .read ()
83+ saved_PATH = environ ["PATH" ]
84+ environ ["PATH" ] = "tests/data" # Let PCIDevices() call Popen("tests/data/lspci")
85+ self .assert_videoclass_devices (ids , PCIDevices ())
86+ environ ["PATH" ] = saved_PATH
87+
88+ def test_videoclass_by_mock_calls (self ):
7089 with patch ("xcp.pci.os.path.exists" ) as exists_mock , \
7190 patch ("xcp.pci.open" ) as open_mock , \
7291 open ("tests/data/pci.ids" ) as fake_data :
@@ -75,15 +94,26 @@ def tests_videoclass(self):
7594 ids = PCIIds .read ()
7695 exists_mock .assert_called_once_with ("/usr/share/hwdata/pci.ids" )
7796 open_mock .assert_called_once_with ("/usr/share/hwdata/pci.ids" )
78- video_class = ids .lookupClass ('Display controller' )
79- self .assertEqual (video_class , ['03' ])
97+ self .assert_videoclass_devices (ids , self .mock_lspci_using_open_testfile ())
8098
99+ @classmethod
100+ def mock_lspci_using_open_testfile (cls ):
101+ """Mock xcp.pci.PCIDevices.Popen() using open(tests/data/lspci-mn)"""
102+ # Note: Mocks Popen using open, which is wrong, but mocking using Popen is
103+ # not supported by mock, so the utility of this test is limited - may be removed
81104 with patch ("xcp.pci.subprocess.Popen" ) as popen_mock , \
82105 open ("tests/data/lspci-mn" ) as fake_data :
83106 popen_mock .return_value .stdout .__iter__ = Mock (return_value = iter (fake_data ))
84107 devs = PCIDevices ()
85- popen_mock .assert_called_once_with (['lspci' , '-mn' ], bufsize = 1 ,
86- stdout = subprocess .PIPE )
108+ popen_mock .assert_called_once_with (
109+ ["lspci" , "-mn" ], bufsize = 1 , stdout = subprocess .PIPE , universal_newlines = True
110+ )
111+ return devs
112+
113+ def assert_videoclass_devices (self , ids , devs ): # type: (PCIIds, PCIDevices) -> None
114+ """Verification function for checking the otuput of PCIDevices.findByClass()"""
115+ video_class = ids .lookupClass ('Display controller' )
116+ self .assertEqual (video_class , ["03" ])
87117 sorted_devices = sorted (devs .findByClass (video_class ),
88118 key = lambda x : x ['id' ])
89119 self .assertEqual (len (sorted_devices ), 2 )
0 commit comments