|  |  |  | #include "catch2/catch.hpp"
 | 
					
						
							|  |  |  | #include "system/loggerd/logger.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef cereal::Sentinel::SentinelType SentinelType;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void verify_segment(const std::string &route_path, int segment, int max_segment, int required_event_cnt) {
 | 
					
						
							|  |  |  |   const std::string segment_path = route_path + "--" + std::to_string(segment);
 | 
					
						
							|  |  |  |   SentinelType begin_sentinel = segment == 0 ? SentinelType::START_OF_ROUTE : SentinelType::START_OF_SEGMENT;
 | 
					
						
							|  |  |  |   SentinelType end_sentinel = segment == max_segment - 1 ? SentinelType::END_OF_ROUTE : SentinelType::END_OF_SEGMENT;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(!util::file_exists(segment_path + "/rlog.lock"));
 | 
					
						
							|  |  |  |   for (const char *fn : {"/rlog", "/qlog"}) {
 | 
					
						
							|  |  |  |     const std::string log_file = segment_path + fn;
 | 
					
						
							|  |  |  |     std::string log = util::read_file(log_file);
 | 
					
						
							|  |  |  |     REQUIRE(!log.empty());
 | 
					
						
							|  |  |  |     int event_cnt = 0, i = 0;
 | 
					
						
							|  |  |  |     kj::ArrayPtr<const capnp::word> words((capnp::word *)log.data(), log.size() / sizeof(capnp::word));
 | 
					
						
							|  |  |  |     while (words.size() > 0) {
 | 
					
						
							|  |  |  |       try {
 | 
					
						
							|  |  |  |         capnp::FlatArrayMessageReader reader(words);
 | 
					
						
							|  |  |  |         auto event = reader.getRoot<cereal::Event>();
 | 
					
						
							|  |  |  |         words = kj::arrayPtr(reader.getEnd(), words.end());
 | 
					
						
							|  |  |  |         if (i == 0) {
 | 
					
						
							|  |  |  |           REQUIRE(event.which() == cereal::Event::INIT_DATA);
 | 
					
						
							|  |  |  |         } else if (i == 1) {
 | 
					
						
							|  |  |  |           REQUIRE(event.which() == cereal::Event::SENTINEL);
 | 
					
						
							|  |  |  |           REQUIRE(event.getSentinel().getType() == begin_sentinel);
 | 
					
						
							|  |  |  |           REQUIRE(event.getSentinel().getSignal() == 0);
 | 
					
						
							|  |  |  |         } else if (words.size() > 0) {
 | 
					
						
							|  |  |  |           REQUIRE(event.which() == cereal::Event::CLOCKS);
 | 
					
						
							|  |  |  |           ++event_cnt;
 | 
					
						
							|  |  |  |         } else {
 | 
					
						
							|  |  |  |           // the last event must be SENTINEL
 | 
					
						
							|  |  |  |           REQUIRE(event.which() == cereal::Event::SENTINEL);
 | 
					
						
							|  |  |  |           REQUIRE(event.getSentinel().getType() == end_sentinel);
 | 
					
						
							|  |  |  |           REQUIRE(event.getSentinel().getSignal() == (end_sentinel == SentinelType::END_OF_ROUTE ? 1 : 0));
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |         ++i;
 | 
					
						
							|  |  |  |       } catch (const kj::Exception &ex) {
 | 
					
						
							|  |  |  |         INFO("failed parse " << i << " exception :" << ex.getDescription());
 | 
					
						
							|  |  |  |         REQUIRE(0);
 | 
					
						
							|  |  |  |         break;
 | 
					
						
							|  |  |  |       }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  |     REQUIRE(event_cnt == required_event_cnt);
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void write_msg(LoggerState *logger) {
 | 
					
						
							|  |  |  |   MessageBuilder msg;
 | 
					
						
							|  |  |  |   msg.initEvent().initClocks();
 | 
					
						
							|  |  |  |   logger->write(msg.toBytes(), true);
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("logger") {
 | 
					
						
							|  |  |  |   const int segment_cnt = 100;
 | 
					
						
							|  |  |  |   const std::string log_root = "/tmp/test_logger";
 | 
					
						
							|  |  |  |   system(("rm " + log_root + " -rf").c_str());
 | 
					
						
							|  |  |  |   std::string route_name;
 | 
					
						
							|  |  |  |   {
 | 
					
						
							|  |  |  |     LoggerState logger(log_root);
 | 
					
						
							|  |  |  |     route_name = logger.routeName();
 | 
					
						
							|  |  |  |     for (int i = 0; i < segment_cnt; ++i) {
 | 
					
						
							|  |  |  |       REQUIRE(logger.next());
 | 
					
						
							|  |  |  |       REQUIRE(util::file_exists(logger.segmentPath() + "/rlog.lock"));
 | 
					
						
							|  |  |  |       REQUIRE(logger.segment() == i);
 | 
					
						
							|  |  |  |       write_msg(&logger);
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  |     logger.setExitSignal(1);
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  |   for (int i = 0; i < segment_cnt; ++i) {
 | 
					
						
							|  |  |  |     verify_segment(log_root + "/" + route_name, i, segment_cnt, 1);
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  | }
 |