Ken Roberts has proposed merging lp:~alisonken1/openlp/pjlink2-t into lp:openlp.
Commit message: PJLink2-T Update (UDP updates and some cleanups) Having network issues - ci failed when running ci but passed when looked at branch webpage: -------------------------------------------------------------------------------- lp:~alisonken1/openlp/pjlink2-t (revision 2834) https://ci.openlp.io/job/Branch-01-Pull/2578/ [SUCCESS] https://ci.openlp.io/job/Branch-02a-Linux-Tests/2475/ [WAITING]Traceback (most recent call last): ... Exception: Build has not started yet, it may be stuck in the queue =============== Jenkins branch webpage: ------------------------------------------------------------------------------- Success Branch-01-Pull (#2578) Success Branch-02a-Linux-Tests (#2475) Failed Branch-02b-macOS-Tests (#249) Success Branch-03a-Build-Source (#162) Success Branch-03b-Build-macOS (#141) Success Branch-04a-Code-Analysis (#1624) Success Branch-04b-Test-Coverage (#1437) Success Branch-04c-Lint-Check (#567) Failed Branch-05-AppVeyor-Tests (#336) Failed Branch-06-Build_API_Docs (#486) Requested reviews: OpenLP Core (openlp-core) For more details, see: https://code.launchpad.net/~alisonken1/openlp/pjlink2-t/+merge/356677 - Move tests/functional/openlp_core/common/test_networkinterfaces.py to tests/openlp_core/common - Minor cleanups in openlp.core.common.__init__.get_local_ip4() - Add more get_local_ip4 tests - Fix some oops in ProjectorManager when add/edit projector entry - Update tests/openlp_core/projectors/test_projector_pjlink_udp.py with correct log entries - Add UDP 'projector/udp broadcast listen' status in Settings() (default=False) - Add UDP broadcast listen option in projector settings tab - Add check_settings(), udp_start(), and udp_stop(), udp_add(), udp_delete() methods in PJLinkUDP - Add Registry().register_function('udp_broadcast_listen') call for UDP settings update - Add udp_listen_add(), udp_listen_delete() methods to ProjectorManager - pep8 cleanup in tests/functional/openlp_core/common/test_i18n.py - pep8 cleanup in openlp/core/lib/__init__.py -- Your team OpenLP Core is requested to review the proposed merge of lp:~alisonken1/openlp/pjlink2-t into lp:openlp.
=== modified file 'openlp/core/common/__init__.py' --- openlp/core/common/__init__.py 2018-08-03 22:32:32 +0000 +++ openlp/core/common/__init__.py 2018-10-13 12:21:32 +0000 @@ -60,7 +60,6 @@ :returns: Dict of interfaces """ - # Get the local IPv4 active address(es) that are NOT localhost (lo or '127.0.0.1') log.debug('Getting local IPv4 interface(es) information') my_ip4 = {} for iface in QNetworkInterface.allInterfaces(): @@ -70,8 +69,6 @@ log.debug('Checking address(es) protocol') for address in iface.addressEntries(): ip = address.ip() - # NOTE: Next line will skip if interface is localhost - keep for now until we decide about it later - # if (ip.protocol() == QAbstractSocket.IPv4Protocol) and (ip != QHostAddress.LocalHost): log.debug('Checking for protocol == IPv4Protocol') if ip.protocol() == QAbstractSocket.IPv4Protocol: log.debug('Getting interface information') @@ -83,12 +80,13 @@ ip.toIPv4Address()).toString() } log.debug('Adding {iface} to active list'.format(iface=iface.name())) + if len(my_ip4) == 0: + log.warning('No active IPv4 network interfaces detected') + return my_ip4 if 'localhost' in my_ip4: log.debug('Renaming windows localhost to lo') my_ip4['lo'] = my_ip4['localhost'] my_ip4.pop('localhost') - if len(my_ip4) == 0: - log.warning('No active IPv4 network interfaces detected') if len(my_ip4) == 1: if 'lo' in my_ip4: # No active interfaces - so leave localhost in there === modified file 'openlp/core/common/settings.py' --- openlp/core/common/settings.py 2018-06-07 17:44:35 +0000 +++ openlp/core/common/settings.py 2018-10-13 12:21:32 +0000 @@ -217,7 +217,8 @@ 'projector/last directory export': None, 'projector/poll time': 20, # PJLink timeout is 30 seconds 'projector/socket timeout': 5, # 5 second socket timeout - 'projector/source dialog type': 0 # Source select dialog box type + 'projector/source dialog type': 0, # Source select dialog box type + 'projector/udp broadcast listen': False # Enable/disable listening for PJLink 2 UDP broadcast packets } __file_path__ = '' # Settings upgrades prior to 3.0 === modified file 'openlp/core/lib/__init__.py' --- openlp/core/lib/__init__.py 2018-08-25 14:08:19 +0000 +++ openlp/core/lib/__init__.py 2018-10-13 12:21:32 +0000 @@ -609,4 +609,4 @@ last=string_list[-1]) else: list_to_string = '' - return list_to_string \ No newline at end of file + return list_to_string === modified file 'openlp/core/projectors/editform.py' --- openlp/core/projectors/editform.py 2018-04-21 19:57:51 +0000 +++ openlp/core/projectors/editform.py 2018-10-13 12:21:32 +0000 @@ -179,6 +179,7 @@ Validate input before accepting input. """ log.debug('accept_me() signal received') + valid = True if len(self.name_text.text().strip()) < 1: QtWidgets.QMessageBox.warning(self, translate('OpenLP.ProjectorEdit', 'Name Not Set'), === modified file 'openlp/core/projectors/manager.py' --- openlp/core/projectors/manager.py 2018-06-28 20:40:54 +0000 +++ openlp/core/projectors/manager.py 2018-10-13 12:21:32 +0000 @@ -38,7 +38,7 @@ from openlp.core.projectors import DialogSourceStyle from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, \ E_SOCKET_TIMEOUT, E_UNKNOWN_SOCKET_ERROR, S_CONNECTED, S_CONNECTING, S_COOLDOWN, S_INITIALIZE, \ - S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP, PJLINK_PORT, STATUS_CODE, STATUS_MSG, QSOCKET_STATE + S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP, STATUS_CODE, STATUS_MSG, QSOCKET_STATE from openlp.core.projectors.db import ProjectorDB from openlp.core.projectors.editform import ProjectorEditForm @@ -335,10 +335,6 @@ """ Post-initialize setups. """ - # Default PJLink port UDP socket - log.debug('Creating PJLinkUDP listener for default port {port}'.format(port=PJLINK_PORT)) - self.pjlink_udp = {PJLINK_PORT: PJLinkUDP(port=PJLINK_PORT)} - self.pjlink_udp[PJLINK_PORT].bind(PJLINK_PORT) # Set 1.5 second delay before loading all projectors if self.autostart: log.debug('Delaying 1.5 seconds before loading all projectors') @@ -351,6 +347,36 @@ self.projector_form.editProjector.connect(self.edit_projector_from_wizard) self.projector_list_widget.itemSelectionChanged.connect(self.update_icons) + def udp_listen_add(self, port): + """ + Add UDP broadcast listener + """ + if port in self.pjlink_udp: + log.warning('UDP Listener for port {port} already added - skipping'.format(port=port)) + else: + log.debug('Adding UDP listener on port {port}'.format(port=port)) + self.pjlink_udp[port] = PJLinkUDP(port=port) + self.pjlink_udp[port].udp_add() + + def udp_listen_delete(self, port): + """ + Remove a UDP broadcast listener + """ + log.debug('Checking for UDP port {port} listener deletion'.format(port=port)) + if port not in self.pjlink_udp: + log.warn('UDP listener for port {port} not there - skipping delete'.format(port=port)) + return + keep_port = False + for item in self.projector_list: + if port == item.link.port: + keep_port = True + if keep_port: + log.warn('UDP listener for port {port} needed for other projectors - skipping delete'.format(port=port)) + return + self.pjlink_udp[port].udp_delete() + del self.pjlink_udp[port] + log.debug('UDP listener for port {port} deleted'.format(port=port)) + def get_settings(self): """ Retrieve the saved settings @@ -518,25 +544,22 @@ except (AttributeError, TypeError): pass try: - projector.poll_timer.stop() - projector.poll_timer.timeout.disconnect(projector.link.poll_loop) - except (AttributeError, TypeError): - pass - try: - projector.socket_timer.stop() - projector.socket_timer.timeout.disconnect(projector.link.socket_abort) - except (AttributeError, TypeError): - pass - # Disconnect signals from projector being deleted - try: - self.pjlink_udp[projector.link.port].data_received.disconnect(projector.link.get_buffer) + projector.link.poll_timer.stop() + projector.link.poll_timer.timeout.disconnect(projector.link.poll_loop) + except (AttributeError, TypeError): + pass + try: + projector.link.socket_timer.stop() + projector.link.socket_timer.timeout.disconnect(projector.link.socket_abort) except (AttributeError, TypeError): pass + old_port = projector.link.port # Rebuild projector list new_list = [] for item in self.projector_list: if item.link.db_item.id == projector.link.db_item.id: + log.debug('Removing projector "{item}"'.format(item=item.link.name)) continue new_list.append(item) self.projector_list = new_list @@ -546,6 +569,7 @@ log.warning('Delete projector {item} failed'.format(item=projector.db_item)) for item in self.projector_list: log.debug('New projector list - item: {ip} {name}'.format(ip=item.link.ip, name=item.link.name)) + self.udp_listen_delete(old_port) def on_disconnect_projector(self, opt=None): """ @@ -748,15 +772,8 @@ item.link.projectorAuthentication.connect(self.authentication_error) item.link.projectorNoAuthentication.connect(self.no_authentication_error) item.link.projectorUpdateIcons.connect(self.update_icons) - # Connect UDP signal to projector instances with same port - if item.link.port not in self.pjlink_udp: - log.debug('Adding new PJLinkUDP listener fo port {port}'.format(port=item.link.port)) - self.pjlink_udp[item.link.port] = PJLinkUDP(port=item.link.port) - self.pjlink_udp[item.link.port].bind(item.link.port) - log.debug('Connecting PJLinkUDP port {port} signal to "{item}"'.format(port=item.link.port, - item=item.link.name)) - self.pjlink_udp[item.link.port].data_received.connect(item.link.get_buffer) - + # Add UDP listener for new projector port + self.udp_listen_add(item.link.port) self.projector_list.append(item) if start: item.link.connect_to_host() @@ -783,13 +800,25 @@ :param projector: Projector() instance of projector with updated information """ log.debug('edit_projector_from_wizard(ip={ip})'.format(ip=projector.ip)) + old_port = self.old_projector.link.port + old_ip = self.old_projector.link.ip self.old_projector.link.name = projector.name self.old_projector.link.ip = projector.ip self.old_projector.link.pin = None if projector.pin == '' else projector.pin - self.old_projector.link.port = projector.port self.old_projector.link.location = projector.location self.old_projector.link.notes = projector.notes self.old_projector.widget.setText(projector.name) + self.old_projector.link.port = int(projector.port) + # Update projector list items + for item in self.projector_list: + if item.link.ip == old_ip: + item.link.port = int(projector.port) + # NOTE: This assumes (!) we are using IP addresses as keys + break + # Update UDP listeners before setting old_projector.port + if old_port != projector.port: + self.udp_listen_delete(old_port) + self.udp_listen_add(int(projector.port)) def _load_projectors(self): """' === modified file 'openlp/core/projectors/pjlink.py' --- openlp/core/projectors/pjlink.py 2018-07-02 20:38:47 +0000 +++ openlp/core/projectors/pjlink.py 2018-10-13 12:21:32 +0000 @@ -54,6 +54,7 @@ from openlp.core.common import qmd5_hash from openlp.core.common.i18n import translate +from openlp.core.common.registry import Registry from openlp.core.common.settings import Settings from openlp.core.projectors.constants import CONNECTION_ERRORS, PJLINK_CLASS, PJLINK_DEFAULT_CODES, PJLINK_ERRORS, \ PJLINK_ERST_DATA, PJLINK_ERST_STATUS, PJLINK_MAX_PACKET, PJLINK_PREFIX, PJLINK_PORT, PJLINK_POWR_STATUS, \ @@ -98,32 +99,65 @@ self.search_active = False self.search_time = 30000 # 30 seconds for allowed time self.search_timer = QtCore.QTimer() + self.udp_broadcast_listen_setting = False + log.debug('(UDP:{port}) PJLinkUDP() Initialized'.format(port=self.port)) + + def udp_add(self): + """ + Setup for new UDP listener + """ + log.debug('(UDP:{port}) Adding Registry() entry'.format(port=self.port)) + Registry().register_function('udp_broadcast_listen', self.check_settings) + self.udp_start() + + def udp_delete(self): + """ + Teardown for UDP listener + """ + self.udp_stop() + log.debug('(UDP:{port}) Removing Registry() entry'.format(port=self.port)) + Registry().remove_function('udp_broadcast_listen', self.check_settings) + + def udp_start(self): + """ + Start listening on UDP port + """ + log.debug('(UDP:{port}) Start called'.format(port=self.port)) self.readyRead.connect(self.get_datagram) - log.debug('(UDP) PJLinkUDP() Initialized for port {port}'.format(port=self.port)) + self.check_settings(checked=Settings().value('projector/udp broadcast listen')) + + def udp_stop(self): + """ + Stop listening on UDP port + """ + log.debug('(UDP:{port}) Stopping listener'.format(port=self.port)) + self.close() + self.readyRead.disconnect(self.get_datagram) @QtCore.pyqtSlot() def get_datagram(self): """ Retrieve packet and basic checks """ - log.debug('(UDP) get_datagram() - Receiving data') + log.debug('(UDP:{port}) get_datagram() - Receiving data'.format(port=self.port)) read_size = self.pendingDatagramSize() if -1 == read_size: - log.warning('(UDP) No data (-1)') + log.warning('(UDP:{port}) No data (-1)'.format(port=self.port)) return elif 0 == read_size: - log.warning('(UDP) get_datagram() called when pending data size is 0') + log.warning('(UDP:{port}) get_datagram() called when pending data size is 0'.format(port=self.port)) return elif read_size > PJLINK_MAX_PACKET: - log.warning('(UDP) UDP Packet too large ({size} bytes)- ignoring'.format(size=read_size)) + log.warning('(UDP:{port}) UDP Packet too large ({size} bytes)- ignoring'.format(size=read_size, + port=self.port)) return data_in, peer_host, peer_port = self.readDatagram(read_size) data = data_in.decode('utf-8') if isinstance(data_in, bytes) else data_in - log.debug('(UDP) {size} bytes received from {adx} on port {port}'.format(size=len(data), - adx=peer_host.toString(), - port=self.port)) - log.debug('(UDP) packet "{data}"'.format(data=data)) - log.debug('(UDP) Sending data_received signal to projectors') + log.debug('(UDP:{port}) {size} bytes received from {adx}'.format(size=len(data), + adx=peer_host.toString(), + port=self.port)) + log.debug('(UDP:{port}) packet "{data}"'.format(data=data, port=self.port)) + log.debug('(UDP:{port}) Sending data_received signal to projectors'.format(port=self.port)) self.data_received.emit(peer_host, self.localPort(), data) return @@ -143,6 +177,24 @@ self.search_active = False self.search_timer.stop() + def check_settings(self, checked): + """ + Update UDP listening state based on settings change + """ + if self.udp_broadcast_listen_setting == checked: + log.debug('(UDP:{port}) No change to status - skipping'.format(port=self.port)) + return + self.udp_broadcast_listen_setting = checked + if self.udp_broadcast_listen_setting: + if self.state() == self.ListeningState: + log.debug('(UDP:{port}) Already listening - skipping') + return + self.bind(self.port) + log.debug('(UDP:{port}) Listening'.format(port=self.port)) + else: + # Close socket + self.udp_stop() + class PJLinkCommands(object): """ === modified file 'openlp/core/projectors/tab.py' --- openlp/core/projectors/tab.py 2018-08-25 14:08:19 +0000 +++ openlp/core/projectors/tab.py 2018-10-13 12:21:32 +0000 @@ -27,6 +27,7 @@ from PyQt5 import QtWidgets from openlp.core.common.i18n import UiStrings, translate +from openlp.core.common.registry import Registry from openlp.core.common.settings import Settings from openlp.core.lib.settingstab import SettingsTab from openlp.core.ui.icons import UiIcons @@ -49,6 +50,8 @@ self.icon_path = UiIcons().projector projector_translated = translate('OpenLP.ProjectorTab', 'Projector') super(ProjectorTab, self).__init__(parent, 'Projector', projector_translated) + # So we don't get tracebacks in the log when there are no UDP listeners registered + Registry().register_function('udp_broadcast_listen', self.ping) def setupUi(self): """ @@ -90,6 +93,10 @@ self.connect_box_layout.addRow(self.dialog_type_label, self.dialog_type_combo_box) self.left_layout.addStretch() self.dialog_type_combo_box.activated.connect(self.on_dialog_type_combo_box_changed) + # Enable/disable listening on UDP ports for PJLink2 broadcasts + self.udp_broadcast_listen = QtWidgets.QCheckBox(self.connect_box) + self.udp_broadcast_listen.setObjectName('udp_broadcast_listen') + self.connect_box_layout.addRow(self.udp_broadcast_listen) # Connect on LKUP packet received (PJLink v2+ only) self.connect_on_linkup = QtWidgets.QCheckBox(self.connect_box) self.connect_on_linkup.setObjectName('connect_on_linkup') @@ -116,6 +123,8 @@ translate('OpenLP.ProjectorTab', 'Single dialog box')) self.connect_on_linkup.setText( translate('OpenLP.ProjectorTab', 'Connect to projector when LINKUP received (v2 only)')) + self.udp_broadcast_listen.setText( + translate('OpenLP.ProjectorTab', 'Enable listening for PJLink2 broadcast messages')) def load(self): """ @@ -125,6 +134,7 @@ self.socket_timeout_spin_box.setValue(Settings().value('projector/socket timeout')) self.socket_poll_spin_box.setValue(Settings().value('projector/poll time')) self.dialog_type_combo_box.setCurrentIndex(Settings().value('projector/source dialog type')) + self.udp_broadcast_listen.setChecked(Settings().value('projector/udp broadcast listen')) self.connect_on_linkup.setChecked(Settings().value('projector/connect when LKUP received')) def save(self): @@ -136,6 +146,14 @@ Settings().setValue('projector/poll time', self.socket_poll_spin_box.value()) Settings().setValue('projector/source dialog type', self.dialog_type_combo_box.currentIndex()) Settings().setValue('projector/connect when LKUP received', self.connect_on_linkup.isChecked()) + Settings().setValue('projector/udp broadcast listen', self.udp_broadcast_listen.isChecked()) + Registry().execute('udp_broadcast_listen', self.udp_broadcast_listen.isChecked()) def on_dialog_type_combo_box_changed(self): self.dialog_type = self.dialog_type_combo_box.currentIndex() + + def ping(self, checked): + """ + Placeholder function so we don't get tracebacks when there are no UDP listeners + """ + log.debug('UDP setting change callback - checked={chk}'.format(chk=checked)) === modified file 'tests/functional/openlp_core/common/test_i18n.py' --- tests/functional/openlp_core/common/test_i18n.py 2018-08-27 14:16:26 +0000 +++ tests/functional/openlp_core/common/test_i18n.py 2018-10-13 12:21:32 +0000 @@ -162,6 +162,7 @@ def test_get_language_from_settings(): assert LanguageManager.get_language() == 'en' + def test_get_language_from_settings_returns_unchanged_if_unknown_format(): Settings().setValue('core/language', '(foobar)') assert LanguageManager.get_language() == '(foobar)' === added directory 'tests/openlp_core/common' === renamed file 'tests/functional/openlp_core/common/test_network_interfaces.py' => 'tests/openlp_core/common/test_network_interfaces.py' --- tests/functional/openlp_core/common/test_network_interfaces.py 2018-08-03 22:32:32 +0000 +++ tests/openlp_core/common/test_network_interfaces.py 2018-10-13 12:21:32 +0000 @@ -23,21 +23,61 @@ Functional tests to test calls for network interfaces. """ from unittest import TestCase -from unittest.mock import MagicMock, call, patch +from unittest.mock import call, patch +from PyQt5.QtCore import QObject +from PyQt5.QtNetwork import QHostAddress, QNetworkAddressEntry, QNetworkInterface import openlp.core.common from openlp.core.common import get_local_ip4 from tests.helpers.testmixin import TestMixin -lo_address_attrs = {'isValid.return_value': True, - 'flags.return_value': True, - 'InterfaceFlags.return_value': True, - 'name.return_value': 'lo', - 'broadcast.toString.return_value': '127.0.0.255', - 'netmask.toString.return_value': '255.0.0.0', - 'prefixLength.return_value': 8, - 'ip.protocol.return_value': True} + +class FakeIP4InterfaceEntry(QObject): + """ + Class to face an interface for testing purposes + """ + def __init__(self, name='lo'): + self.my_name = name + if name in ['localhost', 'lo']: + self.my_ip = QNetworkAddressEntry() + self.my_ip.setBroadcast(QHostAddress('255.0.0.0')) + self.my_ip.setIp(QHostAddress('127.0.0.2')) + self.my_ip.setPrefixLength(8) + self.fake_data = {'lo': {'ip': '127.0.0.2', + 'broadcast': '255.0.0.0', + 'netmask': '255.0.0.0', + 'prefix': 8, + 'localnet': '127.0.0.0'}} + else: + # Define a fake real address + self.my_ip = QNetworkAddressEntry() + self.my_ip.setBroadcast(QHostAddress('255.255.255.0')) + self.my_ip.setIp(QHostAddress('127.254.0.2')) + self.my_ip.setPrefixLength(24) + self.fake_data = {self.my_name: {'ip': '127.254.0.2', + 'broadcast': '255.255.255.0', + 'netmask': '255.255.255.0', + 'prefix': 24, + 'localnet': '127.254.0.0'}} + + def addressEntries(self): + """ + Return fake IP address + """ + return [self.my_ip] + + def flags(self): + """ + Return a QFlags enum with IsUp and IsRunning + """ + return (QNetworkInterface.IsUp | QNetworkInterface.IsRunning) + + def name(self): + return self.my_name + + def isValid(self): + return True class TestInterfaces(TestCase, TestMixin): @@ -49,9 +89,11 @@ Create an instance and a few example actions. """ self.build_settings() - - self.ip4_lo_address = MagicMock() - self.ip4_lo_address.configure_mock(**lo_address_attrs) + if not hasattr(self, 'fake_lo'): + # Since these shouldn't change, only need to instantiate them the first time + self.fake_lo = FakeIP4InterfaceEntry() + self.fake_localhost = FakeIP4InterfaceEntry(name='localhost') + self.fake_address = FakeIP4InterfaceEntry(name='eth25') def tearDown(self): """ @@ -65,14 +107,118 @@ Test no interfaces available """ # GIVEN: Test environment + call_debug = [call('Getting local IPv4 interface(es) information')] call_warning = [call('No active IPv4 network interfaces detected')] - with patch('openlp.core.common.QNetworkInterface') as mock_newtork_interface: - mock_newtork_interface.allInterfaces.return_value = [] - - # WHEN: get_local_ip4 is called - ifaces = get_local_ip4() - - # THEN: There should not be any interfaces detected - assert not ifaces, 'There should have been no active interfaces' - mock_log.warning.assert_has_calls(call_warning) + # WHEN: get_local_ip4 is called + with patch('openlp.core.common.QNetworkInterface') as mock_network_interface: + mock_network_interface.allInterfaces.return_value = [] + ifaces = get_local_ip4() + + # THEN: There should not be any interfaces detected + mock_log.debug.assert_has_calls(call_debug) + mock_log.warning.assert_has_calls(call_warning) + assert not ifaces, 'There should have been no active interfaces listed' + + @patch.object(openlp.core.common, 'log') + def test_ip4_lo(self, mock_log): + """ + Test get_local_ip4 returns proper dictionary with 'lo' + """ + # GIVEN: Test environment + call_debug = [call('Getting local IPv4 interface(es) information'), + call('Checking for isValid and flags == IsUP | IsRunning'), + call('Checking address(es) protocol'), + call('Checking for protocol == IPv4Protocol'), + call('Getting interface information'), + call('Adding lo to active list')] + call_warning = [call('No active IPv4 interfaces found except localhost')] + + # WHEN: get_local_ip4 is called + with patch('openlp.core.common.QNetworkInterface') as mock_network_interface: + mock_network_interface.allInterfaces.return_value = [self.fake_lo] + ifaces = get_local_ip4() + + # THEN: There should be a fake 'lo' interface + mock_log.debug.assert_has_calls(call_debug) + mock_log.warning.assert_has_calls(call_warning) + assert ifaces == self.fake_lo.fake_data, "There should have been an 'lo' interface listed" + + @patch.object(openlp.core.common, 'log') + def test_ip4_localhost(self, mock_log): + """ + Test get_local_ip4 returns proper dictionary with 'lo' if interface is 'localhost' + """ + # GIVEN: Test environment + call_debug = [call('Getting local IPv4 interface(es) information'), + call('Checking for isValid and flags == IsUP | IsRunning'), + call('Checking address(es) protocol'), + call('Checking for protocol == IPv4Protocol'), + call('Getting interface information'), + call('Adding localhost to active list'), + call('Renaming windows localhost to lo')] + call_warning = [call('No active IPv4 interfaces found except localhost')] + + # WHEN: get_local_ip4 is called + with patch('openlp.core.common.QNetworkInterface') as mock_network_interface: + mock_network_interface.allInterfaces.return_value = [self.fake_localhost] + ifaces = get_local_ip4() + + # THEN: There should be a fake 'lo' interface + mock_log.debug.assert_has_calls(call_debug) + mock_log.warning.assert_has_calls(call_warning) + assert ifaces == self.fake_lo.fake_data, "There should have been an 'lo' interface listed" + + @patch.object(openlp.core.common, 'log') + def test_ip4_eth25(self, mock_log): + """ + Test get_local_ip4 returns proper dictionary with 'eth25' + """ + # GIVEN: Test environment + call_debug = [call('Getting local IPv4 interface(es) information'), + call('Checking for isValid and flags == IsUP | IsRunning'), + call('Checking address(es) protocol'), + call('Checking for protocol == IPv4Protocol'), + call('Getting interface information'), + call('Adding eth25 to active list')] + call_warning = [] + + # WHEN: get_local_ip4 is called + with patch('openlp.core.common.QNetworkInterface') as mock_network_interface: + mock_network_interface.allInterfaces.return_value = [self.fake_address] + ifaces = get_local_ip4() + + # 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 ifaces == self.fake_address.fake_data + + @patch.object(openlp.core.common, 'log') + def test_ip4_lo_eth25(self, mock_log): + """ + Test get_local_ip4 returns proper dictionary with 'eth25' + """ + # GIVEN: Test environment + call_debug = [call('Getting local IPv4 interface(es) information'), + call('Checking for isValid and flags == IsUP | IsRunning'), + call('Checking address(es) protocol'), + call('Checking for protocol == IPv4Protocol'), + call('Getting interface information'), + call('Adding lo to active list'), + call('Checking for isValid and flags == IsUP | IsRunning'), + call('Checking address(es) protocol'), + call('Checking for protocol == IPv4Protocol'), + call('Getting interface information'), + call('Adding eth25 to active list'), + call('Found at least one IPv4 interface, removing localhost')] + call_warning = [] + + # WHEN: get_local_ip4 is called + with patch('openlp.core.common.QNetworkInterface') as mock_network_interface: + mock_network_interface.allInterfaces.return_value = [self.fake_lo, self.fake_address] + ifaces = get_local_ip4() + + # 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 ifaces == self.fake_address.fake_data, "There should have been only 'eth25' interface listed" === modified file 'tests/openlp_core/projectors/__init__.py' --- tests/openlp_core/projectors/__init__.py 2018-02-11 11:42:13 +0000 +++ tests/openlp_core/projectors/__init__.py 2018-10-13 12:21:32 +0000 @@ -4,7 +4,7 @@ ############################################################################### # OpenLP - Open Source Lyrics Projection # # --------------------------------------------------------------------------- # -# Copyright (c) 2008-2017 OpenLP Developers # +# Copyright (c) 2008-2018 OpenLP Developers # # --------------------------------------------------------------------------- # # This program is free software; you can redistribute it and/or modify it # # under the terms of the GNU General Public License as published by the Free # @@ -20,5 +20,5 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -Module-level functions for the projector test suite +:mod tests/openlp_core/projectors: Tests for projector code """ === modified file 'tests/openlp_core/projectors/test_projector_pjlink_udp.py' --- tests/openlp_core/projectors/test_projector_pjlink_udp.py 2018-05-03 14:58:50 +0000 +++ tests/openlp_core/projectors/test_projector_pjlink_udp.py 2018-10-13 12:21:32 +0000 @@ -45,9 +45,9 @@ """ # GIVEN: Test setup pjlink_udp = PJLinkUDP() - log_warning_calls = [call('(UDP) No data (-1)')] - log_debug_calls = [call('(UDP) PJLinkUDP() Initialized for port 4352'), - call('(UDP) get_datagram() - Receiving data')] + log_warning_calls = [call('(UDP:4352) No data (-1)')] + log_debug_calls = [call('(UDP:4352) PJLinkUDP() Initialized'), + call('(UDP:4352) get_datagram() - Receiving data')] with patch.object(pjlink_udp, 'pendingDatagramSize') as mock_datagram, \ patch.object(pjlink_udp, 'readDatagram') as mock_read: mock_datagram.return_value = -1 @@ -67,9 +67,9 @@ """ # GIVEN: Test setup pjlink_udp = PJLinkUDP() - log_warning_calls = [call('(UDP) get_datagram() called when pending data size is 0')] - log_debug_calls = [call('(UDP) PJLinkUDP() Initialized for port 4352'), - call('(UDP) get_datagram() - Receiving data')] + log_warning_calls = [call('(UDP:4352) get_datagram() called when pending data size is 0')] + log_debug_calls = [call('(UDP:4352) PJLinkUDP() Initialized'), + call('(UDP:4352) get_datagram() - Receiving data')] with patch.object(pjlink_udp, 'pendingDatagramSize') as mock_datagram, \ patch.object(pjlink_udp, 'readDatagram') as mock_read: mock_datagram.return_value = 0 @@ -89,9 +89,9 @@ """ # GIVEN: Test setup pjlink_udp = PJLinkUDP() - log_warning_calls = [call('(UDP) get_datagram() called when pending data size is 0')] - log_debug_calls = [call('(UDP) PJLinkUDP() Initialized for port 4352'), - call('(UDP) get_datagram() - Receiving data')] + log_warning_calls = [call('(UDP:4352) get_datagram() called when pending data size is 0')] + log_debug_calls = [call('(UDP:4352) PJLinkUDP() Initialized'), + call('(UDP:4352) get_datagram() - Receiving data')] with patch.object(pjlink_udp, 'pendingDatagramSize') as mock_datagram: mock_datagram.return_value = 0
_______________________________________________ Mailing list: https://launchpad.net/~openlp-core Post to : openlp-core@lists.launchpad.net Unsubscribe : https://launchpad.net/~openlp-core More help : https://help.launchpad.net/ListHelp