Skip to content

Commit 9f637f1

Browse files
committed
[skip-changelog] add integration testing infrastructure
1 parent 6ae09d2 commit 9f637f1

File tree

8 files changed

+321
-1
lines changed

8 files changed

+321
-1
lines changed

.github/workflows/test.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,13 @@ jobs:
4848
GOARCH: "arm"
4949
run: task build
5050

51-
- name: Run unit tests
51+
- name: Install Python
52+
uses: actions/setup-python@v2
53+
with:
54+
python-version: "3.8"
55+
56+
- name: Install Poetry
57+
run: pip install poetry
58+
59+
- name: Run unit and integration tests
5260
run: task test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.idea
55
coverage_*.txt
66
/dist
7+
__pycache__/
78

89
# Misc.
910
.DS_Store

Taskfile.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,21 @@ tasks:
3333

3434
test:
3535
desc: Run tests
36+
cmds:
37+
- task: test-unit
38+
- task: test-integration
39+
40+
test-unit:
41+
desc: Run unit tests
3642
cmds:
3743
- go test -short -race -run '.*' {{ default "-v" .GOFLAGS }} -coverprofile=coverage_unit.txt ./... {{.TEST_LDFLAGS}}
3844

45+
test-integration:
46+
desc: Run integration tests
47+
cmds:
48+
- poetry install --no-root
49+
- poetry run pytest test
50+
3951
check:
4052
desc: Check fmt and lint
4153
cmds:

poetry.lock

Lines changed: 177 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[tool.poetry]
2+
name = "FirmwareUploader"
3+
version = "0.0.0"
4+
description = "FirmwareUploader"
5+
authors = ["Arduino <info@arduino.cc>"]
6+
7+
[tool.poetry.dependencies]
8+
python = "^3.8"
9+
pytest = "6.1.2"
10+
invoke = "^1.5.0"
11+
semver = "^2.13.0"

test/conftest.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# FirmwareUploader
2+
# Copyright (c) 2021 Arduino LLC. All right reserved.
3+
4+
# This library is free software; you can redistribute it and/or
5+
# modify it under the terms of the GNU Lesser General Public
6+
# License as published by the Free Software Foundation; either
7+
# version 2.1 of the License, or (at your option) any later version.
8+
9+
# This library is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
# Lesser General Public License for more details.
13+
14+
# You should have received a copy of the GNU Lesser General Public
15+
# License along with this library; if not, write to the Free Software
16+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
18+
import pathlib
19+
import platform
20+
import invoke.context
21+
import pytest
22+
23+
@pytest.fixture(scope="function")
24+
def run_command(pytestconfig, working_dir):
25+
"""Provide a wrapper around invoke's `run` API so that every test will work in the same temporary folder.
26+
Useful reference:
27+
http://docs.pyinvoke.org/en/1.4/api/runners.html#invoke.runners.Result
28+
"""
29+
30+
fwuploader_path = pathlib.Path(pytestconfig.rootdir).parent / "FirmwareUploader"
31+
32+
def _run(cmd_string, custom_working_dir=None, custom_env=None):
33+
if not custom_working_dir:
34+
custom_working_dir = working_dir
35+
cli_full_line = '"{}" {}'.format(fwuploader_path, cmd_string)
36+
run_context = invoke.context.Context()
37+
# It might happen that we need to change directories between drives on Windows,
38+
# in that case the "/d" flag must be used otherwise directory wouldn't change
39+
cd_command = "cd"
40+
if platform.system() == "Windows":
41+
cd_command += " /d"
42+
# Context.cd() is not used since it doesn't work correctly on Windows.
43+
# It escapes spaces in the path using "\ " but it doesn't always work,
44+
# wrapping the path in quotation marks is the safest approach
45+
with run_context.prefix(f'{cd_command} "{custom_working_dir}"'):
46+
return run_context.run(
47+
command=cli_full_line, echo=False, hide=True, warn=True, env=custom_env, encoding="utf-8"
48+
)
49+
50+
return _run
51+
52+
53+
@pytest.fixture(scope="function")
54+
def working_dir(tmpdir_factory):
55+
"""Create a temporary folder for the test to run in. It will be created before running each test and deleted at the
56+
end. This way all the tests work in isolation.
57+
"""
58+
work_dir = tmpdir_factory.mktemp(basename="FirmwareUploaderTestWork")
59+
yield str(work_dir)

test/pytest.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[pytest]
2+
filterwarnings =
3+
error
4+
ignore::DeprecationWarning
5+
ignore::ResourceWarning
6+
7+
# --capture=no - disable per-test capture
8+
# --tb=long sets the length of the traceback in case of failures
9+
addopts = --capture=no --tb=long --verbose

test/test_main.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# FirmwareUploader
2+
# Copyright (c) 2021 Arduino LLC. All right reserved.
3+
4+
# This library is free software; you can redistribute it and/or
5+
# modify it under the terms of the GNU Lesser General Public
6+
# License as published by the Free Software Foundation; either
7+
# version 2.1 of the License, or (at your option) any later version.
8+
9+
# This library is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
# Lesser General Public License for more details.
13+
14+
# You should have received a copy of the GNU Lesser General Public
15+
# License along with this library; if not, write to the Free Software
16+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
18+
import json
19+
import semver
20+
21+
def test_help(run_command):
22+
result = run_command("help")
23+
assert result.ok
24+
assert result.stderr == ""
25+
assert "Usage" in result.stdout
26+
27+
28+
def test_version(run_command):
29+
result = run_command("version")
30+
assert result.ok
31+
assert "Version:" in result.stdout
32+
assert "Commit:" in result.stdout
33+
assert "Date:" in result.stdout
34+
assert "" == result.stderr
35+
36+
result = run_command("version --format json")
37+
assert result.ok
38+
parsed_out = json.loads(result.stdout)
39+
assert parsed_out.get("Application", False) == "FirmwareUploader"
40+
version = parsed_out.get("VersionString", False)
41+
assert semver.VersionInfo.isvalid(version=version) or "git-snapshot" in version or "nightly" in version
42+
assert isinstance(parsed_out.get("Commit", False), str)
43+
assert isinstance(parsed_out.get("Date", False), str)

0 commit comments

Comments
 (0)