diff --git a/tests/test_biosdevname.py b/tests/test_biosdevname.py index 75a3a266..12083979 100644 --- a/tests/test_biosdevname.py +++ b/tests/test_biosdevname.py @@ -1,3 +1,4 @@ +import sys import unittest from mock import patch, Mock @@ -27,9 +28,11 @@ def test_ppn_true(self): class TestDeviceNames(unittest.TestCase): def test(self): with patch("xcp.net.biosdevname.Popen") as popen_mock: - with open("tests/data/physical.biosdevname") as f: + # Python3 Popen().stdout.__iter__ returns bytes. Mock it using mode='rb': + popen_mode = 'r' if sys.version_info.major == 2 else 'rb' + with open("tests/data/physical.biosdevname", popen_mode) as f: fake_output_1 = f.read() - with open("tests/data/all_ethN.biosdevname") as f: + with open("tests/data/all_ethN.biosdevname", popen_mode) as f: fake_output_2 = f.read() communicate_mock = Mock(side_effect=iter([(fake_output_1, ""), (fake_output_2, "")])) diff --git a/tests/test_cmd.py b/tests/test_cmd.py index c6304873..456b03cd 100644 --- a/tests/test_cmd.py +++ b/tests/test_cmd.py @@ -1,3 +1,4 @@ +import sys import unittest from mock import patch, Mock, DEFAULT @@ -30,12 +31,18 @@ def test_fileContents(self): self.assertEqual(data, "line1\nline2\n") def test_runCmd(self): - output_data = "line1\nline2\n" + mock_popen_stdout = expected_stdout = "line1\nline2\n" + mock_popen_stderr = expected_stderr = "mock error" + # Python3 Popen().communicate() returns a tuple of bytes: + if sys.version_info.major != 2: + mock_popen_stdout = expected_stdout.encode() + mock_popen_stderr = expected_stderr.encode() + with patch("xcp.cmd.subprocess.Popen") as popen_mock: # mock Popen .communicate and .returncode for - # `output_data`on stdout, nothing on stderr, and exit + # `mock_popen_stdout`on stdout, `mock_popen_stderr` on stderr, and an exit # value of 42 - communicate_mock = Mock(return_value=(output_data, "")) + communicate_mock = Mock(return_value=(mock_popen_stdout, mock_popen_stderr)) popen_mock.return_value.communicate = communicate_mock def communicate_side_effect(_input_text): popen_mock.return_value.returncode = 42 @@ -45,10 +52,10 @@ def communicate_side_effect(_input_text): # uncached runCmd data = self.c.runCmd(['ls', '/tmp'], True) popen_mock.assert_called_once() - self.assertEqual(data, (42, output_data)) + self.assertEqual(data, (42, expected_stdout)) # rerun as cached popen_mock.reset_mock() - data = self.c.runCmd(['ls', '/tmp'], True) + data = self.c.runCmd(['ls', '/tmp'], with_stdout=True, with_stderr=True) popen_mock.assert_not_called() - self.assertEqual(data, (42, output_data)) + self.assertEqual(data, (42, expected_stdout, expected_stderr)) diff --git a/tests/test_pci.py b/tests/test_pci.py index 1895e88a..e4ec4aa7 100644 --- a/tests/test_pci.py +++ b/tests/test_pci.py @@ -1,3 +1,4 @@ +import sys import subprocess import unittest from mock import patch, Mock @@ -78,15 +79,40 @@ def tests_videoclass(self): video_class = ids.lookupClass('Display controller') self.assertEqual(video_class, ['03']) + # Python3 Popen().stdout.__iter__ returns bytes. Mock it using mode='rb': + popen_mode = 'r' if sys.version_info.major == 2 else 'rb' + with patch("xcp.pci.subprocess.Popen") as popen_mock, \ - open("tests/data/lspci-mn") as fake_data: + open("tests/data/lspci-mn", popen_mode) as fake_data: popen_mock.return_value.stdout.__iter__ = Mock(return_value=iter(fake_data)) devs = PCIDevices() popen_mock.assert_called_once_with(['lspci', '-mn'], bufsize = 1, stdout = subprocess.PIPE) sorted_devices = sorted(devs.findByClass(video_class), key=lambda x: x['id']) - self.assertEqual(len(sorted_devices), 2) + expected = [ + { + "id": "03:00.0", + "class": "03", + "subclass": "80", + "vendor": "1002", + "device": "7340", + "subvendor": "1462", + "subdevice": "12ac", + }, + { + "id": "07:00.0", + "class": "03", + "subclass": "00", + "vendor": "1002", + "device": "1636", + "subvendor": "1462", + "subdevice": "12ac", + }, + ] + self.assertEqual(len(sorted_devices), len(expected)) + for device in [0, 1]: + self.assertDictEqual(expected[device], sorted_devices[device]) for (video_dev, num_functions, diff --git a/xcp/cmd.py b/xcp/cmd.py index 16cfb64f..e19e932b 100644 --- a/xcp/cmd.py +++ b/xcp/cmd.py @@ -41,9 +41,11 @@ def runCmd(command, with_stdout = False, with_stderr = False, inputtext = None): l = "ran %s; rc %d" % (str(command), rv) if inputtext: l += " with input %s" % inputtext - if out != "": + if out: + out = out.decode() l += "\nSTANDARD OUT:\n" + out - if err != "": + if err: + err = err.decode() l += "\nSTANDARD ERROR:\n" + err for line in l.split('\n'): diff --git a/xcp/net/biosdevname.py b/xcp/net/biosdevname.py index 78995056..60ddfe82 100644 --- a/xcp/net/biosdevname.py +++ b/xcp/net/biosdevname.py @@ -65,7 +65,7 @@ def all_devices_all_names(): if retcode: continue - for device in (x.strip() for x in stdout.split("\n\n") if len(x)): + for device in (x.strip() for x in stdout.decode().split("\n\n") if len(x)): dinfo = {} for l in device.split("\n"): diff --git a/xcp/pci.py b/xcp/pci.py index 1f911a6b..cbd312c3 100644 --- a/xcp/pci.py +++ b/xcp/pci.py @@ -259,7 +259,7 @@ def __init__(self): stdout = subprocess.PIPE) for l in cmd.stdout: line = l.rstrip() - el = [x for x in line.replace('"', '').split() if not x.startswith('-')] + el = [x for x in line.decode().replace('"', '').split() if not x.startswith('-')] self.devs[el[0]] = {'id': el[0], 'class': el[1][:2], 'subclass': el[1][2:],