Skip to content

Commit 2ff42c5

Browse files
committed
Merge branch 'testsuite-driven-py3'
* testsuite-driven-py3: CI: also run tests with python3 Pylint complements: avoid no-else-raise "refactor" issues Pylint complements: test_ifrename_logic: disable "no-member" warning Pylint complements: whitespace in expressions Pylint complements: honor len-as-condition convention WIP xcp.repository: switch from ConfigParser to configparser xcp.repository: switch from md5 to hashlib.md5 WIP python3: fix xmlunwrap and its test to align with the use of bytes cpiofile: migrate last "list.sort()" call still using a "cmp" argument test_cpio: ensure paths are handled as text ifrename: don't rely on dict ordering in tests test_dom0: mock "open()" in a python3-compatible way python3: use raw strings for regexps, fixes insufficient quoting xcp.net.ifrename.logic: use "logger.warning", "logger.warn" is deprecated python3: xcp.net.mac: use six.python_2_unicode_compatible for stringification Remove direct call's to file's constructor and replace them with calls to open() as ths is considered best practice. python3: use "six.ensure_binary" and "six.ensure_text" for str/bytes conversion python3: use six.string_types not version-dependant types Signed-off-by: Yann Dirson <[email protected]>
2 parents 723dfe0 + 92b2913 commit 2ff42c5

22 files changed

+188
-154
lines changed

.github/workflows/main.yml

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,54 @@ name: Unit tests
33
on: [push, pull_request]
44

55
jobs:
6-
test_py2:
7-
runs-on: ubuntu-20.04
6+
test:
7+
strategy:
8+
matrix:
9+
include:
10+
- pyversion: '2.7'
11+
os: ubuntu-20.04
12+
- pyversion: '3'
13+
os: ubuntu-latest
14+
runs-on: ${{ matrix.os }}
815

916
steps:
1017
- uses: actions/checkout@v2
1118
with:
1219
fetch-depth: 0
13-
- name: Set up Python 2.7
20+
- name: Set up Python ${{ matrix.pyversion }}
1421
uses: actions/setup-python@v2
1522
with:
16-
python-version: '2.7'
23+
python-version: ${{ matrix.pyversion }}
1724

1825
- name: Install dependencies
1926
run: |
2027
python -m pip install --upgrade pip
2128
pip install -r requirements-dev.txt
2229
# FIXME: branding.py still has no permanent home
2330
curl https://gist.github.com/ydirson/3c36a7e19d762cc529a6c82340894ccc/raw/5ca39f621b1feab813e171f535c1aad1bd483f1d/branding.py -O -L
24-
pip install pyliblzma
2531
pip install -e .
2632
command -v xz
2733
2834
- name: Test
2935
run: |
3036
pytest --cov -rP
3137
coverage xml
32-
coverage html
33-
coverage html -d htmlcov-tests --include="tests/*"
34-
diff-cover --html-report coverage-diff.html coverage.xml
38+
coverage html -d htmlcov-${{ matrix.pyversion }}
39+
coverage html -d htmlcov-tests-${{ matrix.pyversion }} --include="tests/*"
40+
diff-cover --compare-branch=origin/master --html-report coverage-diff-${{ matrix.pyversion }}.html coverage.xml
3541
3642
- name: Pylint
3743
run: |
3844
pylint --version
3945
pylint --exit-zero xcp/ tests/ setup.py
4046
pylint --exit-zero --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" xcp/ tests/ setup.py > pylint.txt
41-
diff-quality --violations=pylint --html-report pylint-diff.html pylint.txt
47+
diff-quality --compare-branch=origin/master --violations=pylint --html-report pylint-diff-${{ matrix.pyversion }}.html pylint.txt
4248
4349
- uses: actions/upload-artifact@v3
4450
with:
4551
name: Coverage and pylint reports
4652
path: |
47-
coverage-diff.html
48-
pylint-diff.html
49-
htmlcov
50-
htmlcov-tests
53+
coverage-diff-${{ matrix.pyversion }}.html
54+
pylint-diff-${{ matrix.pyversion }}.html
55+
htmlcov-${{ matrix.pyversion }}
56+
htmlcov-tests-${{ matrix.pyversion }}

requirements-dev.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ diff_cover
55
mock
66
pytest
77
pytest-cov
8+
parameterized
89
# dependencies also in setup.py until they can be used
910
six
1011
future
12+
13+
# python-2.7 only
14+
configparser ; python_version < "3.0"
15+
pyliblzma ; python_version < "3.0"
32.8 KB
Binary file not shown.

tests/test_accessor.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
11
import unittest
2+
import hashlib
3+
from tempfile import NamedTemporaryFile
4+
5+
from parameterized import parameterized_class
26

37
import xcp.accessor
48

9+
@parameterized_class([{"url": "file://tests/data/repo/"},
10+
{"url": "https://updates.xcp-ng.org/netinstall/8.2.1"}])
511
class TestAccessor(unittest.TestCase):
6-
def test_http(self):
7-
raise unittest.SkipTest("comment out if you really mean it")
8-
a = xcp.accessor.createAccessor("https://updates.xcp-ng.org/netinstall/8.2.1", True)
12+
def test_access(self):
13+
a = xcp.accessor.createAccessor(self.url, True)
914
a.start()
1015
self.assertTrue(a.access('.treeinfo'))
1116
self.assertFalse(a.access('no_such_file'))
1217
self.assertEqual(a.lastError, 404)
1318
a.finish()
1419

