blob: 51b337d1100f406957bea07386332a418497185c [file] [log] [blame]
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +10001#include "common/transport.hpp"
Tom Joseph74f27c72021-05-16 07:58:53 -07002#include "mock_request.hpp"
3
George Liuc453e162022-12-21 17:16:23 +08004#include <libpldm/base.h>
5
Tom Joseph74f27c72021-05-16 07:58:53 -07006#include <sdbusplus/timer.hpp>
7#include <sdeventplus/event.hpp>
8
9#include <gmock/gmock.h>
10#include <gtest/gtest.h>
11
12using namespace pldm::requester;
13using namespace std::chrono;
14using ::testing::AtLeast;
15using ::testing::Between;
16using ::testing::Exactly;
17using ::testing::Return;
18
19class RequestIntfTest : public testing::Test
20{
21 protected:
Patrick Williams6da4f912023-05-10 07:50:53 -050022 RequestIntfTest() : event(sdeventplus::Event::get_default()) {}
Tom Joseph74f27c72021-05-16 07:58:53 -070023
24 /** @brief This function runs the sd_event_run in a loop till all the events
25 * in the testcase are dispatched and exits when there are no events
26 * for the timeout time.
27 *
28 * @param[in] timeout - maximum time to wait for an event
29 */
30 void waitEventExpiry(milliseconds timeout)
31 {
32 while (1)
33 {
34 auto sleepTime = duration_cast<microseconds>(timeout);
35 // Returns 0 on timeout
36 if (!sd_event_run(event.get(), sleepTime.count()))
37 {
38 break;
39 }
40 }
41 }
42
43 int fd = 0;
44 mctp_eid_t eid = 0;
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100045 PldmTransport* pldmTransport = nullptr;
Tom Joseph74f27c72021-05-16 07:58:53 -070046 sdeventplus::Event event;
Tom Joseph74f27c72021-05-16 07:58:53 -070047};
48
49TEST_F(RequestIntfTest, 0Retries100msTimeout)
50{
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100051 std::vector<uint8_t> requestMsg;
52 MockRequest request(pldmTransport, eid, event, std::move(requestMsg), 0,
53 milliseconds(100), false);
Tom Joseph74f27c72021-05-16 07:58:53 -070054 EXPECT_CALL(request, send())
55 .Times(Exactly(1))
56 .WillOnce(Return(PLDM_SUCCESS));
57 auto rc = request.start();
Tom Josepha5ed6582021-06-17 22:08:47 -070058 EXPECT_EQ(rc, PLDM_SUCCESS);
Tom Joseph74f27c72021-05-16 07:58:53 -070059}
60
61TEST_F(RequestIntfTest, 2Retries100msTimeout)
62{
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100063 std::vector<uint8_t> requestMsg;
64 MockRequest request(pldmTransport, eid, event, std::move(requestMsg), 2,
65 milliseconds(100), false);
Tom Joseph74f27c72021-05-16 07:58:53 -070066 // send() is called a total of 3 times, the original plus two retries
67 EXPECT_CALL(request, send()).Times(3).WillRepeatedly(Return(PLDM_SUCCESS));
68 auto rc = request.start();
Tom Josepha5ed6582021-06-17 22:08:47 -070069 EXPECT_EQ(rc, PLDM_SUCCESS);
Tom Joseph74f27c72021-05-16 07:58:53 -070070 waitEventExpiry(milliseconds(500));
71}
72
73TEST_F(RequestIntfTest, 9Retries100msTimeoutRequestStoppedAfter1sec)
74{
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100075 std::vector<uint8_t> requestMsg;
76 MockRequest request(pldmTransport, eid, event, std::move(requestMsg), 9,
77 milliseconds(100), false);
Tom Joseph74f27c72021-05-16 07:58:53 -070078 // send() will be called a total of 10 times, the original plus 9 retries.
79 // In a ideal scenario send() would have been called 10 times in 1 sec (when
80 // the timer is stopped) with a timeout of 100ms. Because there are delays
81 // in dispatch, the range is kept between 5 and 10. This recreates the
82 // situation where the Instance ID expires before the all the retries have
83 // been completed and the timer is stopped.
84 EXPECT_CALL(request, send())
85 .Times(Between(5, 10))
86 .WillRepeatedly(Return(PLDM_SUCCESS));
87 auto rc = request.start();
Tom Josepha5ed6582021-06-17 22:08:47 -070088 EXPECT_EQ(rc, PLDM_SUCCESS);
Tom Joseph74f27c72021-05-16 07:58:53 -070089
90 auto requestStopCallback = [&](void) { request.stop(); };
91 phosphor::Timer timer(event.get(), requestStopCallback);
92 timer.start(duration_cast<microseconds>(seconds(1)));
93
94 waitEventExpiry(milliseconds(500));
95}
96
97TEST_F(RequestIntfTest, 2Retries100msTimeoutsendReturnsError)
98{
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +100099 std::vector<uint8_t> requestMsg;
100 MockRequest request(pldmTransport, eid, event, std::move(requestMsg), 2,
101 milliseconds(100), false);
Tom Joseph74f27c72021-05-16 07:58:53 -0700102 EXPECT_CALL(request, send()).Times(Exactly(1)).WillOnce(Return(PLDM_ERROR));
103 auto rc = request.start();
Tom Josepha5ed6582021-06-17 22:08:47 -0700104 EXPECT_EQ(rc, PLDM_ERROR);
Tom Joseph74f27c72021-05-16 07:58:53 -0700105}