Add missing nullptr check in LogReader::State constructor
This change only affects the code which uses replay filters.
We ran into the path where construction of State happens with no
timestamp_mapper while running log_replayer on single node logs.
The timestamp_mapper does not exist when there are no communications
with other nodes as no filters are needed for logfile sorting. This has been
reproduced by creating a unit test with a single node which has been blocked
of any communication with other nodes and by calling Register on the logged files.
Change-Id: Ie3e2f1742e0480339f572e474f5cb49a4f051525
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/logging/log_reader.cc b/aos/events/logging/log_reader.cc
index 36c8e8a..fa5e5d5 100644
--- a/aos/events/logging/log_reader.cc
+++ b/aos/events/logging/log_reader.cc
@@ -1333,7 +1333,8 @@
RemapConflict conflict_handling) {
if (replay_channels_ != nullptr) {
CHECK(std::find(replay_channels_->begin(), replay_channels_->end(),
- std::make_pair(std::string{name}, std::string{type})) != replay_channels_->end())
+ std::make_pair(std::string{name}, std::string{type})) !=
+ replay_channels_->end())
<< "Attempted to remap channel " << name << " " << type
<< " which is not included in the replay channels passed to LogReader.";
}
@@ -1755,7 +1756,10 @@
multinode_filters_(multinode_filters),
threading_(threading),
replay_channel_indices_(std::move(replay_channel_indices)) {
- if (replay_channel_indices_ != nullptr) {
+ // If timestamp_mapper_ is nullptr, then there are no log parts associated
+ // with this node. If there are no log parts for the node, there will be no
+ // log data, and so we do not need to worry about the replay channel filters.
+ if (replay_channel_indices_ != nullptr && timestamp_mapper_ != nullptr) {
timestamp_mapper_->set_replay_channels_callback(
[filter = replay_channel_indices_.get()](
const TimestampedMessage &message) -> bool {
diff --git a/aos/events/logging/log_reader_utils_test.cc b/aos/events/logging/log_reader_utils_test.cc
index 680b472..9977be9 100644
--- a/aos/events/logging/log_reader_utils_test.cc
+++ b/aos/events/logging/log_reader_utils_test.cc
@@ -1,6 +1,9 @@
#include "aos/events/logging/log_reader_utils.h"
#include "aos/events/logging/multinode_logger_test_lib.h"
+#include "aos/events/ping_lib.h"
+#include "aos/events/pong_lib.h"
+#include "aos/testing/tmpdir.h"
namespace aos::logger::testing {
@@ -76,4 +79,51 @@
// There no fetcher channels, check for none
ASSERT_EQ(channels.fetchers.value().size(), 0);
}
+
+// Test to run log reader with replay channels via simulated event loop
+TEST_P(MultinodeLoggerOneConfigTest, SingleNodeLogReplay) {
+ time_converter_.StartEqual();
+ std::vector<std::string> actual_filenames;
+ const std::string kLogfile1_1 =
+ aos::testing::TestTmpDir() + "/multi_logfile1/";
+ util::UnlinkRecursive(kLogfile1_1);
+
+ {
+ LoggerState pi1_logger = MakeLoggerState(
+ pi1_, &event_loop_factory_, SupportedCompressionAlgorithms()[0]);
+ pi2_->DisableStatistics();
+ pi2_->Disconnect(pi1_->node());
+ pi1_->Disconnect(pi2_->node());
+ pi1_logger.StartLogger(kLogfile1_1);
+ event_loop_factory_.RunFor(chrono::milliseconds(20000));
+ pi1_logger.AppendAllFilenames(&actual_filenames);
+ }
+
+ ReplayChannels replay_channels{{"/test", "aos.examples.Ping"}};
+ LogReader reader(logger::SortParts(actual_filenames), &config_.message(),
+ &replay_channels);
+ SimulatedEventLoopFactory log_reader_factory(reader.configuration());
+ int ping_count = 0;
+ int pong_count = 0;
+
+ // This sends out the fetched messages and advances time to the start of the
+ // log file.
+ reader.Register(&log_reader_factory);
+
+ const Node *pi1 =
+ configuration::GetNode(log_reader_factory.configuration(), "pi1");
+
+ std::unique_ptr<EventLoop> pi1_event_loop =
+ log_reader_factory.MakeEventLoop("test", pi1);
+ pi1_event_loop->MakeWatcher(
+ "/test", [&ping_count](const examples::Ping &) { ++ping_count; });
+ pi1_event_loop->MakeWatcher(
+ "/test", [&pong_count](const examples::Pong &) { ++pong_count; });
+
+ int sent_messages = 1999;
+ reader.event_loop_factory()->Run();
+ EXPECT_EQ(ping_count, sent_messages);
+ EXPECT_EQ(pong_count, 0);
+ reader.Deregister();
+}
} // namespace aos::logger::testing