added test cases and changed test case structure

master
Konstantin Gründger 2025-05-21 17:23:18 +02:00
rodzic 14cf4848c8
commit 3f326d5087
7 zmienionych plików z 210 dodań i 159 usunięć

Wyświetl plik

@ -0,0 +1,23 @@
from datetime import datetime, timezone
from ogn.parser import parse
def test_comment():
raw_message = "# bad configured ogn receiver"
message = parse(raw_message)
assert message['comment'] == raw_message
assert message['aprs_type'] == 'comment'
def test_server_comment():
raw_message = "# aprsc 2.1.4-g408ed49 17 Mar 2018 09:30:36 GMT GLIDERN1 37.187.40.234:10152"
message = parse(raw_message)
assert message['version'] == '2.1.4-g408ed49'
assert message['timestamp'] == datetime(2018, 3, 17, 9, 30, 36, tzinfo=timezone.utc)
assert message['server'] == 'GLIDERN1'
assert message['ip_address'] == '37.187.40.234'
assert message['port'] == 10152
assert message['aprs_type'] == 'server'

Wyświetl plik

@ -10,7 +10,7 @@ from ogn.parser.exceptions import AprsParseError
def _parse_valid_beacon_data_file(filename, beacon_type):
with open(os.path.dirname(__file__) + '/../../ogn-aprs-protocol/valid_messages/' + filename) as f:
with open(os.path.dirname(__file__) + '/../../../ogn-aprs-protocol/valid_messages/' + filename) as f:
for line in f:
if line.strip() == '':
continue
@ -143,7 +143,10 @@ def test_spot_beacons():
def test_generic_beacons():
message = parse("EPZR>WTFDSTCALL,TCPIP*,qAC,GLIDERN1:>093456h this is a comment")
assert message['aprs_type'] == 'status'
assert message['beacon_type'] == 'unknown'
assert message['user_comment'] == "this is a comment"
@ -157,6 +160,11 @@ def test_fail_empty():
parse("")
def test_fail_validationassert():
with pytest.raises(AprsParseError):
parse("notAValidString")
def test_fail_bad_string():
with pytest.raises(AprsParseError):
parse("Lachens>APRS,TCPIwontbeavalidstring")
@ -186,19 +194,12 @@ def test_default_reference_date(createTimestamp_mock):
assert call_args_before != call_args_seconds_later
def test_copy_constructor():
valid_aprs_string = "FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 id0ADDA5BA -454fpm -1.1rot 8.8dB 0e +51.2kHz gps4x5"
message = parse(valid_aprs_string)
assert message['name'] == 'FLRDDA5BA'
assert message['address'] == 'DDA5BA'
def test_no_receiver():
result = parse("EDFW>OGNSDR:/102713h4949.02NI00953.88E&/A=000984")
assert result['aprs_type'] == 'position'
assert result['beacon_type'] == 'receiver'
assert result['name'] == 'EDFW'
assert result['dstcall'] == 'OGNSDR'
assert result.get('receiver_name') is None

Wyświetl plik

