# python-cc1101 - Python Library to Transmit RF Signals via CC1101 Transceivers # # Copyright (C) 2020 Fabian Peter Hammerle # # 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 Software Foundation, either version 3 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import io import logging import unittest.mock import pytest import cc1101._cli from cc1101.options import PacketLengthMode, SyncMode # pylint: disable=protected-access,too-many-positional-arguments @pytest.mark.parametrize( ( "args", "base_frequency_hertz", "symbol_rate_baud", "sync_mode", "packet_length_mode", "checksum_disabled", ), ( ([""], None, None, None, None, False), (["", "-f", "433920000"], 433920000, None, None, None, False), ( ["", "--base-frequency-hertz", "868000000"], 868000000, None, None, None, False, ), (["", "-r", "10000"], None, 10000, None, None, False), (["", "--symbol-rate-baud", "12345"], None, 12345, None, None, False), ( ["", "-s", "no-preamble-and-sync-word"], None, None, SyncMode.NO_PREAMBLE_AND_SYNC_WORD, None, False, ), ( ["", "--sync-mode", "no-preamble-and-sync-word"], None, None, SyncMode.NO_PREAMBLE_AND_SYNC_WORD, None, False, ), ( ["", "--sync-mode", "transmit-16-match-15-bits"], None, None, SyncMode.TRANSMIT_16_MATCH_15_BITS, None, False, ), (["", "-l", "fixed"], None, None, None, PacketLengthMode.FIXED, False), ( ["", "--packet-length-mode", "fixed"], None, None, None, PacketLengthMode.FIXED, False, ), ( ["", "--packet-length-mode", "variable"], None, None, None, PacketLengthMode.VARIABLE, False, ), (["", "--disable-checksum"], None, None, None, None, True), ), ) @pytest.mark.parametrize("payload", (b"", b"message")) def test_configure_device( args, base_frequency_hertz, symbol_rate_baud, sync_mode, packet_length_mode, checksum_disabled, payload, ): # pylint: disable=too-many-arguments with unittest.mock.patch("cc1101.CC1101") as transceiver_class_mock: stdin_mock = unittest.mock.MagicMock() stdin_mock.buffer = io.BytesIO(payload) with unittest.mock.patch("sys.stdin", stdin_mock): with unittest.mock.patch("sys.argv", args): cc1101._cli._transmit() transceiver_class_mock.assert_called_once_with(lock_spi_device=True) with transceiver_class_mock() as transceiver_mock: pass if base_frequency_hertz is None: transceiver_mock.set_base_frequency_hertz.assert_not_called() else: transceiver_mock.set_base_frequency_hertz.assert_called_once_with( base_frequency_hertz ) if symbol_rate_baud is None: transceiver_mock.set_symbol_rate_baud.assert_not_called() else: transceiver_mock.set_symbol_rate_baud.assert_called_once_with(symbol_rate_baud) if sync_mode is None: transceiver_mock.set_sync_mode.assert_not_called() else: transceiver_mock.set_sync_mode.assert_called_once_with(sync_mode) if packet_length_mode is None: # pylint: disable=duplicate-code transceiver_mock.set_packet_length_mode.assert_not_called() else: transceiver_mock.set_packet_length_mode.assert_called_once_with( packet_length_mode ) if packet_length_mode == PacketLengthMode.FIXED: transceiver_mock.set_packet_length_bytes.assert_called_with(len(payload)) else: transceiver_mock.set_packet_length_bytes.assert_not_called() if checksum_disabled: transceiver_mock.disable_checksum.assert_called_once_with() else: transceiver_mock.disable_checksum.assert_not_called() @pytest.mark.parametrize( ("args", "output_power_settings"), ( ([""], None), (["", "-p", "198"], [198]), # default (["", "--output-power", "198"], [198]), (["", "-p", "0", "198"], [0, 198]), # OOK ( ["", "-p", "18", "14", "29", "52", "96", "132", "200", "192"], [18, 14, 29, 52, 96, 132, 200, 192], ), ), ) def test_configure_device_output_power(args, output_power_settings): with unittest.mock.patch("cc1101.CC1101") as transceiver_class_mock: stdin_mock = unittest.mock.MagicMock() stdin_mock.buffer = io.BytesIO(b"message") with unittest.mock.patch("sys.stdin", stdin_mock): with unittest.mock.patch("sys.argv", args): cc1101._cli._transmit() transceiver_class_mock.assert_called_once_with(lock_spi_device=True) with transceiver_class_mock() as transceiver_mock: pass if output_power_settings: transceiver_mock.set_output_power.assert_called_with(output_power_settings) else: transceiver_mock.set_output_power.assert_not_called() @pytest.mark.parametrize( ("args", "root_log_level", "log_format"), ( ([""], logging.INFO, "%(message)s"), ( ["", "--debug"], logging.DEBUG, "%(asctime)s:%(levelname)s:%(name)s:%(funcName)s:%(message)s", ), ), ) def test_root_log_level(args, root_log_level, log_format): stdin_mock = unittest.mock.MagicMock() stdin_mock.buffer = io.BytesIO(b"") with unittest.mock.patch("cc1101.CC1101"), unittest.mock.patch( "sys.stdin", stdin_mock ), unittest.mock.patch("sys.argv", args), unittest.mock.patch( "logging.basicConfig" ) as logging_basic_config_mock: cc1101._cli._transmit() logging_basic_config_mock.assert_called_once() assert logging_basic_config_mock.call_args[1]["level"] == root_log_level assert logging_basic_config_mock.call_args[1]["format"] == log_format @pytest.mark.parametrize("payload", (b"", b"message")) def test_logging(caplog, payload): # pylint: disable=too-many-arguments stdin_mock = unittest.mock.MagicMock() stdin_mock.buffer = io.BytesIO(payload) with unittest.mock.patch("sys.stdin", stdin_mock), unittest.mock.patch( "sys.argv", [""] ), unittest.mock.patch("cc1101.CC1101") as transceiver_class_mock, caplog.at_level( logging.DEBUG ): with transceiver_class_mock() as transceiver_mock: transceiver_mock.__str__.return_value = "dummy" cc1101._cli._transmit() assert len(caplog.records) == 2 assert caplog.records[0].name == "cc1101._cli" assert caplog.records[0].levelno == logging.DEBUG assert caplog.records[0].message.startswith( "args=Namespace(base_frequency_hertz=None, " ) assert caplog.record_tuples[1] == ("cc1101._cli", logging.INFO, "dummy")