Added tests for updater.core
This commit is contained in:
parent
2a8294d6d0
commit
455c987b67
0
test/__init__.py
Normal file
0
test/__init__.py
Normal file
13
test/conftest.py
Normal file
13
test/conftest.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import pytest
|
||||||
|
import json
|
||||||
|
|
||||||
|
update_data= dict(current_version="1.1", description="Snapshot version.", downloads=dict(Windows32="https://google.com_32", Windows64="https://google.com_64"))
|
||||||
|
@pytest.fixture
|
||||||
|
def file_data():
|
||||||
|
global update_data
|
||||||
|
yield json.dumps(update_data)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def json_data():
|
||||||
|
global update_data
|
||||||
|
yield update_data
|
BIN
test/helloworld_v2_win64.zip
Normal file
BIN
test/helloworld_v2_win64.zip
Normal file
Binary file not shown.
164
test/test_core.py
Normal file
164
test/test_core.py
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pytest
|
||||||
|
import requests_mock
|
||||||
|
from unittest import mock
|
||||||
|
from json.decoder import JSONDecodeError
|
||||||
|
from requests.exceptions import HTTPError
|
||||||
|
from updater import core
|
||||||
|
|
||||||
|
app_name: str = "a simple app"
|
||||||
|
current_version: str = "0.15"
|
||||||
|
endpoint: str = "https://gitlab.mcvsoftware.com"
|
||||||
|
|
||||||
|
# Fake a win32api module, as this fails on non-windows platforms without this hack.
|
||||||
|
# ToDo: Find a way to do this better.
|
||||||
|
win32api = mock.Mock(name="win32api")
|
||||||
|
win32api.__name__ = "win32api"
|
||||||
|
sys.modules["win32api"] = win32api
|
||||||
|
|
||||||
|
def test_requests_session():
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
assert hasattr(updater, "session")
|
||||||
|
assert app_name in updater.session.headers.get("User-Agent")
|
||||||
|
assert current_version in updater.session.headers.get("User-Agent")
|
||||||
|
|
||||||
|
def test_get_update_information_valid_json(file_data, json_data):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||||
|
mocked.get(endpoint, json=json_data)
|
||||||
|
contents = updater.get_update_information()
|
||||||
|
assert contents == json_data
|
||||||
|
|
||||||
|
def test_get_update_information_invalid_json(file_data, json_data):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||||
|
mocked.get(endpoint, text="thisisnotjson")
|
||||||
|
with pytest.raises(JSONDecodeError):
|
||||||
|
contents = updater.get_update_information()
|
||||||
|
|
||||||
|
def test_get_update_information_not_found():
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with requests_mock.Mocker(session=updater.session) as mocked:
|
||||||
|
mocked.get(endpoint, status_code=404)
|
||||||
|
with pytest.raises(HTTPError):
|
||||||
|
contents = updater.get_update_information()
|
||||||
|
|
||||||
|
def test_version_data_no_update(json_data):
|
||||||
|
global app_name, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=json_data.get("current_version"))
|
||||||
|
updater.create_session()
|
||||||
|
results = updater.get_version_data(json_data)
|
||||||
|
assert results == (False, False, False)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("platform, architecture", [
|
||||||
|
("Windows", ("32bit", "")),
|
||||||
|
("Windows", ("64bit", "")),
|
||||||
|
])
|
||||||
|
def test_version_data_update_available(json_data, platform, architecture):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with mock.patch("platform.system", return_value=platform):
|
||||||
|
with mock.patch("platform.architecture", return_value=architecture):
|
||||||
|
results = updater.get_version_data(json_data)
|
||||||
|
k = platform+architecture[0][:2]
|
||||||
|
assert results == (json_data["current_version"], json_data["description"], json_data["downloads"][k])
|
||||||
|
|
||||||
|
def test_version_data_architecture_not_found(json_data):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with mock.patch("platform.system", return_value="nonos"):
|
||||||
|
with mock.patch("platform.architecture", return_value=("31bits", "")):
|
||||||
|
with pytest.raises(KeyError):
|
||||||
|
results = updater.get_version_data(json_data)
|
||||||
|
|
||||||
|
def test_download_update():
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
updater.create_session()
|
||||||
|
with mock.patch("pubsub.pub.sendMessage") as sendMessage_mock:
|
||||||
|
with mock.patch("io.open") as open_mock:
|
||||||
|
with requests_mock.Mocker(session=updater.session) as mocker:
|
||||||
|
updatefile = os.path.join(os.path.dirname(__file__), "helloworld_v2_win64.zip")
|
||||||
|
mocker.get("http://downloads.update.org/update.zip", body=open(updatefile, "rb"))
|
||||||
|
result = updater.download_update(update_url="http://downloads.update.org/update.zip", update_destination="update.zip")
|
||||||
|
open_mock.assert_called_once_with("update.zip", "w+b")
|
||||||
|
assert result == "update.zip"
|
||||||
|
assert sendMessage_mock.call_count > 0
|
||||||
|
|
||||||
|
def test_extract_archive():
|
||||||
|
# This only tests if archive extraction methods were called successfully and with the right parameters.
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
zipfile_opened = mock.MagicMock()
|
||||||
|
with mock.patch("zipfile.ZipFile", return_value=zipfile_opened) as zipfile_mock:
|
||||||
|
result = updater.extract_update("update.zip", os.path.dirname(__file__))
|
||||||
|
assert result == os.path.dirname(__file__)
|
||||||
|
zipfile_mock.called_once_with("update.zip")
|
||||||
|
zipfile_opened.extractall.assert_called_once()
|
||||||
|
# Test a password protected update file.
|
||||||
|
zipfile_opened_with_password = mock.MagicMock()
|
||||||
|
with mock.patch("zipfile.ZipFile", return_value=zipfile_opened_with_password) as zipfile_mock:
|
||||||
|
# Set a password manually.
|
||||||
|
updater.password = "MyLongPassword"
|
||||||
|
result2 = updater.extract_update("update.zip", os.path.dirname(__file__))
|
||||||
|
assert result2 == os.path.dirname(__file__)
|
||||||
|
zipfile_mock.called_once_with("update.zip")
|
||||||
|
zipfile_opened_with_password.setpassword.called_once_with("MyLongPassword")
|
||||||
|
zipfile_opened_with_password.extractall.assert_called_once()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("system", [("Windows"), ("Darwin"), ("Linux")])
|
||||||
|
def test_move_bootstrap(system):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
# provide a fake extraction path.
|
||||||
|
extracted_path = os.path.dirname(__file__)
|
||||||
|
# supposedly, the bootstrap file should be moved to the parent path.
|
||||||
|
|
||||||
|
with mock.patch("platform.system", return_value=system):
|
||||||
|
with mock.patch("os.rename") as os_rename:
|
||||||
|
expected_path = os.path.abspath(os.path.join(extracted_path, "..", updater.bootstrap_name()))
|
||||||
|
result = updater.move_bootstrap(extracted_path)
|
||||||
|
assert result == expected_path
|
||||||
|
os_rename.assert_called_once()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("system", [("Windows"), ("Darwin"), ("Linux")])
|
||||||
|
def test_execute_bootstrap(system):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
with mock.patch("platform.system", return_value=system):
|
||||||
|
with mock.patch("os.stat") as os_stat:
|
||||||
|
with mock.patch("subprocess.Popen") as subprocess_popen:
|
||||||
|
with mock.patch("os.chmod") as os_chmod:
|
||||||
|
with mock.patch("win32api.ShellExecute") as win32api_ShellExecute:
|
||||||
|
bootstrap_path = os.path.join(os.path.dirname(__file__), updater.bootstrap_name())
|
||||||
|
source_path = os.path.dirname(__file__)
|
||||||
|
updater.execute_bootstrap(bootstrap_path, source_path)
|
||||||
|
if system == "Windows":
|
||||||
|
win32api_ShellExecute.assert_called_once()
|
||||||
|
else:
|
||||||
|
os_chmod.assert_called_once()
|
||||||
|
os_stat.assert_called_once()
|
||||||
|
subprocess_popen.assert_called_once()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("system, bootstrap_file", [
|
||||||
|
("Windows", "bootstrap.exe"),
|
||||||
|
("Darwin", "bootstrap-mac.sh"),
|
||||||
|
("Linux", "bootstrap-lin.sh")
|
||||||
|
])
|
||||||
|
def test_bootstrap_name(system, bootstrap_file):
|
||||||
|
global app_name, current_version, endpoint
|
||||||
|
updater = core.updaterCore(endpoint=endpoint, app_name=app_name, current_version=current_version)
|
||||||
|
with mock.patch("platform.system", return_value=system):
|
||||||
|
result = updater.bootstrap_name()
|
||||||
|
assert result == bootstrap_file
|
Loading…
Reference in New Issue
Block a user