@ -0,0 +1,100 @@
import pytest
from ogn.parser import parse
from ogn.parser.exceptions import AprsParseError
from ogn.parser.utils import FPM_TO_MS, HPM_TO_DEGS, KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER
def test_basic():
raw_message = r"FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 this is a comment"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['beacon_type'] == 'unknown'
assert message['name'] == "FLRDDA5BA"
assert message['dstcall'] == "APRS"
assert message['receiver_name'] == "LFMX"
assert message['timestamp'].strftime('%H:%M:%S') == "16:08:29"
assert message['latitude'] == pytest.approx(44.25683, 5)
assert message['symboltable'] == '/'
assert message['longitude'] == pytest.approx(6.0005, 5)
assert message['symbolcode'] == '\''
assert message['track'] == 342
assert message['ground_speed'] == 49 * KNOTS_TO_MS / KPH_TO_MS
assert message['altitude'] == pytest.approx(5524 * FEETS_TO_METER, 5)
assert message['user_comment'] == "this is a comment"
def test_v026_relay():
# beacons can be relayed
raw_message = "FLRFFFFFF>OGNAVI,NAV07220E*,qAS,NAVITER:/092002h1000.00S/01000.00W'000/000/A=003281 !W00! id2820FFFFFF +300fpm +1.7rot"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['beacon_type'] == 'naviter'
assert message['relay'] == "NAV07220E"
def test_no_altitude():
# altitude is not a 'must have'
raw_message = "FLRDDEEF1>OGCAPT,qAS,CAPTURS:/065511h4837.63N/00233.79E'000/000"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['beacon_type'] == 'capturs'
assert message.get('altitude') is None
def test_invalid_coordinates():
# sometimes the coordinates leave their valid range: -90<=latitude<=90 or -180<=longitude<=180
with pytest.raises(AprsParseError):
parse("RND000000>APRS,qAS,TROCALAN1:/210042h6505.31S/18136.75W^054/325/A=002591 !W31! idA4000000 +099fpm +1.8rot FL029.04 12.0dB 5e -6.3kHz gps11x17")
with pytest.raises(AprsParseError):
parse("RND000000>APRS,qAS,TROCALAN1:/210042h9505.31S/17136.75W^054/325/A=002591 !W31! idA4000000 +099fpm +1.8rot FL029.04 12.0dB 5e -6.3kHz gps11x17")
def test_invalid_timestamp():
with pytest.raises(AprsParseError):
parse("OGND4362A>APRS,qAS,Eternoz:/194490h4700.25N/00601.47E'003/063/A=000000 !W22! id07D4362A 0fpm +0.0rot FL000.00 2.0dB 3e -2.8kHz gps3x4 +12.2dBm")
with pytest.raises(AprsParseError):
parse("Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/194490h5747.30NI01324.77E&/A=001322")
def test():
raw_message = r"FLRDDEEF1>OGCAPT,qAS,CAPTURS:/065511h4837.63N/00233.79E'255/045/A=003399 !W03! id06DDFAA3 -613fpm -3.9rot 22.5dB 7e -7.0kHz gps3x7 s7.07 h41 rD002F8"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['beacon_type'] == 'capturs'
assert message['name'] == "FLRDDEEF1"
assert message['dstcall'] == "OGCAPT"
assert message['receiver_name'] == "CAPTURS"
assert message['timestamp'].strftime('%H:%M:%S') == "06:55:11"
assert message['latitude'] == pytest.approx(48.62605, 5)
assert message['longitude'] == pytest.approx(2.56298, 5)
assert message['symboltable'] == '/'
assert message['symbolcode'] == '\''
assert message['track'] == 255
assert message['ground_speed'] == 45 * KNOTS_TO_MS / KPH_TO_MS
assert message['altitude'] == pytest.approx(3399 * FEETS_TO_METER, 5)
assert message['address_type'] == 2
assert message['aircraft_type'] == 1
assert message['stealth'] is False
assert message['no-tracking'] is False
assert message['address'] == 'DDFAA3'
assert message['climb_rate'] == pytest.approx(-613 * FPM_TO_MS, 0.1)
assert message['turn_rate'] == pytest.approx(-3.9 * HPM_TO_DEGS, 0.1)
assert message['signal_quality'] == 22.5
assert message['error_count'] == 7
assert message['frequency_offset'] == -7.0
assert message['gps_quality'] == '3x7'
assert message['software_version'] == 7.07
assert message['hardware_version'] == 65
assert message['real_address'] == 'D002F8'

Wyświetl plik

@ -0,0 +1,32 @@
from ogn.parser import parse
from ogn.parser.utils import KNOTS_TO_MS, KPH_TO_MS, INCH_TO_MM, fahrenheit_to_celsius
def test_v028_fanet_position_weather():
# with v0.2.8 fanet devices can report weather data
raw_message = 'FNTFC9002>OGNFNT,qAS,LSXI2:/163051h4640.33N/00752.21E_187/004g007t075h78b63620 29.0dB -8.0kHz'
message = parse(raw_message)
assert message['aprs_type'] == 'position_weather'
assert message['beacon_type'] == 'fanet'
assert message['wind_direction'] == 187
assert message['wind_speed'] == 4 * KNOTS_TO_MS / KPH_TO_MS
assert message['wind_speed_peak'] == 7 * KNOTS_TO_MS / KPH_TO_MS
assert message['temperature'] == fahrenheit_to_celsius(75)
assert message['humidity'] == 78 * 0.01
assert message['barometric_pressure'] == 63620
assert message['signal_quality'] == 29.0
assert message['frequency_offset'] == -8.0
def test_GXAirCom_fanet_position_weather_rainfall():
raw_message = 'FNT08F298>OGNFNT,qAS,DREIFBERG:/082654h4804.90N/00845.74E_273/005g008t057r123p234h90b10264 0.0dB'
message = parse(raw_message)
assert message['aprs_type'] == 'position_weather'
assert message['beacon_type'] == 'fanet'
assert message['rainfall_1h'] == 123 / 100 * INCH_TO_MM
assert message['rainfall_24h'] == 234 / 100 * INCH_TO_MM

