forked from openlp/openlp
Add distribution detection in is_linux() function
- Optional argument to check Linux distro - Add a test for the new argument - Add some other tests to expand test coverage - Remove Windows from testing - If "distro" module is missing, create a replacement that returns False
This commit is contained in:
parent
3b3f92d8b1
commit
771e97862f
@ -63,19 +63,6 @@ test-macos:
|
|||||||
only:
|
only:
|
||||||
- master@openlp/openlp
|
- master@openlp/openlp
|
||||||
|
|
||||||
test-windows:
|
|
||||||
stage: test
|
|
||||||
tags:
|
|
||||||
- windows
|
|
||||||
script:
|
|
||||||
- C:\Users\raoul\GitLab-Runner\venv\Scripts\pytest.exe --color=no --disable-warnings --cov openlp
|
|
||||||
- mv .coverage windows.coverage
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- windows.coverage
|
|
||||||
only:
|
|
||||||
- master@openlp/openlp
|
|
||||||
|
|
||||||
test-display:
|
test-display:
|
||||||
stage: test
|
stage: test
|
||||||
image: openlp/angular
|
image: openlp/angular
|
||||||
@ -87,7 +74,7 @@ pages:
|
|||||||
stage: deploy
|
stage: deploy
|
||||||
image: openlp/debian
|
image: openlp/debian
|
||||||
script:
|
script:
|
||||||
- python3-coverage combine linux.coverage macos.coverage windows.coverage
|
- python3-coverage combine linux.coverage macos.coverage
|
||||||
- fixpaths .coverage
|
- fixpaths .coverage
|
||||||
- python3-coverage html
|
- python3-coverage html
|
||||||
- mv htmlcov public
|
- mv htmlcov public
|
||||||
@ -99,6 +86,5 @@ pages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- test-debian
|
- test-debian
|
||||||
- test-macos
|
- test-macos
|
||||||
- test-windows
|
|
||||||
only:
|
only:
|
||||||
- master@openlp/openlp
|
- master@openlp/openlp
|
||||||
|
@ -38,6 +38,13 @@ from PyQt5.QtCore import QCryptographicHash as QHash
|
|||||||
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
||||||
from chardet.universaldetector import UniversalDetector
|
from chardet.universaldetector import UniversalDetector
|
||||||
|
|
||||||
|
try:
|
||||||
|
from distro import id as distro_id
|
||||||
|
except ImportError:
|
||||||
|
# The distro module is only valid for Linux, so if it doesn't exist, create a function that always returns False
|
||||||
|
def distro_id():
|
||||||
|
return False
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + '.__init__')
|
log = logging.getLogger(__name__ + '.__init__')
|
||||||
|
|
||||||
|
|
||||||
@ -212,13 +219,17 @@ def is_macosx():
|
|||||||
return sys.platform.startswith('darwin')
|
return sys.platform.startswith('darwin')
|
||||||
|
|
||||||
|
|
||||||
def is_linux():
|
def is_linux(distro=None):
|
||||||
"""
|
"""
|
||||||
Returns true if running on a system with a linux kernel e.g. Ubuntu, Debian, etc
|
Returns true if running on a system with a linux kernel e.g. Ubuntu, Debian, etc
|
||||||
|
|
||||||
|
:param distro: If not None, check if running that Linux distro
|
||||||
:return: True if system is running a linux kernel false otherwise
|
:return: True if system is running a linux kernel false otherwise
|
||||||
"""
|
"""
|
||||||
return sys.platform.startswith('linux')
|
result = sys.platform.startswith('linux')
|
||||||
|
if result and distro:
|
||||||
|
result = result and distro == distro_id()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def is_64bit_instance():
|
def is_64bit_instance():
|
||||||
|
@ -56,6 +56,7 @@ WIN32_MODULES = [
|
|||||||
LINUX_MODULES = [
|
LINUX_MODULES = [
|
||||||
# Optical drive detection.
|
# Optical drive detection.
|
||||||
'dbus',
|
'dbus',
|
||||||
|
'distro',
|
||||||
'Xlib',
|
'Xlib',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
1
setup.py
1
setup.py
@ -101,6 +101,7 @@ using a computer and a data projector.""",
|
|||||||
'beautifulsoup4',
|
'beautifulsoup4',
|
||||||
'chardet',
|
'chardet',
|
||||||
'dbus-python; platform_system=="Linux"',
|
'dbus-python; platform_system=="Linux"',
|
||||||
|
'distro; platform_system=="Linux"',
|
||||||
'lxml',
|
'lxml',
|
||||||
'Mako',
|
'Mako',
|
||||||
'pymediainfo >= 2.2',
|
'pymediainfo >= 2.2',
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
Functional tests to test the AppLocation class and related methods.
|
Functional tests to test the AppLocation class and related methods.
|
||||||
"""
|
"""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase, skipUnless
|
||||||
from unittest.mock import MagicMock, call, patch
|
from unittest.mock import MagicMock, call, patch
|
||||||
|
|
||||||
from openlp.core.common import Singleton, clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
|
from openlp.core.common import Singleton, clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
|
||||||
normalize_str, path_to_module, trace_error_handler
|
is_64bit_instance, normalize_str, path_to_module, trace_error_handler
|
||||||
|
|
||||||
|
|
||||||
class TestCommonFunctions(TestCase):
|
class TestCommonFunctions(TestCase):
|
||||||
@ -243,7 +243,7 @@ class TestCommonFunctions(TestCase):
|
|||||||
# GIVEN: Mocked out objects
|
# GIVEN: Mocked out objects
|
||||||
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
|
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
|
||||||
|
|
||||||
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectivly
|
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectively
|
||||||
mocked_os.name = 'posix'
|
mocked_os.name = 'posix'
|
||||||
mocked_sys.platform = 'linux3'
|
mocked_sys.platform = 'linux3'
|
||||||
|
|
||||||
@ -252,6 +252,40 @@ class TestCommonFunctions(TestCase):
|
|||||||
assert is_win() is False, 'is_win() should return False'
|
assert is_win() is False, 'is_win() should return False'
|
||||||
assert is_macosx() is False, 'is_macosx() should return False'
|
assert is_macosx() is False, 'is_macosx() should return False'
|
||||||
|
|
||||||
|
@skipUnless(is_linux(), 'This can only run on Linux')
|
||||||
|
def test_is_linux_distro(self):
|
||||||
|
"""
|
||||||
|
Test the is_linux() function for a particular Linux distribution
|
||||||
|
"""
|
||||||
|
# GIVEN: Mocked out objects
|
||||||
|
with patch('openlp.core.common.os') as mocked_os, \
|
||||||
|
patch('openlp.core.common.sys') as mocked_sys, \
|
||||||
|
patch('openlp.core.common.distro_id') as mocked_distro_id:
|
||||||
|
|
||||||
|
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectively
|
||||||
|
# and the distro is Fedora
|
||||||
|
mocked_os.name = 'posix'
|
||||||
|
mocked_sys.platform = 'linux3'
|
||||||
|
mocked_distro_id.return_value = 'fedora'
|
||||||
|
|
||||||
|
# THEN: The three platform functions should perform properly
|
||||||
|
assert is_linux(distro='fedora') is True, 'is_linux(distro="fedora") should return True'
|
||||||
|
assert is_win() is False, 'is_win() should return False'
|
||||||
|
assert is_macosx() is False, 'is_macosx() should return False'
|
||||||
|
|
||||||
|
def test_is_64bit_instance(self):
|
||||||
|
"""
|
||||||
|
Test the is_64bit_instance() function
|
||||||
|
"""
|
||||||
|
# GIVEN: Mocked out objects
|
||||||
|
with patch('openlp.core.common.sys') as mocked_sys:
|
||||||
|
|
||||||
|
# WHEN: The mocked sys.maxsize is set to 32-bit
|
||||||
|
mocked_sys.maxsize = 2**32
|
||||||
|
|
||||||
|
# THEN: The result should be False
|
||||||
|
assert is_64bit_instance() is False, 'is_64bit_instance() should return False'
|
||||||
|
|
||||||
def test_normalize_str_leaves_newlines(self):
|
def test_normalize_str_leaves_newlines(self):
|
||||||
# GIVEN: a string containing newlines
|
# GIVEN: a string containing newlines
|
||||||
string = 'something\nelse'
|
string = 'something\nelse'
|
||||||
|
@ -35,8 +35,9 @@ class FakeIP4InterfaceEntry(QObject):
|
|||||||
"""
|
"""
|
||||||
Class to face an interface for testing purposes
|
Class to face an interface for testing purposes
|
||||||
"""
|
"""
|
||||||
def __init__(self, name='lo'):
|
def __init__(self, name='lo', is_valid=True):
|
||||||
self.my_name = name
|
self.my_name = name
|
||||||
|
self._is_valid = is_valid
|
||||||
if name in ['localhost', 'lo']:
|
if name in ['localhost', 'lo']:
|
||||||
self.my_ip = QNetworkAddressEntry()
|
self.my_ip = QNetworkAddressEntry()
|
||||||
self.my_ip.setBroadcast(QHostAddress('255.0.0.0'))
|
self.my_ip.setBroadcast(QHostAddress('255.0.0.0'))
|
||||||
@ -75,7 +76,7 @@ class FakeIP4InterfaceEntry(QObject):
|
|||||||
return self.my_name
|
return self.my_name
|
||||||
|
|
||||||
def isValid(self):
|
def isValid(self):
|
||||||
return True
|
return self._is_valid
|
||||||
|
|
||||||
|
|
||||||
class TestInterfaces(TestCase, TestMixin):
|
class TestInterfaces(TestCase, TestMixin):
|
||||||
@ -92,6 +93,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
self.fake_lo = FakeIP4InterfaceEntry()
|
self.fake_lo = FakeIP4InterfaceEntry()
|
||||||
self.fake_localhost = FakeIP4InterfaceEntry(name='localhost')
|
self.fake_localhost = FakeIP4InterfaceEntry(name='localhost')
|
||||||
self.fake_address = FakeIP4InterfaceEntry(name='eth25')
|
self.fake_address = FakeIP4InterfaceEntry(name='eth25')
|
||||||
|
self.invalid_if = FakeIP4InterfaceEntry(name='invalid', is_valid=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""
|
"""
|
||||||
@ -126,7 +128,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: lo")
|
call('Filtering out interfaces we don\'t care about: lo')
|
||||||
]
|
]
|
||||||
|
|
||||||
# WHEN: get_network_interfaces() is called
|
# WHEN: get_network_interfaces() is called
|
||||||
@ -146,7 +148,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: localhost")
|
call('Filtering out interfaces we don\'t care about: localhost')
|
||||||
]
|
]
|
||||||
|
|
||||||
# WHEN: get_network_interfaces() is called
|
# WHEN: get_network_interfaces() is called
|
||||||
@ -190,7 +192,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: lo"),
|
call('Filtering out interfaces we don\'t care about: lo'),
|
||||||
call('Checking for isValid and flags == IsUP | IsRunning'),
|
call('Checking for isValid and flags == IsUP | IsRunning'),
|
||||||
call('Checking address(es) protocol'),
|
call('Checking address(es) protocol'),
|
||||||
call('Checking for protocol == IPv4Protocol'),
|
call('Checking for protocol == IPv4Protocol'),
|
||||||
@ -205,4 +207,26 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
|
|
||||||
# THEN: There should be a fake 'eth25' interface
|
# THEN: There should be a fake 'eth25' interface
|
||||||
mock_log.debug.assert_has_calls(call_debug)
|
mock_log.debug.assert_has_calls(call_debug)
|
||||||
assert interfaces == self.fake_address.fake_data, "There should have been only 'eth25' interface listed"
|
assert interfaces == self.fake_address.fake_data, 'There should have been only "eth25" interface listed'
|
||||||
|
|
||||||
|
@patch.object(openlp.core.common, 'log')
|
||||||
|
def test_network_interfaces_invalid(self, mock_log):
|
||||||
|
"""
|
||||||
|
Test get_network_interfaces() returns an empty dictionary when there are no valid interfaces
|
||||||
|
"""
|
||||||
|
# GIVEN: Test environment
|
||||||
|
call_debug = [
|
||||||
|
call('Getting local IPv4 interface(es) information'),
|
||||||
|
call('Checking for isValid and flags == IsUP | IsRunning')
|
||||||
|
]
|
||||||
|
call_warning = [call('No active IPv4 network interfaces detected')]
|
||||||
|
|
||||||
|
# WHEN: get_network_interfaces() is called
|
||||||
|
with patch('openlp.core.common.QNetworkInterface') as mock_network_interface:
|
||||||
|
mock_network_interface.allInterfaces.return_value = [self.invalid_if]
|
||||||
|
interfaces = get_network_interfaces()
|
||||||
|
|
||||||
|
# THEN: There should be a fake 'eth25' interface
|
||||||
|
mock_log.debug.assert_has_calls(call_debug)
|
||||||
|
mock_log.warning.assert_has_calls(call_warning)
|
||||||
|
assert interfaces == {}, 'There should not be any interfaces listed'
|
||||||
|
Loading…
Reference in New Issue
Block a user