Skip to content

Commit

Permalink
Attempt at fix for #387 (#388)
Browse files Browse the repository at this point in the history
* Attempt at fix for #387

* Made the return statements a bit more concise
  • Loading branch information
webbpinner authored May 9, 2024
1 parent 8ce3e71 commit a95de69
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
53 changes: 53 additions & 0 deletions logger/readers/test_udp_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@
b'\xff\xa2',
b'\xff\xa3']

SAMPLE_DATA_EOL = [
"$INGGA,074633.951958,4914.2813714,N,00457.4807581,W,4,,0.616,-95.296,M,,M,,*67\n$INGGA,074634.054429,4914.2813739,N,00457.4807665,W,4,,0.616,-95.296,M,,M,,*61\n",
"$INGGA,074634.151923,4914.2813762,N,00457.4807746,W,4,,0.616,-95.297,M,,M,,*6D\n",
"$INGGA,074634.351497,4914.2813879,N,00457.4807920,W,4,,0.616,-95.293,M,,M,,*62"
]

SAMPLE_DATA_EOL_OUTPUT = [
[
"$INGGA,074633.951958,4914.2813714,N,00457.4807581,W,4,,0.616,-95.296,M,,M,,*67",
"$INGGA,074634.054429,4914.2813739,N,00457.4807665,W,4,,0.616,-95.296,M,,M,,*61"
],
"$INGGA,074634.151923,4914.2813762,N,00457.4807746,W,4,,0.616,-95.297,M,,M,,*6D",
"$INGGA,074634.351497,4914.2813879,N,00457.4807920,W,4,,0.616,-95.293,M,,M,,*62"
]

# We're going to set MAXSIZE to 1K before writing this, and the fragmentation
# marker is 10 bytes long. The first record here should fragment cleanly into
# all a's, all b's, and all c's, then get reassembled by the reader
Expand Down Expand Up @@ -84,6 +99,23 @@ def read_udp(self, interface, port, data, mc_group=None, encoding='utf-8', delay
self.assertTrue(False, 'UDPReader timed out in test - is port '
'%s:%s open?' % (interface, port))

############################
# Read with eol
def read_udp_eol(self, interface, port, data, mc_group=None, encoding='utf-8', delay=0):
time.sleep(delay)
try:
reader = UDPReader(interface=interface, port=port, mc_group=mc_group, encoding=encoding,
eol='\n', this_is_a_test=True)
for line in data:
time.sleep(delay)
logging.debug('UDPReader reading...')
result = reader.read()
self.assertEqual(line, result)
except ReaderTimeout:
self.assertTrue(False, 'UDPReader timed out in test - is port '
'%s:%s open?' % (interface, port))


############################
# UNICAST
def test_unicast(self):
Expand All @@ -107,6 +139,27 @@ def test_unicast(self):
# Silence the alarm
signal.alarm(0)

def test_unicast_with_eol(self):
port = 8000
dest = 'localhost'

w_thread = threading.Thread(target=self.write_udp, name='write_thread',
args=(dest, port, SAMPLE_DATA_EOL),
kwargs={'interval': 0.1, 'delay': 0.2})

# Set timeout we can catch if things are taking too long
signal.signal(signal.SIGALRM, self._handler)
signal.alarm(1)

w_thread.start()
self.read_udp_eol(dest, port, SAMPLE_DATA_EOL_OUTPUT)

# Make sure everyone has terminated
w_thread.join()

# Silence the alarm
signal.alarm(0)

############################
# UNICAST raw/binary
def test_unicast_binary(self):
Expand Down
32 changes: 23 additions & 9 deletions logger/readers/udp_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class UDPReader(Reader):
############################
def __init__(self, interface=None, port=None, mc_group=None,
reuseaddr=False, reuseport=False,
encoding='utf-8', encoding_errors='ignore',
encoding='utf-8', encoding_errors='ignore', eol=None,
this_is_a_test=False):
"""
```
Expand All @@ -63,14 +63,16 @@ def __init__(self, interface=None, port=None, mc_group=None,
reuseport Specifies wether we set SO_REUSEPORT on the created socket. If
you don't know you need this, don't enable it.
encoding - 'utf-8' by default. If empty or None, do not attempt any decoding
and return raw bytes. Other possible encodings are listed in online
documentation here:
https://docs.python.org/3/library/codecs.html#standard-encodings
encoding 'utf-8' by default. If empty or None, do not attempt any decoding
and return raw bytes. Other possible encodings are listed in
online documentation here:
https://docs. python.org/3/library/codecs.html#standard-encodings
encoding_errors - 'ignore' by default. Other error strategies are 'strict',
'replace', and 'backslashreplace', described here:
https://docs.python.org/3/howto/unicode.html#encodings
encoding_errors 'ignore' by default. Other error strategies are 'strict',
'replace', and 'backslashreplace', described here:
https://docs.python.org/3/howto/unicode.html#encodings
eol split the record by the eol character if present.
this_is_a_test - If True, recognize that this is being called in a unittest, so
don't output warnings about not using loopback addresses.
Expand Down Expand Up @@ -117,6 +119,8 @@ def __init__(self, interface=None, port=None, mc_group=None,
self.reuseaddr = reuseaddr
self.reuseport = reuseport

self.eol = eol

self.this_is_a_test = this_is_a_test

# socket gets initialized on-demand in read()
Expand Down Expand Up @@ -213,4 +217,14 @@ def read(self):
break

# we've got a whole record in our record_buffer, decode it
return self._decode_bytes(record_buffer)

# if eol == None, return the record as is
if not self.eol:
return self._decode_bytes(record_buffer)

# otherwise split the record by the eol
decoded_records = self._decode_bytes(record_buffer).rstrip(self.eol).split(self.eol)

# if there was only one record, return just the first element in the
# list, otherwise return the whole list.
return decoded_records[0] if len(decoded_records) == 1 else decoded_records

0 comments on commit a95de69

Please sign in to comment.