Wyświetl plik

@ -0,0 +1,45 @@
from ogn.parser import parse
def test_v025():
# introduced the "aprs status" format where many informations (lat, lon, alt, speed, ...) are just optional
raw_message = "EPZR>APRS,TCPIP*,qAC,GLIDERN1:>093456h this is a comment"
message = parse(raw_message)
assert message['aprs_type'] == 'status'
assert message['beacon_type'] == 'unknown'
assert message['name'] == "EPZR"
assert message['receiver_name'] == "GLIDERN1"
assert message['timestamp'].strftime('%H:%M:%S') == "09:34:56"
assert message['user_comment'] == "this is a comment"
def test():
raw_message = "EPZR>APRS,TCPIP*,qAC,GLIDERN1:>093456h v0.2.7.RPI-GPU CPU:0.7 RAM:770.2/968.2MB NTP:1.8ms/-3.3ppm +55.7C 7/8Acfts[1h] RF:+54-1.1ppm/-0.16dB/+7.1dB@10km[19481]/+16.8dB@10km[7/13]"
message = parse(raw_message)
assert message['aprs_type'] == 'status'
assert message['beacon_type'] == 'unknown'
assert message['name'] == "EPZR"
assert message['receiver_name'] == "GLIDERN1"
assert message['timestamp'].strftime('%H:%M:%S') == "09:34:56"
assert message['version'] == "0.2.7"
assert message['platform'] == "RPI-GPU"
assert message['cpu_load'] == 0.7
assert message['free_ram'] == 770.2
assert message['total_ram'] == 968.2
assert message['ntp_offset'] == 1.8
assert message['rt_crystal_correction'] == -3.3
assert message['cpu_temp'] == 55.7
assert message['senders_visible'] == 7
assert message['senders_total'] == 8
assert message['rec_crystal_correction'] == 54
assert message['rec_crystal_correction_fine'] == -1.1
assert message['rec_input_noise'] == -0.16
assert message['senders_signal'] == 7.1
assert message['senders_messages'] == 19481
assert message['good_senders_signal'] == 16.8
assert message['good_senders'] == 7
assert message['good_and_bad_senders'] == 13

Wyświetl plik

