Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions can/io/blf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class BLFParseError(Exception):
OBJ_HEADER_BASE_STRUCT = struct.Struct("<4sHHLL")

# flags, client index, object version, timestamp
OBJ_HEADER_V1_STRUCT = struct.Struct("<LHHQ")
OBJ_HEADER_V1_STRUCT = struct.Struct("<LHHq")

# flags, timestamp status, object version, timestamp, (original timestamp)
OBJ_HEADER_V2_STRUCT = struct.Struct("<LBxHQ8x")
OBJ_HEADER_V2_STRUCT = struct.Struct("<LBxHq8x")

# compression method, size uncompressed
LOG_CONTAINER_STRUCT = struct.Struct("<H6xL4x")
Expand Down Expand Up @@ -546,7 +546,7 @@ def _add_object(
base_header = OBJ_HEADER_BASE_STRUCT.pack(
b"LOBJ", header_size, 1, obj_size, obj_type
)
obj_header = OBJ_HEADER_V1_STRUCT.pack(TIME_ONE_NANS, 0, 0, max(timestamp, 0))
obj_header = OBJ_HEADER_V1_STRUCT.pack(TIME_ONE_NANS, 0, 0, timestamp)

self._buffer.append(base_header)
self._buffer.append(obj_header)
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/+blf_prerecording_timestamps.fixed.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
changed interpretion of blf recording relative timestamps from unsigned to signed int64
36 changes: 34 additions & 2 deletions test/logformats_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
from pathlib import Path
from unittest.mock import patch

from parameterized import parameterized

import can.io
from can.io import asc, blf
from parameterized import parameterized

from .data.example_data import (
TEST_COMMENTS,
Expand Down Expand Up @@ -908,6 +907,39 @@ def test_can_fd_message_64(self):
self.assertMessagesEqual(actual, [expected] * 2)
self.assertEqual(actual[0].channel, expected.channel)

def test_readwrite_cycle(self):
data_folder = os.path.join(os.path.dirname(__file__), "data")
dont_test_files = ["test_CanErrorFrameExt.blf"]
blf_test_files = [ f for f in os.listdir(data_folder) if f.endswith(".blf") and f not in dont_test_files ]
for src in blf_test_files:
with can.BLFReader(os.path.join(data_folder, src)) as reader:
msgs = list(reader)
with can.BLFWriter(self.test_file_name, timestamps_format="absolute") as writer:
writer.start_timestamp = reader.start_timestamp
for m in msgs:
writer.on_message_received(m)

with can.BLFReader(self.test_file_name) as verification_reader:
verification_msgs = list(verification_reader)
self.assertMessagesEqual(msgs, verification_msgs, msg="file: " + src)

def test_pre_recording_timestamp(self):
t0 = 716868000.0
msgs_absolute = [
can.Message(timestamp=t0 - 0.1, arbitration_id=0x123, data=b"\x01"),
can.Message(timestamp=t0, arbitration_id=0x456, data=b"\x02"),
can.Message(timestamp=t0 + 0.1, arbitration_id=0x789, data=b"\x03"),
]

with can.BLFWriter(self.test_file_name) as writer:
writer.start_timestamp = t0
for m in msgs_absolute:
writer.on_message_received(m)
with can.BLFReader(self.test_file_name) as reader:
print("reader.start_timestamp:", reader.start_timestamp)
resulting_msgs = list(reader)
self.assertMessagesEqual(resulting_msgs, msgs_absolute)

def test_can_error_frame_ext(self):
expected = can.Message(
timestamp=2459565876.494607,
Expand Down
18 changes: 13 additions & 5 deletions test/message_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, allowed_timestamp_delta=0.0, preserves_channel=True):
self.allowed_timestamp_delta = allowed_timestamp_delta
self.preserves_channel = preserves_channel

def assertMessageEqual(self, message_1, message_2):
def assertMessageEqual(self, message_1, message_2, msg=None):
"""
Checks that two messages are equal, according to the given rules.
"""
Expand All @@ -31,18 +31,26 @@ def assertMessageEqual(self, message_1, message_2):
check_channel=self.preserves_channel,
timestamp_delta=self.allowed_timestamp_delta,
):
fail_message = f"messages are unequal: \n{message_1}\n{message_2}"
if msg:
fail_message = f"{msg}: {fail_message}"
print(f"Assertion message: {msg}")
print(f"Comparing: message 1: {message_1!r}")
print(f" message 2: {message_2!r}")
self.fail(f"messages are unequal: \n{message_1}\n{message_2}")
self.fail(fail_message)

def assertMessagesEqual(self, messages_1, messages_2):
def assertMessagesEqual(self, messages_1, messages_2, msg=None):
"""
Checks the order and content of the individual messages pairwise.
Raises an error if the lengths of the sequences are not equal.
"""
assert_msg = "the number of messages differs"
if msg:
assert_msg = f"{assert_msg}2:2 {msg}"

self.assertEqual(
len(messages_1), len(messages_2), "the number of messages differs"
len(messages_1), len(messages_2), assert_msg
)

for message_1, message_2 in zip(messages_1, messages_2):
self.assertMessageEqual(message_1, message_2)
self.assertMessageEqual(message_1, message_2, msg=msg)