From 8242f61309944ed55ac3fd17bdf31b724fff5620 Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 08:33:10 -0400 Subject: [PATCH 1/8] Add FRAME_TYPE enum to static (#216) * Add FRAME_TYPE enum to static * Add SESSION_ to three values. --- tnc/static.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tnc/static.py b/tnc/static.py index a974afa1..a41c978e 100644 --- a/tnc/static.py +++ b/tnc/static.py @@ -9,6 +9,7 @@ Not nice, suggestions are appreciated :-) """ import subprocess +from enum import Enum VERSION = "0.4.2-alpha" @@ -123,3 +124,43 @@ INFO: list = [] # ------- CODEC2 SETTINGS TUNING_RANGE_FMIN: float = -50.0 TUNING_RANGE_FMAX: float = 50.0 + + +class FRAME_TYPE(Enum): + """Lookup for frame types""" + + BURST_01 = 10 + BURST_02 = 11 + BURST_03 = 12 + BURST_04 = 13 + BURST_05 = 14 + BURST_06 = 15 + BURST_07 = 16 + BURST_08 = 17 + BURST_09 = 18 + BURST_10 = 19 + BURST_11 = 20 + BURST_12 = 21 + BURST_13 = 22 + BURST_14 = 23 + BURST_15 = 24 + BURST_16 = 25 + ACK = 60 + FR_ACK = 61 + FR_REPEAT = 62 + FR_NACK = 63 + BURST_NACK = 64 + CQ = 200 + QRV = 201 + PING = 210 + PING_ACK = 211 + ARQ_SESSION_OPEN = 221 + ARQ_SESSION_HB = 222 + ARQ_SESSION_CLOSE = 223 + ARQ_DC_OPEN_W = 225 + ARQ_DC_OPEN_ACK_W = 226 + ARQ_DC_OPEN_N = 227 + ARQ_DC_OPEN_ACK_N = 228 + ARQ_STOP = 249 + BEACON = 250 + TEST_FRAME = 255 \ No newline at end of file From 8a5eea4dd536d0268209dc673190b9f4c49caeb2 Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 08:33:37 -0400 Subject: [PATCH 2/8] Make log_handler a little more flexible. (#215) --- tnc/log_handler.py | 71 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/tnc/log_handler.py b/tnc/log_handler.py index 514c2086..216f1c1a 100644 --- a/tnc/log_handler.py +++ b/tnc/log_handler.py @@ -22,44 +22,47 @@ def setup_logging(filename: str = "", level: str = "DEBUG"): timestamper, ] - logging.config.dictConfig( - { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "plain": { - "()": structlog.stdlib.ProcessorFormatter, - "processor": structlog.dev.ConsoleRenderer(colors=False), - "foreign_pre_chain": pre_chain, - }, - "colored": { - "()": structlog.stdlib.ProcessorFormatter, - "processor": structlog.dev.ConsoleRenderer(colors=True), - "foreign_pre_chain": pre_chain, - }, + config_dict = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "plain": { + "()": structlog.stdlib.ProcessorFormatter, + "processor": structlog.dev.ConsoleRenderer(colors=False), + "foreign_pre_chain": pre_chain, }, - "handlers": { - "default": { - "level": level, - "class": "logging.StreamHandler", - "formatter": "colored", - }, - "file": { - "level": level, - "class": "logging.handlers.WatchedFileHandler", - "filename": f"{filename}.log", - "formatter": "plain", - }, + "colored": { + "()": structlog.stdlib.ProcessorFormatter, + "processor": structlog.dev.ConsoleRenderer(colors=True), + "foreign_pre_chain": pre_chain, }, - "loggers": { - "": { - "handlers": ["default", "file"] if filename else ["default"], - "level": level, - "propagate": True, - }, + }, + "handlers": { + "default": { + "level": level, + "class": "logging.StreamHandler", + "formatter": "colored", }, + }, + "loggers": { + "": { + "handlers": ["default"], + "level": level, + "propagate": True, + }, + }, + } + + if filename: + config_dict["handlers"]["file"] = { + "level": level, + "class": "logging.handlers.WatchedFileHandler", + "filename": f"{filename}.log", + "formatter": "plain", } - ) + config_dict["loggers"][""]["handlers"].append("file") + + logging.config.dictConfig(config_dict) structlog.configure( processors=[ structlog.stdlib.add_log_level, From 1e054c8343da692d8db31bcb07e184c80147ab6b Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 08:38:22 -0400 Subject: [PATCH 3/8] Properly flag low/high bandwidth mode in chat test --- test/test_chat_text.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_chat_text.py b/test/test_chat_text.py index feecb5e7..75e0e888 100644 --- a/test/test_chat_text.py +++ b/test/test_chat_text.py @@ -145,7 +145,7 @@ def test_chat_text( STATIONS[0], STATIONS[1], messages[message_no], - True, # low bandwidth mode + freedv_mode == "datac3", # low bandwidth mode tmp_path, ), daemon=True, @@ -159,7 +159,7 @@ def test_chat_text( STATIONS[1], STATIONS[0], messages[message_no], - True, # low bandwidth mode + freedv_mode == "datac3", # low bandwidth mode tmp_path, ), daemon=True, From bc9e8849ac843e8937b28b331efe9651e55cf188 Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 08:42:20 -0400 Subject: [PATCH 4/8] Remove unused miniaudio install --- .github/workflows/ctest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ctest.yml b/.github/workflows/ctest.yml index 38cb8871..98cb0e4e 100644 --- a/.github/workflows/ctest.yml +++ b/.github/workflows/ctest.yml @@ -18,7 +18,7 @@ jobs: run: | sudo apt-get update sudo apt-get install octave octave-common octave-signal sox python3 python3-pip portaudio19-dev python3-pyaudio - pip3 install psutil crcengine ujson pyserial numpy structlog miniaudio sounddevice + pip3 install psutil crcengine ujson pyserial numpy structlog sounddevice pip3 install pytest pytest-rerunfailures - name: Build codec2 From 4a8f9ce6d0df601a487396bf77eb67000acaad5d Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 08:47:56 -0400 Subject: [PATCH 5/8] Correct merge omission --- tnc/data_handler.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tnc/data_handler.py b/tnc/data_handler.py index 10f64c88..f5676303 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -2277,11 +2277,11 @@ class DATA: """ # reset ARQ statistics static.ARQ_BYTES_PER_MINUTE_BURST = 0 - static.ARQ_BYTES_PER_MINUTE = 0 - static.ARQ_BITS_PER_SECOND_BURST = 0 - static.ARQ_BITS_PER_SECOND = 0 - static.ARQ_TRANSMISSION_PERCENT = 0 - static.TOTAL_BYTES = 0 + static.ARQ_BYTES_PER_MINUTE = 0 + static.ARQ_BITS_PER_SECOND_BURST = 0 + static.ARQ_BITS_PER_SECOND = 0 + static.ARQ_TRANSMISSION_PERCENT = 0 + static.TOTAL_BYTES = 0 def calculate_transfer_rate_tx( self, tx_start_of_transmission: float, sentbytes: int, tx_buffer_length: int From 1db20048fb39ca465fe20af866685ea8d1aed961 Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 09:39:32 -0400 Subject: [PATCH 6/8] Remove redundant test. --- test/test_modem.py | 156 --------------------------------------------- 1 file changed, 156 deletions(-) delete mode 100644 test/test_modem.py diff --git a/test/test_modem.py b/test/test_modem.py deleted file mode 100644 index 6d3d9054..00000000 --- a/test/test_modem.py +++ /dev/null @@ -1,156 +0,0 @@ -""" -Tests for the FreeDATA modem. -""" - -import multiprocessing -import sys -import time - -import pytest - -# pylint: disable=wrong-import-position -sys.path.insert(0, "..") -sys.path.insert(0, "../tnc") -import helpers -import modem -import static - - -def print_frame(data: bytearray): - """ - Pretty-print the provided frame. - - :param data: Frame to be output - :type data: bytearray - """ - print(f"Type : {int(data[0])}") - print(f"DXCRC : {bytes(data[1:4])}") - print(f"CallCRC: {bytes(data[4:7])}") - print(f"Call : {helpers.bytes_to_callsign(data[7:13])}") - - -def t_create_frame(frame_type: int, mycall: str, dxcall: str) -> bytearray: - """ - Generate the requested frame. - - :param frame_type: The numerical type of the desired frame. - :type frame_type: int - :param mycall: Callsign of the near station - :type mycall: str - :param dxcall: Callsign of the far station - :type dxcall: str - :return: Bytearray of the requested frame - :rtype: bytearray - """ - mycallsign_bytes = helpers.callsign_to_bytes(mycall) - mycallsign = helpers.bytes_to_callsign(mycallsign_bytes) - mycallsign_crc = helpers.get_crc_24(mycallsign) - - dxcallsign_bytes = helpers.callsign_to_bytes(dxcall) - dxcallsign = helpers.bytes_to_callsign(dxcallsign_bytes) - dxcallsign_crc = helpers.get_crc_24(dxcallsign) - - frame = bytearray(14) - frame[:1] = bytes([frame_type]) - frame[1:4] = dxcallsign_crc - frame[4:7] = mycallsign_crc - frame[7:13] = mycallsign_bytes - - return frame - - -def t_create_session_close(mycall: str, dxcall: str) -> bytearray: - """ - Generate the session_close frame. - - :param mycall: Callsign of the near station - :type mycall: str - :param dxcall: Callsign of the far station - :type dxcall: str - :return: Bytearray of the requested frame - :rtype: bytearray - """ - return t_create_frame(223, mycall, dxcall) - - -def t_create_start_session(mycall: str, dxcall: str) -> bytearray: - """ - Generate the create_session frame. - - :param mycall: Callsign of the near station - :type mycall: str - :param dxcall: Callsign of the far station - :type dxcall: str - :return: Bytearray of the requested frame - :rtype: bytearray - """ - return t_create_frame(221, mycall, dxcall) - - -def t_modem(): - """ - Execute test to validate that receiving a session open frame sets the correct machine - state. - """ - t_mode = t_repeats = t_repeat_delay = 0 - t_frames = [] - - def t_tx_dummy(mode, repeats, repeat_delay, frames): - """Replacement function for transmit""" - print(f"t_tx_dummy: In transmit({mode}, {repeats}, {repeat_delay}, {frames})") - nonlocal t_mode, t_repeats, t_repeat_delay, t_frames - t_mode = mode - t_repeats = repeats - t_repeat_delay = repeat_delay - t_frames = frames[:] - static.TRANSMITTING = False - - # enable testmode - modem.TESTMODE = True - modem.RXCHANNEL = "/tmp/hfchannel1" - modem.TXCHANNEL = "/tmp/hfchannel2" - static.HAMLIB_RADIOCONTROL = "disabled" - - # Create the modem - local_modem = modem.RF() - - # Replace transmit routine with our own, an effective No-Op. - local_modem.transmit = t_tx_dummy - - txbuffer = t_create_start_session("AA9AA", "DC2EJ") - - # Start the transmission - static.TRANSMITTING = True - modem.MODEM_TRANSMIT_QUEUE.put([14, 5, 250, txbuffer]) - while static.TRANSMITTING: - time.sleep(0.1) - - # Check that the contents were transferred correctly. - assert t_mode == 14 - assert t_repeats == 5 - assert t_repeat_delay == 250 - assert t_frames == txbuffer - - -def test_modem_queue(): - proc = multiprocessing.Process(target=t_modem, args=()) - # print("Starting threads.") - proc.start() - - time.sleep(0.5) - - # print("Terminating threads.") - proc.terminate() - proc.join() - - # print(f"\n{proc.exitcode=}") - assert proc.exitcode == 0 - - -if __name__ == "__main__": - # Run pytest with the current script as the filename. - ecode = pytest.main(["-v", "-s", sys.argv[0]]) - if ecode == 0: - print("errors: 0") - else: - print(ecode) From 56695039b32a251a3670b298e887afabd8459fd4 Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 09:55:50 -0400 Subject: [PATCH 7/8] Add documentation to tests and utilities. --- test/test_chat_text.py | 34 ++++++++++++++++++++++++--- test/test_datac0.py | 11 ++++++--- test/test_helpers.py | 8 ++++++- test/test_highsnr_stdio_C_P_datacx.py | 13 +++++++++- test/test_highsnr_stdio_P_C_datacx.py | 13 +++++++++- test/test_highsnr_stdio_P_P_datacx.py | 13 +++++++++- test/test_highsnr_stdio_P_P_multi.py | 13 +++++++++- test/test_tnc.py | 11 +++++++++ test/test_tnc_states.py | 12 +++++++++- test/util_chat_text_1.py | 9 ++++--- test/util_chat_text_2.py | 9 ++++--- test/util_datac0.py | 10 +++++--- test/util_multimode_rx.py | 10 ++++++++ test/util_multimode_tx.py | 9 +++++++ test/util_rx.py | 9 +++++-- test/util_tnc_IRS.py | 9 ++++--- test/util_tnc_ISS.py | 9 ++++--- test/util_tx.py | 9 +++++++ 18 files changed, 182 insertions(+), 29 deletions(-) diff --git a/test/test_chat_text.py b/test/test_chat_text.py index 75e0e888..7581dc9c 100644 --- a/test/test_chat_text.py +++ b/test/test_chat_text.py @@ -1,9 +1,17 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Test small (single-frame) and large (multi-frame) messages over a high quality +simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving data through the TNC and modem +and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. Tests both low- and +high-bandwidth data frames (datac3 and datac1 respectively) from Codec2. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_chat_test_[12].py in separate processes to perform the data transfer. """ import contextlib @@ -33,7 +41,27 @@ bytes_out = b'{"dt":"f","fn":"zeit.txt","ft":"text\\/plain","d":"data:text\\/pla messages = [ "This is a test chat...", - "This is a much longer message, hopefully longer than each of the datac1 and datac3 frames available to use in this modem. This should be long enought, but to err on the side of completeness this will string on for many more words before coming to the long awaited conclusion. We are not at the concluding point just yet because there is still more space to be taken up in the datac3 frame. Perhaps now would be a good place to terminate this test message, but perhaps not because we need a few more bytes. Here then we stop. This compresses so well that I need more data, even more stuff than is already here and included in the unreadable diatribe below, or is it a soliloquy? MyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=MyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=", + "This is a much longer message, hopefully longer than each of the datac1 and " + "datac3 frames available to use in this modem. This should be long enough, " + "but to err on the side of completeness this will string on for many more " + "words before coming to the long awaited conclusion. We are not at the " + "concluding point just yet because there is still more space to be taken up " + "in the datac3 frame. Perhaps now would be a good place to terminate this test " + "message, but perhaps not because we need a few more bytes. Here then we stop. " + "This compresses so well that I need more data, even more stuff than is already " + "here and included in the unreadable diatribe below, or is it a soliloquy? " + "MyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obm" + "UgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5" + "NjY5NzY1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0" + "MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG" + "9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=MyBtb2Rlcywgb2huZSBjbGFzcwowL" + "jAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODk" + "xMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5CgMyBtb2R" + "lcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjIgbW9kZXMsIG9obmUgY2xhc" + "3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY2xhc3MKMC4wMDA5NjY5NzY" + "1NTU4Nzc4MjA5CgMyBtb2Rlcywgb2huZSBjbGFzcwowLjAwMDk2OTQ4MTE4MDk5MTg0MTcKCjI" + "gbW9kZXMsIG9obmUgY2xhc3MKMC4wMDA5NjY1NDUxODkxMjI1Mzk0CgoxIG1vZGUsIG9obmUgY" + "2xhc3MKMC4wMDA5NjY5NzY1NTU4Nzc4MjA5Cg=", ] PIPE_THREAD_RUNNING = True diff --git a/test/test_datac0.py b/test/test_datac0.py index f4881fcf..0663d09a 100644 --- a/test/test_datac0.py +++ b/test/test_datac0.py @@ -1,9 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Test control frame commands over a high quality simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving select control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_datac0.py in separate process to perform the data transfer. """ import contextlib @@ -173,7 +179,6 @@ def analyze_results(station1: list, station2: list, call_list: list): # pytest.param("cq", marks=pytest.mark.xfail(reason="Too unstable for CI")), ], ) -# @pytest.mark.flaky(reruns=2) def test_datac0(frame_type: str, tmp_path): log_handler.setup_logging(filename=tmp_path / "test_datac0", level="DEBUG") log = structlog.get_logger("test_datac0") diff --git a/test/test_helpers.py b/test/test_helpers.py index e33eb798..b847c846 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -1,5 +1,11 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests for the FreeDATA TNC state machine. +Unit test common helper routines used throughout the TNC. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses no other files. """ import sys diff --git a/test/test_highsnr_stdio_C_P_datacx.py b/test/test_highsnr_stdio_C_P_datacx.py index fa5f4ba9..4bbd696c 100644 --- a/test/test_highsnr_stdio_C_P_datacx.py +++ b/test/test_highsnr_stdio_C_P_datacx.py @@ -1,5 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests a high signal-to-noise ratio path with codec2 data formats using codec2 to transmit. +Test small multiple-burst messages over a high quality simulated audio channel. + +Legacy test for sending / receiving frames through the codec2 modem +and back through on the other station. Data injection initiates directly into +codec2 API. Tests all three codec2 data frames. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_rx.py, sox and freedv_data_raw_tx in separate processeses to perform +the audio tests. """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_C_datacx.py b/test/test_highsnr_stdio_P_C_datacx.py index ea5316df..8f4af97e 100644 --- a/test/test_highsnr_stdio_P_C_datacx.py +++ b/test/test_highsnr_stdio_P_C_datacx.py @@ -1,5 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests a high signal-to-noise ratio path with codec2 data formats using codec2 to receive. +Test small multiple-burst messages over a high quality simulated audio channel. + +Legacy test for sending / receiving frames through the codec2 modem +and back through on the other station. Data injection initiates directly into +codec2 API. Tests all three codec2 data frames. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_tx.py, sox, freedv_data_raw_rx and hexdump in separate processeses to +perform the audio tests. """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_P_datacx.py b/test/test_highsnr_stdio_P_P_datacx.py index 634d5164..fdba8bb9 100644 --- a/test/test_highsnr_stdio_P_P_datacx.py +++ b/test/test_highsnr_stdio_P_P_datacx.py @@ -1,5 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests a high signal-to-noise ratio path with codec2 data formats. +Test small multiple-burst messages over a high quality simulated audio channel. + +Legacy test for sending / receiving frames through the codec2 modem +and back through on the other station. Data injection initiates directly into +codec2 API. Tests all three codec2 data frames. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_rx.py and util_tx.py in separate processeses to perform +the audio tests. """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_P_multi.py b/test/test_highsnr_stdio_P_P_multi.py index 17f44781..536a1849 100644 --- a/test/test_highsnr_stdio_P_P_multi.py +++ b/test/test_highsnr_stdio_P_P_multi.py @@ -1,5 +1,16 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests a high signal-to-noise ratio path with multiple codec2 data formats. +Test small multiple-burst messages over a high quality simulated audio channel. + +Legacy test for sending / receiving frames through the codec2 modem +and back through on the other station. Data injection initiates directly into +codec2 API. Tests all three codec2 data frames simultaneously. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_multimode_tx.py and util_multimode_tx in separate processeses to perform +the audio tests. """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_tnc.py b/test/test_tnc.py index 850a5a3f..f43b571d 100755 --- a/test/test_tnc.py +++ b/test/test_tnc.py @@ -1,5 +1,16 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +""" +Test connect frame commands over a high quality simulated audio channel. + +Near end-to-end test for sending / receiving connection control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_tnc_I[RS]S.py in separate process to perform the data transfer. +""" import multiprocessing import os diff --git a/test/test_tnc_states.py b/test/test_tnc_states.py index 9b46c69e..87548765 100644 --- a/test/test_tnc_states.py +++ b/test/test_tnc_states.py @@ -1,5 +1,15 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Tests for the FreeDATA TNC state machine. +Test control frame messages over a high quality simulated audio channel. + +Near end-to-end test for sending / receiving select control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Can be invoked from CMake, pytest, coverage or directly. + +Uses util_datac0.py in separate process to perform the data transfer. """ import multiprocessing diff --git a/test/util_chat_text_1.py b/test/util_chat_text_1.py index 1095c17d..11a01432 100644 --- a/test/util_chat_text_1.py +++ b/test/util_chat_text_1.py @@ -1,9 +1,12 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Send-side station emulator for connect frame tests over a high quality simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving connection control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Invoked from test_chat_text.py. """ import base64 diff --git a/test/util_chat_text_2.py b/test/util_chat_text_2.py index d77ebb15..0de11ff5 100644 --- a/test/util_chat_text_2.py +++ b/test/util_chat_text_2.py @@ -1,9 +1,12 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Receive-side station emulator for connect frame tests over a high quality simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving connection control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Invoked from test_chat_text.py. """ import time diff --git a/test/util_datac0.py b/test/util_datac0.py index 1e1068e0..366825ac 100644 --- a/test/util_datac0.py +++ b/test/util_datac0.py @@ -1,9 +1,13 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Send- and receive-side station emulator for control frame tests over a high quality +simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving control frames through the TNC and modem +and back through on the other station. Data injection initiates from the queue used +by the daemon process into and out of the TNC. + +Invoked from test_datac0.py. """ import json diff --git a/test/util_multimode_rx.py b/test/util_multimode_rx.py index 807d2155..7a1cceab 100755 --- a/test/util_multimode_rx.py +++ b/test/util_multimode_rx.py @@ -1,5 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +""" +Receive-side station emulator for test frame tests over a high quality audio channel +using a physical sound card or STDIO. + +Legacy test for sending / receiving connection test frames through the codec2 and +back through on the other station. Data injection initiates directly through +the codec2 API. Tests all three codec2 data frames simultaneously. + +Invoked from CMake, test_highsnr_stdio_P_P_multi.py, and many test_virtual[1-3]*.sh. +""" import argparse import ctypes diff --git a/test/util_multimode_tx.py b/test/util_multimode_tx.py index 9335e795..fb27fc9e 100644 --- a/test/util_multimode_tx.py +++ b/test/util_multimode_tx.py @@ -1,6 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +""" +Send-side station emulator for test frame tests over a high quality audio channel +using a physical sound card or STDIO. +Legacy test for sending / receiving connection test frames through the codec2 and +back through on the other station. Data injection initiates directly through +the codec2 API. Tests all three codec2 data frames simultaneously. + +Invoked from CMake, test_highsnr_stdio_P_P_multi.py, and many test_virtual[1-3]*.sh. +""" import argparse import ctypes diff --git a/test/util_rx.py b/test/util_rx.py index 8b69593f..ac84c4d0 100644 --- a/test/util_rx.py +++ b/test/util_rx.py @@ -1,9 +1,14 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Receive-side station emulator for test frame tests over a high quality audio channel +using a physical sound card or STDIO. -@author: DJ2LS +Legacy test for sending / receiving connection test frames through the codec2 and +back through on the other station. Data injection initiates directly through +the codec2 API. + +Invoked from CMake, test_highsnr_stdio_{P_C, P_P}_datacx.py, and many test_virtual[1-3]*.sh. """ import argparse diff --git a/test/util_tnc_IRS.py b/test/util_tnc_IRS.py index a38bc6de..2af34a4d 100644 --- a/test/util_tnc_IRS.py +++ b/test/util_tnc_IRS.py @@ -1,9 +1,12 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Receive-side station emulator for connect frame tests over a high quality simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving connection control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Invoked from test_tnc.py. """ import signal diff --git a/test/util_tnc_ISS.py b/test/util_tnc_ISS.py index 28a86914..cecf60b3 100644 --- a/test/util_tnc_ISS.py +++ b/test/util_tnc_ISS.py @@ -1,9 +1,12 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Created on Wed Dec 23 07:04:24 2020 +Send-side station emulator for connect frame tests over a high quality simulated audio channel. -@author: DJ2LS +Near end-to-end test for sending / receiving connection control frames through the +TNC and modem and back through on the other station. Data injection initiates from the +queue used by the daemon process into and out of the TNC. + +Invoked from test_tnc.py. """ import json diff --git a/test/util_tx.py b/test/util_tx.py index 6abebc30..76f3a548 100644 --- a/test/util_tx.py +++ b/test/util_tx.py @@ -1,6 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +""" +Send-side station emulator for test frame tests over a high quality audio channel +using a physical sound card or STDIO. +Legacy test for sending / receiving connection test frames through the codec2 and +back through on the other station. Data injection initiates directly through +the codec2 API. + +Invoked from CMake, test_highsnr_stdio_{P_C, P_P}_datacx.py, and many test_virtual[1-3]*.sh. +""" import argparse import ctypes From e0d4117518bd2c17619c7ba1c2ab25832536e64b Mon Sep 17 00:00:00 2001 From: Paul Kronenwetter Date: Sun, 19 Jun 2022 10:04:46 -0400 Subject: [PATCH 8/8] Re-add authorship tags. --- test/test_chat_text.py | 2 ++ test/test_datac0.py | 2 ++ test/test_helpers.py | 2 ++ test/test_highsnr_stdio_C_P_datacx.py | 2 ++ test/test_highsnr_stdio_P_C_datacx.py | 2 ++ test/test_highsnr_stdio_P_P_datacx.py | 2 ++ test/test_highsnr_stdio_P_P_multi.py | 2 ++ test/test_tnc.py | 2 ++ test/test_tnc_states.py | 2 ++ test/util_chat_text_1.py | 2 ++ test/util_chat_text_2.py | 2 ++ test/util_datac0.py | 2 ++ test/util_multimode_rx.py | 2 ++ test/util_multimode_tx.py | 2 ++ test/util_rx.py | 2 ++ test/util_tnc_IRS.py | 2 ++ test/util_tnc_ISS.py | 2 ++ test/util_tx.py | 2 ++ 18 files changed, 36 insertions(+) diff --git a/test/test_chat_text.py b/test/test_chat_text.py index 7581dc9c..aacdf2a4 100644 --- a/test/test_chat_text.py +++ b/test/test_chat_text.py @@ -12,6 +12,8 @@ high-bandwidth data frames (datac3 and datac1 respectively) from Codec2. Can be invoked from CMake, pytest, coverage or directly. Uses util_chat_test_[12].py in separate processes to perform the data transfer. + +@author: N2KIQ """ import contextlib diff --git a/test/test_datac0.py b/test/test_datac0.py index 0663d09a..3761b298 100644 --- a/test/test_datac0.py +++ b/test/test_datac0.py @@ -10,6 +10,8 @@ queue used by the daemon process into and out of the TNC. Can be invoked from CMake, pytest, coverage or directly. Uses util_datac0.py in separate process to perform the data transfer. + +@author: N2KIQ """ import contextlib diff --git a/test/test_helpers.py b/test/test_helpers.py index b847c846..49186b7a 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -6,6 +6,8 @@ Unit test common helper routines used throughout the TNC. Can be invoked from CMake, pytest, coverage or directly. Uses no other files. + +@author: N2KIQ """ import sys diff --git a/test/test_highsnr_stdio_C_P_datacx.py b/test/test_highsnr_stdio_C_P_datacx.py index 4bbd696c..058074a1 100644 --- a/test/test_highsnr_stdio_C_P_datacx.py +++ b/test/test_highsnr_stdio_C_P_datacx.py @@ -11,6 +11,8 @@ Can be invoked from CMake, pytest, coverage or directly. Uses util_rx.py, sox and freedv_data_raw_tx in separate processeses to perform the audio tests. + +@author: DJ2LS, N2KIQ """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_C_datacx.py b/test/test_highsnr_stdio_P_C_datacx.py index 8f4af97e..3ba5f222 100644 --- a/test/test_highsnr_stdio_P_C_datacx.py +++ b/test/test_highsnr_stdio_P_C_datacx.py @@ -11,6 +11,8 @@ Can be invoked from CMake, pytest, coverage or directly. Uses util_tx.py, sox, freedv_data_raw_rx and hexdump in separate processeses to perform the audio tests. + +@author: N2KIQ """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_P_datacx.py b/test/test_highsnr_stdio_P_P_datacx.py index fdba8bb9..c430e96f 100644 --- a/test/test_highsnr_stdio_P_P_datacx.py +++ b/test/test_highsnr_stdio_P_P_datacx.py @@ -11,6 +11,8 @@ Can be invoked from CMake, pytest, coverage or directly. Uses util_rx.py and util_tx.py in separate processeses to perform the audio tests. + +@author: N2KIQ """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_highsnr_stdio_P_P_multi.py b/test/test_highsnr_stdio_P_P_multi.py index 536a1849..2c02802f 100644 --- a/test/test_highsnr_stdio_P_P_multi.py +++ b/test/test_highsnr_stdio_P_P_multi.py @@ -11,6 +11,8 @@ Can be invoked from CMake, pytest, coverage or directly. Uses util_multimode_tx.py and util_multimode_tx in separate processeses to perform the audio tests. + +@author: N2KIQ """ # pylint: disable=global-statement, invalid-name, unused-import diff --git a/test/test_tnc.py b/test/test_tnc.py index f43b571d..58de47b1 100755 --- a/test/test_tnc.py +++ b/test/test_tnc.py @@ -10,6 +10,8 @@ queue used by the daemon process into and out of the TNC. Can be invoked from CMake, pytest, coverage or directly. Uses util_tnc_I[RS]S.py in separate process to perform the data transfer. + +@author: DJ2LS, N2KIQ """ import multiprocessing diff --git a/test/test_tnc_states.py b/test/test_tnc_states.py index 87548765..3b5e6b47 100644 --- a/test/test_tnc_states.py +++ b/test/test_tnc_states.py @@ -10,6 +10,8 @@ queue used by the daemon process into and out of the TNC. Can be invoked from CMake, pytest, coverage or directly. Uses util_datac0.py in separate process to perform the data transfer. + +@author: N2KIQ """ import multiprocessing diff --git a/test/util_chat_text_1.py b/test/util_chat_text_1.py index 11a01432..329b7bcd 100644 --- a/test/util_chat_text_1.py +++ b/test/util_chat_text_1.py @@ -7,6 +7,8 @@ TNC and modem and back through on the other station. Data injection initiates fr queue used by the daemon process into and out of the TNC. Invoked from test_chat_text.py. + +@author: N2KIQ """ import base64 diff --git a/test/util_chat_text_2.py b/test/util_chat_text_2.py index 0de11ff5..2b9285e8 100644 --- a/test/util_chat_text_2.py +++ b/test/util_chat_text_2.py @@ -7,6 +7,8 @@ TNC and modem and back through on the other station. Data injection initiates fr queue used by the daemon process into and out of the TNC. Invoked from test_chat_text.py. + +@author: N2KIQ """ import time diff --git a/test/util_datac0.py b/test/util_datac0.py index 366825ac..7b2d60a6 100644 --- a/test/util_datac0.py +++ b/test/util_datac0.py @@ -8,6 +8,8 @@ and back through on the other station. Data injection initiates from the queue u by the daemon process into and out of the TNC. Invoked from test_datac0.py. + +@author: N2KIQ """ import json diff --git a/test/util_multimode_rx.py b/test/util_multimode_rx.py index 7a1cceab..61af5e56 100755 --- a/test/util_multimode_rx.py +++ b/test/util_multimode_rx.py @@ -9,6 +9,8 @@ back through on the other station. Data injection initiates directly through the codec2 API. Tests all three codec2 data frames simultaneously. Invoked from CMake, test_highsnr_stdio_P_P_multi.py, and many test_virtual[1-3]*.sh. + +@author: DJ2LS """ import argparse diff --git a/test/util_multimode_tx.py b/test/util_multimode_tx.py index fb27fc9e..986cc3f7 100644 --- a/test/util_multimode_tx.py +++ b/test/util_multimode_tx.py @@ -9,6 +9,8 @@ back through on the other station. Data injection initiates directly through the codec2 API. Tests all three codec2 data frames simultaneously. Invoked from CMake, test_highsnr_stdio_P_P_multi.py, and many test_virtual[1-3]*.sh. + +@author: DJ2LS """ import argparse diff --git a/test/util_rx.py b/test/util_rx.py index ac84c4d0..ab7613e0 100644 --- a/test/util_rx.py +++ b/test/util_rx.py @@ -9,6 +9,8 @@ back through on the other station. Data injection initiates directly through the codec2 API. Invoked from CMake, test_highsnr_stdio_{P_C, P_P}_datacx.py, and many test_virtual[1-3]*.sh. + +@author: DJ2LS """ import argparse diff --git a/test/util_tnc_IRS.py b/test/util_tnc_IRS.py index 2af34a4d..99507cd3 100644 --- a/test/util_tnc_IRS.py +++ b/test/util_tnc_IRS.py @@ -7,6 +7,8 @@ TNC and modem and back through on the other station. Data injection initiates fr queue used by the daemon process into and out of the TNC. Invoked from test_tnc.py. + +@author: N2KIQ """ import signal diff --git a/test/util_tnc_ISS.py b/test/util_tnc_ISS.py index cecf60b3..f3d20a35 100644 --- a/test/util_tnc_ISS.py +++ b/test/util_tnc_ISS.py @@ -7,6 +7,8 @@ TNC and modem and back through on the other station. Data injection initiates fr queue used by the daemon process into and out of the TNC. Invoked from test_tnc.py. + +@author: DJ2LS, N2KIQ """ import json diff --git a/test/util_tx.py b/test/util_tx.py index 76f3a548..06e6a636 100644 --- a/test/util_tx.py +++ b/test/util_tx.py @@ -9,6 +9,8 @@ back through on the other station. Data injection initiates directly through the codec2 API. Invoked from CMake, test_highsnr_stdio_{P_C, P_P}_datacx.py, and many test_virtual[1-3]*.sh. + +@author: DJ2LS """ import argparse