15-
def test_file(self):
16-
a = xcp.accessor.createAccessor("file://tests/data/repo/", True)
20+
def test_file_binfile(self):
21+
BINFILE = "boot/isolinux/mboot.c32"
22+
a = xcp.accessor.createAccessor(self.url, True)
1723
a.start()
18-
self.assertTrue(a.access('.treeinfo'))
19-
self.assertFalse(a.access('no_such_file'))
20-
self.assertEqual(a.lastError, 404)
24+
self.assertTrue(a.access(BINFILE))
25+
inf = a.openAddress(BINFILE)
26+
with NamedTemporaryFile("wb") as outf:
27+
while True:
28+
data = inf.read()
29+
if not data: # EOF
30+
break
31+
outf.write(data)
32+
outf.flush()
33+
hasher = hashlib.md5()
34+
with open(outf.name, "rb") as bincontents:
35+
while True:
36+
data = bincontents.read()
37+
if not data: # EOF
38+
break
39+
hasher.update(data)
40+
csum = hasher.hexdigest()
41+
self.assertEqual(csum, "eab52cebc3723863432dc672360f6dac")
2142
a.finish()

tests/test_cpio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ def writeRandomFile(fn, size, start=b'', add=b'a'):
1414
with open(fn, 'wb') as f:
1515
m = md5()
1616
m.update(start)
17-
assert(len(add) != 0)
17+
assert add
1818
while size > 0:
1919
d = m.digest()
2020
if size < len(d):
21-
d=d[:size]
21+
d = d[:size]
2222
f.write(d)
2323
size -= len(d)
2424
m.update(add)

tests/test_dom0.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def mock_version(open_mock, version):
3030
(2*1024, 4*1024, 8*1024), # Above max
3131
]
3232

33-
with patch("__builtin__.open") as open_mock:
33+
with patch("xcp.dom0.open") as open_mock:
3434
for host_gib, dom0_mib, _ in test_values:
3535
mock_version(open_mock, '2.8.0')
3636
expected = dom0_mib * 1024;
@@ -39,7 +39,7 @@ def mock_version(open_mock, version):
3939

4040
open_mock.assert_called_with("/etc/xensource-inventory")
4141

42-
with patch("__builtin__.open") as open_mock:
42+
with patch("xcp.dom0.open") as open_mock:
4343
for host_gib, _, dom0_mib in test_values:
4444
mock_version(open_mock, '2.9.0')
4545
expected = dom0_mib * 1024;

tests/test_ifrename_dynamic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@ def test_pci_matching_invert(self):
125125
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", kname="eth1",
126126
ppn="", label="")])
127127

128-
self.assertEqual(dr.rules,[
128+
self.assertEqual(set(dr.rules), set([
129129
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth1"),
130130
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth0")
131-
])
131+
]))
132132

133133
def test_pci_missing(self):
134134

tests/test_ifrename_logic.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ def test_ibft_nic_to_ibft(self):
518518

519519

520520
class TestInputSanitisation(unittest.TestCase):
521+
# pylint: disable=no-member
521522

522523
def setUp(self):
523524
"""

tests/test_ifrename_static.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,10 @@ def test_pci_matching(self):
375375

376376
sr.generate(self.state)
377377

378-
self.assertEqual(sr.rules,[
379-
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth1"),
380-
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth0")
381-
])
378+
self.assertEqual(set(sr.rules), set([
379+
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth1"),
380+
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth0")
381+
]))
382382

383383
def test_pci_matching_invert(self):
384384

@@ -389,10 +389,10 @@ def test_pci_matching_invert(self):
389389

390390
sr.generate(self.state)
391391

392-
self.assertEqual(sr.rules,[
393-
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth1"),
394-
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth0")
395-
])
392+
self.assertEqual(set(sr.rules), set([
393+
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth1"),
394+
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth0")
395+
]))
396396

397397
def test_pci_matching_mixed(self):
398398

@@ -403,10 +403,10 @@ def test_pci_matching_mixed(self):
403403

404404
sr.generate(self.state)
405405

406-
self.assertEqual(sr.rules,[
407-
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth0"),
408-
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth1")
409-
])
406+
self.assertEqual(set(sr.rules), set([
407+
MACPCI("c8:cb:b8:d3:0c:cf", "0000:04:00.0", tname="eth0"),
408+
MACPCI("c8:cb:b8:d3:0c:ce", "0000:04:00.0", tname="eth1")
409+
]))
410410

411411
def test_pci_missing(self):
412412

tests/test_repository.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
import unittest
2+
from parameterized import parameterized_class
23

34
import xcp.accessor
45
from xcp import repository
56
from xcp.version import Version
67

8+
@parameterized_class([{"url": "file://tests/data/repo/"},
9+
{"url": "https://updates.xcp-ng.org/netinstall/8.2.1"}])
710
class TestRepository(unittest.TestCase):
8-
def test_http(self):
9-
raise unittest.SkipTest("comment out if you really mean it")
10-
a = xcp.accessor.createAccessor("https://updates.xcp-ng.org/netinstall/8.2.1", True)
11-
repo_ver = repository.BaseRepository.getRepoVer(a)
12-
self.assertEqual(repo_ver, Version([3, 2, 1]))
13-
product_ver = repository.BaseRepository.getProductVersion(a)
14-
self.assertEqual(product_ver, Version([8, 2, 1]))
15-
repos = repository.BaseRepository.findRepositories(a)
16-
self.assertEqual(len(repos), 1)
17-
18-
def test_file(self):
19-
a = xcp.accessor.createAccessor("file://tests/data/repo/", True)
11+
def test_basicinfo(self):
12+
a = xcp.accessor.createAccessor(self.url, True)
2013
repo_ver = repository.BaseRepository.getRepoVer(a)
2114
self.assertEqual(repo_ver, Version([3, 2, 1]))
2215
product_ver = repository.BaseRepository.getProductVersion(a)

0 commit comments

Comments
 (0)