Skip to content

Commit 6c8656c

Browse files
jlevequeJoe LeVeque
authored andcommitted
[ci] Test and build packages using Azure Pipelines (#164)
Configure Azure Pipelines to run unit tests, build Python wheels and publish the test results, test coverage and resulting wheels. Also fix existing unit tests.
1 parent 1e34c4d commit 6c8656c

File tree

6 files changed

+127
-48
lines changed

6 files changed

+127
-48
lines changed

.artifactignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/*
2+
!dist/*.whl

azure-pipelines.yml

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,101 @@
44
# https://aka.ms/yaml
55

66
trigger:
7-
- master
7+
branches:
8+
include:
9+
- '*'
810

911
pool:
10-
vmImage: ubuntu-20.04
12+
vmImage: 'ubuntu-20.04'
13+
14+
container:
15+
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-buster:latest
1116

1217
steps:
13-
- script: echo Hello, world!
14-
displayName: 'Run a one-line script'
18+
- task: DownloadPipelineArtifact@2
19+
inputs:
20+
source: specific
21+
project: build
22+
pipeline: 1
23+
artifact: sonic-buildimage.kvm
24+
runVersion: 'latestFromBranch'
25+
runBranch: 'refs/heads/master'
26+
displayName: "Download artifacts from latest sonic-buildimage build"
27+
28+
- script: |
29+
set -xe
30+
sudo dpkg -i libnl-3-200_*.deb
31+
sudo dpkg -i libnl-genl-3-200_*.deb
32+
sudo dpkg -i libnl-route-3-200_*.deb
33+
sudo dpkg -i libnl-nf-3-200_*.deb
34+
sudo dpkg -i libhiredis0.14_*.deb
35+
sudo dpkg -i libswsscommon_1.0.0_amd64.deb
36+
sudo dpkg -i python-swsscommon_1.0.0_amd64.deb
37+
sudo dpkg -i python3-swsscommon_1.0.0_amd64.deb
38+
workingDirectory: $(Pipeline.Workspace)/target/debs/buster/
39+
displayName: 'Install Debian dependencies'
40+
41+
- script: |
42+
set -xe
43+
pip2 install swsssdk-2.0.1-py2-none-any.whl
44+
pip2 install sonic_py_common-1.0-py2-none-any.whl
45+
pip2 install sonic_config_engine-1.0-py2-none-any.whl
46+
pip3 install swsssdk-2.0.1-py3-none-any.whl
47+
pip3 install sonic_py_common-1.0-py3-none-any.whl
48+
pip3 install sonic_config_engine-1.0-py3-none-any.whl
49+
workingDirectory: $(Pipeline.Workspace)/target/python-wheels/
50+
displayName: 'Install Python dependencies'
51+
52+
# Python 2
53+
- script: |
54+
python2 setup.py test
55+
displayName: 'Test Python 2'
56+
57+
- task: PublishTestResults@2
58+
inputs:
59+
testResultsFiles: '$(System.DefaultWorkingDirectory)/test-results.xml'
60+
testRunTitle: Python 2
61+
failTaskOnFailedTests: true
62+
condition: succeededOrFailed()
63+
displayName: 'Publish Python 2 test results'
64+
65+
- task: PublishCodeCoverageResults@1
66+
inputs:
67+
codeCoverageTool: Cobertura
68+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage.xml'
69+
reportDirectory: '$(System.DefaultWorkingDirectory)/htmlcov/'
70+
displayName: 'Publish Python 2 test coverage'
71+
72+
- script: |
73+
set -e
74+
python2 setup.py bdist_wheel
75+
displayName: 'Build Python 2 wheel'
76+
77+
# Python 3
78+
- script: |
79+
python3 setup.py test
80+
displayName: 'Test Python 3'
81+
82+
- task: PublishTestResults@2
83+
inputs:
84+
testResultsFiles: '$(System.DefaultWorkingDirectory)/test-results.xml'
85+
testRunTitle: Python 3
86+
failTaskOnFailedTests: true
87+
condition: succeededOrFailed()
88+
displayName: 'Publish Python 3 test results'
89+
90+
- task: PublishCodeCoverageResults@1
91+
inputs:
92+
codeCoverageTool: Cobertura
93+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage.xml'
94+
reportDirectory: '$(System.DefaultWorkingDirectory)/htmlcov/'
95+
displayName: 'Publish Python 3 test coverage'
1596

1697
- script: |
17-
echo Add other tasks to build, test, and deploy your project.
18-
echo See https://aka.ms/yaml
19-
displayName: 'Run a multi-line script'
98+
set -e
99+
python3 setup.py bdist_wheel
100+
displayName: 'Build Python 3 wheel'
101+
102+
- publish: '$(System.DefaultWorkingDirectory)/dist/'
103+
artifact: wheels
104+
displayName: "Publish Python wheels"

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[pytest]
2-
addopts = --cov=sonic_platform_base --cov-report html
2+
addopts = --cov=sonic_platform_base --cov-report html --cov-report term --cov-report xml --junitxml=test-results.xml -v

setup.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
'sonic_thermal',
2626
'sonic_y_cable',
2727
],
28-
# NOTE: Install also depends on sonic-config-engine for portconfig.py, but we are not yet
29-
# building a Python 3 version of sonic-config-engine. Also, this dependency should be
30-
# eliminated by moving portconfig.py functionality into sonic-py-common
28+
# NOTE: Install also depends on sonic-config-engine for portconfig.py
29+
# This dependency should be eliminated by moving portconfig.py
30+
# functionality into sonic-py-common
3131
install_requires=[
3232
'natsort==6.2.1', # 6.2.1 is the last version which supports Python 2
3333
'PyYAML',
3434
'redis',
35+
'sonic-config-engine',
3536
'sonic-py-common'
3637
],
3738
setup_requires = [
File renamed without changes.

tests/sfputilhelper_test.py

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,44 @@
22
import sys
33

44
import pytest
5-
try:
6-
import sonic_platform_base.sonic_sfp.sfputilhelper
7-
except Exception as e:
8-
print("Failed to load sonic_platform_base.sonic_sfp.sfputilhelper due to {}".format(repr(e)))
5+
6+
from sonic_platform_base.sonic_sfp import sfputilhelper
97

108

119
@pytest.fixture(scope="class")
1210
def setup_class(request):
1311
# Configure the setup
1412
test_dir = os.path.dirname(os.path.realpath(__file__))
15-
request.cls.port_config = os.path.join(
16-
test_dir, 't0-sample-port-config.ini')
17-
18-
request.cls.port_config = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper()
13+
request.cls.port_config_file = os.path.join(test_dir, 'port_config.ini')
1914

2015

2116
@pytest.mark.usefixtures("setup_class")
2217
class TestSfpUtilHelper(object):
2318

24-
platform_sfputil = None
25-
port_config = None
19+
port_config_file = None
2620

2721
def test_read_port_mappings(self):
28-
29-
try:
30-
platform_sfputil.read_porttab_mappings(self.port_config, 0)
31-
except Exception as e:
32-
print("Failed to read port tab mappings to {}".format(repr(e)))
33-
34-
PORT_LIST = ["Ethernet0",
35-
"Ethernet4",
36-
"Ethernet8",
37-
"Ethernet12",
38-
"Ethernet16",
39-
"Ethernet20",
40-
"Ethernet24",
41-
"Ethernet28",
42-
"Ethernet32",
43-
"Ethernet36",
44-
"Ethernet40",
45-
"Ethernet44",
46-
"Ethernet48"]
47-
48-
if self.platform_sfputil is not None:
49-
logical_port_list = self.platform_sfputil.logical
50-
assert len(logical_port_name) == len(self.port_list)
51-
for logical_port_name in logical_port_list:
52-
assert logical_port_name in PORT_LIST
53-
else:
54-
print("platform_sfputil is None, cannot read Ports")
22+
PORT_LIST = [
23+
"Ethernet0",
24+
"Ethernet4",
25+
"Ethernet8",
26+
"Ethernet12",
27+
"Ethernet16",
28+
"Ethernet20",
29+
"Ethernet24",
30+
"Ethernet28",
31+
"Ethernet32",
32+
"Ethernet36",
33+
"Ethernet40",
34+
"Ethernet44",
35+
"Ethernet48"
36+
]
37+
38+
sfputil_helper = sfputilhelper.SfpUtilHelper()
39+
sfputil_helper.read_porttab_mappings(self.port_config_file, 0)
40+
41+
logical_port_list = sfputil_helper.logical
42+
assert len(logical_port_list) == len(PORT_LIST)
43+
44+
for logical_port_name in logical_port_list:
45+
assert logical_port_name in PORT_LIST

0 commit comments

Comments
 (0)