Added Unit Tests, Increased Coverage, and Fixed Compilation and I/O Issues#69
Added Unit Tests, Increased Coverage, and Fixed Compilation and I/O Issues#69ipekoke wants to merge 22 commits into
Conversation
ipekoke
commented
Aug 7, 2025
- Added unit tests for ReadoutTypes, SkiplistLatencyBufferModel and IterableQueueModel classes.
- Fixed an issue in BufferedFileWriter where excessive I/O operations were causing the run to take too long.
- Removed the explicit constructor with size parameter from IterableQueueModel, as it could not be called.
- RecorderConcept now inherits from MonitorableObject.
- Fixed a compilation error in EmptyFragmentRequestHandlerModel where the previous call to send(std::move(fragment), inherited::m_fragment_send_timeout_ms) did not compile because the send() function expects a std::chrono::milliseconds duration, not a raw integer.
- Fixed a comment in IterableQueueModel that said back() gives a pointer to the current write index when it should be the last written element.
- Lcov only includes header files that were included and declared in a .cpp file. A .cxx test file was created, with object declarations from the models directory.
- Fake classes were added in the testutils directory to be used in unit testing.
- Unit test line coverage increased from 10.01% to 36.1%. Function coverage increased from 12.8% to 27.2%.
…n and end functions
…onversion for fragment send timeout create a test app to include files to lcov
…s, increase coverage for data move callback registry
… handler model and fix fake readout type
denizergonul
left a comment
There was a problem hiding this comment.
I did the first round of my review to ask for some quick changes. I'll review more thoroughly soon.
| } | ||
| else { | ||
| //TLOG() << "Add element " << element->get_timestamp(); | ||
| TLOG() << "Add element " << element->get_timestamp(); |
There was a problem hiding this comment.
Undo uncommenting (I assume for test purposes)
| #include "datahandlinglibs/models/DefaultRequestHandlerModel.hpp" | ||
| #include "datahandlinglibs/models/TaskRawDataProcessorModel.hpp" | ||
| #include "datahandlinglibs/models/EmptyFragmentRequestHandlerModel.hpp" | ||
| //#include "daqdataformats/Fragment.hpp" // for FragmentType |
There was a problem hiding this comment.
We can remove the commented-out line.
| namespace datahandlinglibs{ | ||
| namespace unittest{ | ||
|
|
||
| using namespace dunedaq::datahandlinglibs; |
There was a problem hiding this comment.
Don't think this is necessary since you're already inside the namespace declared above.
| } | ||
| ts +=25; | ||
| rl.limit(); | ||
| //std::this_thread::sleep_for(std::chrono::milliseconds(5)); |
| } else { | ||
| TLOG() << tname << ": Didn't manage to get SKL head and tail!"; | ||
| } | ||
| std::cout << "out of if" << std::endl; |
There was a problem hiding this comment.
Remove debug logs. Stick to either std::cout or TLOG.
| //cant change request timeout so cant enter if statement? | ||
| //needs 32 seconds |
There was a problem hiding this comment.
Please remove debug logs or make them descriptive enough.
There was a problem hiding this comment.
You can also use labels like TODO: or FIXME: where appropriate.
| /** | ||
| * num_frames needs to be constexpr. | ||
| * In get_fragment_pieces there is a case where the result depends on it. | ||
| * | ||
| */ | ||
| /* | ||
| struct Changed_num_frames_FakeReadoutType : unittest::FakeReadoutType { | ||
| static constexpr size_t fixed_num_frames = 4; | ||
| size_t get_num_frames() const override {return fixed_num_frames;} | ||
| size_t get_payload_size() const override | ||
| { | ||
| return fixed_num_frames * get_frame_size(); | ||
| } | ||
|
|
||
| virtual Changed_num_frames_FakeReadoutType* begin() override{ return reinterpret_cast<Changed_num_frames_FakeReadoutType*>(data); } | ||
| virtual Changed_num_frames_FakeReadoutType* end() override { return begin() + fixed_num_frames; } | ||
|
|
||
| char data[fixed_payload_size]; | ||
| static constexpr size_t fixed_payload_size = fixed_frame_size * fixed_num_frames; | ||
| }; | ||
| BOOST_AUTO_TEST_CASE(DefaultRequestHandlerModel_issue_request_kFound_num_frames_more_than_one) | ||
| { | ||
| auto latency_buffer = std::make_shared<SkipListLatencyBufferModel<Changed_num_frames_FakeReadoutType>>(); | ||
| auto error_registry = std::make_unique<dunedaq::datahandlinglibs::FrameErrorRegistry>(); | ||
| unittest::FakeRequestHandlerType<Changed_num_frames_FakeReadoutType,SkipListLatencyBufferModel<Changed_num_frames_FakeReadoutType>> testhandler(latency_buffer, error_registry); | ||
|
|
||
| testhandler.test_start(); | ||
| for(int i = 1; i<10; i++) | ||
| { | ||
| Changed_num_frames_FakeReadoutType elem; | ||
| elem.set_timestamp(i); | ||
| TLOG()<<elem.get_num_frames()<< " " << elem.get_timestamp(); | ||
| latency_buffer->write(std::move(elem)); | ||
| } | ||
|
|
||
| BOOST_REQUIRE_EQUAL(testhandler.get_m_num_requests_found(),0); | ||
|
|
||
| testhandler.issue_request(create_request(5,2)); | ||
|
|
||
| auto start = std::chrono::steady_clock::now(); | ||
| while (testhandler.get_m_handled_requests() < 1) { | ||
| std::this_thread::sleep_for(std::chrono::milliseconds(50)); | ||
| if (std::chrono::steady_clock::now() - start > std::chrono::seconds(6)) { | ||
| BOOST_FAIL("Timeout: handler never processed the request"); | ||
| } | ||
| } | ||
| BOOST_REQUIRE_EQUAL(testhandler.get_m_handled_requests(),1); | ||
| BOOST_REQUIRE(testhandler.get_m_response_time_acc()>0); | ||
| BOOST_REQUIRE_EQUAL(testhandler.get_m_response_time_acc(),testhandler.get_m_response_time_min()); | ||
| BOOST_REQUIRE_EQUAL(testhandler.get_m_response_time_acc(),testhandler.get_m_response_time_max()); | ||
| BOOST_REQUIRE_EQUAL(testhandler.get_m_num_requests_found(),1); | ||
| } | ||
| */ No newline at end of file |
There was a problem hiding this comment.
Remove commented-out lines if there is no need for them.
| BOOST_REQUIRE(queue.write(std::move(i))); | ||
|
|
||
| BOOST_REQUIRE(queue.isFull()); | ||
| BOOST_REQUIRE(!queue.write(10)); // Attempt to write when full |
There was a problem hiding this comment.
These kind of comments combined with the name of the function are very useful. Please make sure every test has them as much as possible.
| processor.add_postprocess_task([&post_func_two_called](const ROType* /*elem*/) { post_func_two_called = true;}); | ||
| processor.make_queues(); | ||
|
|
||
| ROType* post_pro_elem = new ROType(); |
There was a problem hiding this comment.
Is it okay that we're not deleting these? If possible, we can use smart pointers instead which are less prone to user errors.
| using DefaultRequestHandlerModel<ReadoutType, LatencyBufferType>::DefaultRequestHandlerModel; | ||
|
|
||
|
|
||
| int get_m_handled_requests () const {return (this->m_handled_requests).load();} |
There was a problem hiding this comment.
Please remove the m prefix from function names.