@ -1,150 +0,0 @@
import pytest
from datetime import datetime, timezone
from ogn.parser import parse
from ogn.parser.utils import KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER, INCH_TO_MM, fahrenheit_to_celsius
from ogn.parser.exceptions import AprsParseError
def test_fail_validationassert():
with pytest.raises(AprsParseError):
parse("notAValidString")
def test_basic():
message = parse("FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 this is a comment")
assert message['aprs_type'] == 'position'
assert message['name'] == "FLRDDA5BA"
assert message['dstcall'] == "APRS"
assert message['receiver_name'] == "LFMX"
assert message['timestamp'].strftime('%H:%M:%S') == "16:08:29"
assert message['latitude'] == pytest.approx(44.25683, 5)
assert message['symboltable'] == '/'
assert message['longitude'] == pytest.approx(6.0005, 5)
assert message['symbolcode'] == '\''
assert message['track'] == 342
assert message['ground_speed'] == 49 * KNOTS_TO_MS / KPH_TO_MS
assert message['altitude'] == pytest.approx(5524 * FEETS_TO_METER, 5)
assert message['user_comment'] == "this is a comment"
def test_v024():
# higher precision datum format introduced
raw_message = "FLRDDA5BA>APRS,qAS,LFMX:/160829h4415.41N/00600.03E'342/049/A=005524 !W26! id21400EA9 -2454fpm +0.9rot 19.5dB 0e -6.6kHz gps1x1 s6.02 h44 rDF0C56"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['latitude'] - 44.2568 - 1 / 30000 == pytest.approx(2 / 1000 / 60, 10)
assert message['longitude'] - 6.0005 == pytest.approx(6 / 1000 / 60, 10)
def test_v025():
# introduced the "aprs status" format where many informations (lat, lon, alt, speed, ...) are just optional
raw_message = "EPZR>APRS,TCPIP*,qAC,GLIDERN1:>093456h this is a comment"
message = parse(raw_message)
assert message['aprs_type'] == 'status'
assert message['name'] == "EPZR"
assert message['receiver_name'] == "GLIDERN1"
assert message['timestamp'].strftime('%H:%M:%S') == "09:34:56"
assert message['user_comment'] == "this is a comment"
def test_v026():
# from 0.2.6 the ogn comment of a receiver beacon is just optional
raw_message = "Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/085616h5747.30NI01324.77E&/A=001322"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message.get('comment') is None
def test_v026_relay():
# beacons can be relayed
raw_message = "FLRFFFFFF>OGNAVI,NAV07220E*,qAS,NAVITER:/092002h1000.00S/01000.00W'000/000/A=003281 !W00! id2820FFFFFF +300fpm +1.7rot"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['relay'] == "NAV07220E"
def test_v027_ddhhmm():
# beacons can have hhmmss or ddhhmm timestamp
raw_message = "ICA4B0678>APRS,qAS,LSZF:/301046z4729.50N/00812.89E'227/091/A=002854 !W01! id054B0678 +040fpm +0.0rot 19.0dB 0e +1.5kHz gps1x1"
message = parse(raw_message)
assert message['aprs_type'] == 'position'
assert message['timestamp'].strftime('%d %H:%M') == "30 10:46"
def test_v028_fanet_position_weather():
# with v0.2.8 fanet devices can report weather data
raw_message = 'FNTFC9002>OGNFNT,qAS,LSXI2:/163051h4640.33N/00752.21E_187/004g007t075h78b63620 29.0dB -8.0kHz'
message = parse(raw_message)
assert message['aprs_type'] == 'position_weather'
assert message['wind_direction'] == 187
assert message['wind_speed'] == 4 * KNOTS_TO_MS / KPH_TO_MS
assert message['wind_speed_peak'] == 7 * KNOTS_TO_MS / KPH_TO_MS
assert message['temperature'] == fahrenheit_to_celsius(75)
assert message['humidity'] == 78 * 0.01
assert message['barometric_pressure'] == 63620
assert message['signal_quality'] == 29.0
assert message['frequency_offset'] == -8.0
def test_GXAirCom_fanet_position_weather_rainfall():
raw_message = 'FNT08F298>OGNFNT,qAS,DREIFBERG:/082654h4804.90N/00845.74E_273/005g008t057r123p234h90b10264 0.0dB'
message = parse(raw_message)
assert message['aprs_type'] == 'position_weather'
assert message['rainfall_1h'] == 123 / 100 * INCH_TO_MM
assert message['rainfall_24h'] == 234 / 100 * INCH_TO_MM
def test_no_altitude():
# altitude is not a 'must have'
raw_message = "FLRDDEEF1>OGCAPT,qAS,CAPTURS:/065511h4837.63N/00233.79E'000/000"
message = parse(raw_message)
assert message.get('altitude') is None
def test_invalid_coordinates():
# sometimes the coordinates leave their valid range: -90<=latitude<=90 or -180<=longitude<=180
with pytest.raises(AprsParseError):
parse("RND000000>APRS,qAS,TROCALAN1:/210042h6505.31S/18136.75W^054/325/A=002591 !W31! idA4000000 +099fpm +1.8rot FL029.04 12.0dB 5e -6.3kHz gps11x17")
with pytest.raises(AprsParseError):
parse("RND000000>APRS,qAS,TROCALAN1:/210042h9505.31S/17136.75W^054/325/A=002591 !W31! idA4000000 +099fpm +1.8rot FL029.04 12.0dB 5e -6.3kHz gps11x17")
def test_invalid_timestamp():
with pytest.raises(AprsParseError):
parse("OGND4362A>APRS,qAS,Eternoz:/194490h4700.25N/00601.47E'003/063/A=000000 !W22! id07D4362A 0fpm +0.0rot FL000.00 2.0dB 3e -2.8kHz gps3x4 +12.2dBm")
with pytest.raises(AprsParseError):
parse("Ulrichamn>APRS,TCPIP*,qAC,GLIDERN1:/194490h5747.30NI01324.77E&/A=001322")
def test_bad_comment():
raw_message = "# bad configured ogn receiver"
message = parse(raw_message)
assert message['comment'] == raw_message
assert message['aprs_type'] == 'comment'
def test_server_comment():
raw_message = "# aprsc 2.1.4-g408ed49 17 Mar 2018 09:30:36 GMT GLIDERN1 37.187.40.234:10152"
message = parse(raw_message)
assert message['version'] == '2.1.4-g408ed49'
assert message['timestamp'] == datetime(2018, 3, 17, 9, 30, 36, tzinfo=timezone.utc)
assert message['server'] == 'GLIDERN1'
assert message['ip_address'] == '37.187.40.234'
assert message['port'] == 10152
assert message['aprs_type'] == 'server'