1 #include "mock_request.hpp" 2 3 #include <libpldm/base.h> 4 5 #include <sdbusplus/timer.hpp> 6 #include <sdeventplus/event.hpp> 7 8 #include <gmock/gmock.h> 9 #include <gtest/gtest.h> 10 11 using namespace pldm::requester; 12 using namespace std::chrono; 13 using ::testing::AtLeast; 14 using ::testing::Between; 15 using ::testing::Exactly; 16 using ::testing::Return; 17 18 class RequestIntfTest : public testing::Test 19 { 20 protected: 21 RequestIntfTest() : event(sdeventplus::Event::get_default()) {} 22 23 /** @brief This function runs the sd_event_run in a loop till all the events 24 * in the testcase are dispatched and exits when there are no events 25 * for the timeout time. 26 * 27 * @param[in] timeout - maximum time to wait for an event 28 */ 29 void waitEventExpiry(milliseconds timeout) 30 { 31 while (1) 32 { 33 auto sleepTime = duration_cast<microseconds>(timeout); 34 // Returns 0 on timeout 35 if (!sd_event_run(event.get(), sleepTime.count())) 36 { 37 break; 38 } 39 } 40 } 41 42 int fd = 0; 43 mctp_eid_t eid = 0; 44 sdeventplus::Event event; 45 std::vector<uint8_t> requestMsg; 46 }; 47 48 TEST_F(RequestIntfTest, 0Retries100msTimeout) 49 { 50 MockRequest request(fd, eid, event, std::move(requestMsg), 0, 51 milliseconds(100), 90000, false); 52 EXPECT_CALL(request, send()) 53 .Times(Exactly(1)) 54 .WillOnce(Return(PLDM_SUCCESS)); 55 auto rc = request.start(); 56 EXPECT_EQ(rc, PLDM_SUCCESS); 57 } 58 59 TEST_F(RequestIntfTest, 2Retries100msTimeout) 60 { 61 MockRequest request(fd, eid, event, std::move(requestMsg), 2, 62 milliseconds(100), 90000, false); 63 // send() is called a total of 3 times, the original plus two retries 64 EXPECT_CALL(request, send()).Times(3).WillRepeatedly(Return(PLDM_SUCCESS)); 65 auto rc = request.start(); 66 EXPECT_EQ(rc, PLDM_SUCCESS); 67 waitEventExpiry(milliseconds(500)); 68 } 69 70 TEST_F(RequestIntfTest, 9Retries100msTimeoutRequestStoppedAfter1sec) 71 { 72 MockRequest request(fd, eid, event, std::move(requestMsg), 9, 73 milliseconds(100), 90000, false); 74 // send() will be called a total of 10 times, the original plus 9 retries. 75 // In a ideal scenario send() would have been called 10 times in 1 sec (when 76 // the timer is stopped) with a timeout of 100ms. Because there are delays 77 // in dispatch, the range is kept between 5 and 10. This recreates the 78 // situation where the Instance ID expires before the all the retries have 79 // been completed and the timer is stopped. 80 EXPECT_CALL(request, send()) 81 .Times(Between(5, 10)) 82 .WillRepeatedly(Return(PLDM_SUCCESS)); 83 auto rc = request.start(); 84 EXPECT_EQ(rc, PLDM_SUCCESS); 85 86 auto requestStopCallback = [&](void) { request.stop(); }; 87 phosphor::Timer timer(event.get(), requestStopCallback); 88 timer.start(duration_cast<microseconds>(seconds(1))); 89 90 waitEventExpiry(milliseconds(500)); 91 } 92 93 TEST_F(RequestIntfTest, 2Retries100msTimeoutsendReturnsError) 94 { 95 MockRequest request(fd, eid, event, std::move(requestMsg), 2, 96 milliseconds(100), 90000, false); 97 EXPECT_CALL(request, send()).Times(Exactly(1)).WillOnce(Return(PLDM_ERROR)); 98 auto rc = request.start(); 99 EXPECT_EQ(rc, PLDM_ERROR); 100 } 101