blob: 0464bf237d5425385ab7d748511c6deb0d708e6e [file] [log] [blame]
Nan Zhou042b5ba2021-06-18 09:32:45 -07001// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2021 Google
3
4#include "buffer_service.hpp"
5#include "config.hpp"
6#include "dbus_loop_mock.hpp"
7#include "file_storage_mock.hpp"
8#include "host_console_mock.hpp"
9#include "log_buffer_mock.hpp"
10
11#include <memory>
12#include <string>
13#include <system_error>
14
15#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
18namespace
19{
20
21constexpr char firstDatagram[] = "Hello world";
22// Shouldn't read more than maximum size of a datagram.
23constexpr int consoleReadMaxSize = 1024;
24
25using ::testing::_;
26using ::testing::DoAll;
27using ::testing::Eq;
28using ::testing::InSequence;
29using ::testing::Le;
30using ::testing::Ref;
31using ::testing::Return;
32using ::testing::SetArrayArgument;
33using ::testing::StrEq;
34using ::testing::Test;
35using ::testing::Throw;
36
37// A helper class that owns config.
38struct ConfigInTest
39{
40 Config config;
Patrick Williamsb6752722023-05-10 07:50:26 -050041 ConfigInTest() : config() {}
Nan Zhou042b5ba2021-06-18 09:32:45 -070042};
43
44class BufferServiceTest : public Test, public ConfigInTest, public BufferService
45{
46 public:
47 // ConfigInTest::config is initialized before BufferService.
48 BufferServiceTest() :
49 BufferService(ConfigInTest::config, dbusLoopMock, hostConsoleMock,
50 logBufferMock, fileStorageMock)
51 {}
52
53 MOCK_METHOD(void, flush, (), (override));
54 MOCK_METHOD(void, readConsole, (), (override));
55
56 protected:
57 // Set hostConsole firstly read specified data and then read nothing.
Patrick Williamsb6752722023-05-10 07:50:26 -050058 void setHostConsoleOnce(const char* data, size_t len)
Nan Zhou042b5ba2021-06-18 09:32:45 -070059 {
60 EXPECT_CALL(hostConsoleMock, read(_, Le(consoleReadMaxSize)))
61 .WillOnce(DoAll(SetArrayArgument<0>(data, data + len), Return(len)))
62 .WillOnce(Return(0));
63 }
64
65 DbusLoopMock dbusLoopMock;
66 HostConsoleMock hostConsoleMock;
67 LogBufferMock logBufferMock;
68 FileStorageMock fileStorageMock;
69};
70
71TEST_F(BufferServiceTest, FlushEmptyBuffer)
72{
73 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(true));
74 EXPECT_NO_THROW(BufferService::flush());
75}
76
77TEST_F(BufferServiceTest, FlushExceptionCaught)
78{
79 InSequence sequence;
80 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
81 EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)))
82 .WillOnce(Throw(std::runtime_error("Mock error")));
83 EXPECT_NO_THROW(BufferService::flush());
84}
85
86TEST_F(BufferServiceTest, FlushOk)
87{
88 InSequence sequence;
89 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
90 EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)));
91 EXPECT_CALL(logBufferMock, clear());
92 EXPECT_NO_THROW(BufferService::flush());
93}
94
95TEST_F(BufferServiceTest, ReadConsoleExceptionCaught)
96{
97 InSequence sequence;
98 // Shouldn't read more than maximum size of a datagram.
99 EXPECT_CALL(hostConsoleMock, read(_, Le(1024)))
100 .WillOnce(Throw(std::system_error(std::error_code(), "Mock error")));
101 EXPECT_NO_THROW(BufferService::readConsole());
102}
103
104TEST_F(BufferServiceTest, ReadConsoleOk)
105{
Nan Zhou042b5ba2021-06-18 09:32:45 -0700106 setHostConsoleOnce(firstDatagram, strlen(firstDatagram));
107 EXPECT_CALL(logBufferMock,
108 append(StrEq(firstDatagram), Eq(strlen(firstDatagram))))
109 .WillOnce(Return());
110 EXPECT_NO_THROW(BufferService::readConsole());
111}
112
113TEST_F(BufferServiceTest, RunIoRegisterError)
114{
115 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
116 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
117 .WillOnce(Return());
118 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
119 .WillOnce(Return());
120 EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
121 .WillOnce(Throw(std::runtime_error("Mock error")));
122 EXPECT_THROW(run(), std::runtime_error);
123}
124
125TEST_F(BufferServiceTest, RunSignalRegisterError)
126{
127 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
128 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
129 .WillOnce(Throw(std::runtime_error("Mock error")));
130 EXPECT_THROW(run(), std::runtime_error);
131}
132
133TEST_F(BufferServiceTest, RunOk)
134{
135 ConfigInTest::config.bufFlushFull = true;
136 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
137 EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
138 .WillOnce(Return());
139 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
140 .WillOnce(Return());
141 EXPECT_CALL(logBufferMock, setFullHandler(_)).WillOnce(Return());
142 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
143 .WillOnce(Return());
144 EXPECT_CALL(dbusLoopMock,
145 addPropertyHandler(StrEq(ConfigInTest::config.hostState), _, _))
146 .WillOnce(Return());
147 EXPECT_CALL(dbusLoopMock, run).WillOnce(Return(0));
148 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
149 EXPECT_CALL(*this, flush()).WillOnce(Return());
150 EXPECT_NO_THROW(run());
151}
152} // namespace