blob: 602dfcc07302906ec4dd4443532d3506867fd935 [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;
41 ConfigInTest() : config()
42 {}
43};
44
45class BufferServiceTest : public Test, public ConfigInTest, public BufferService
46{
47 public:
48 // ConfigInTest::config is initialized before BufferService.
49 BufferServiceTest() :
50 BufferService(ConfigInTest::config, dbusLoopMock, hostConsoleMock,
51 logBufferMock, fileStorageMock)
52 {}
53
54 MOCK_METHOD(void, flush, (), (override));
55 MOCK_METHOD(void, readConsole, (), (override));
56
57 protected:
58 // Set hostConsole firstly read specified data and then read nothing.
59 void setHostConsoleOnce(char const* data, size_t len)
60 {
61 EXPECT_CALL(hostConsoleMock, read(_, Le(consoleReadMaxSize)))
62 .WillOnce(DoAll(SetArrayArgument<0>(data, data + len), Return(len)))
63 .WillOnce(Return(0));
64 }
65
66 DbusLoopMock dbusLoopMock;
67 HostConsoleMock hostConsoleMock;
68 LogBufferMock logBufferMock;
69 FileStorageMock fileStorageMock;
70};
71
72TEST_F(BufferServiceTest, FlushEmptyBuffer)
73{
74 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(true));
75 EXPECT_NO_THROW(BufferService::flush());
76}
77
78TEST_F(BufferServiceTest, FlushExceptionCaught)
79{
80 InSequence sequence;
81 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
82 EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)))
83 .WillOnce(Throw(std::runtime_error("Mock error")));
84 EXPECT_NO_THROW(BufferService::flush());
85}
86
87TEST_F(BufferServiceTest, FlushOk)
88{
89 InSequence sequence;
90 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
91 EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)));
92 EXPECT_CALL(logBufferMock, clear());
93 EXPECT_NO_THROW(BufferService::flush());
94}
95
96TEST_F(BufferServiceTest, ReadConsoleExceptionCaught)
97{
98 InSequence sequence;
99 // Shouldn't read more than maximum size of a datagram.
100 EXPECT_CALL(hostConsoleMock, read(_, Le(1024)))
101 .WillOnce(Throw(std::system_error(std::error_code(), "Mock error")));
102 EXPECT_NO_THROW(BufferService::readConsole());
103}
104
105TEST_F(BufferServiceTest, ReadConsoleOk)
106{
107
108 setHostConsoleOnce(firstDatagram, strlen(firstDatagram));
109 EXPECT_CALL(logBufferMock,
110 append(StrEq(firstDatagram), Eq(strlen(firstDatagram))))
111 .WillOnce(Return());
112 EXPECT_NO_THROW(BufferService::readConsole());
113}
114
115TEST_F(BufferServiceTest, RunIoRegisterError)
116{
117 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
118 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
119 .WillOnce(Return());
120 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
121 .WillOnce(Return());
122 EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
123 .WillOnce(Throw(std::runtime_error("Mock error")));
124 EXPECT_THROW(run(), std::runtime_error);
125}
126
127TEST_F(BufferServiceTest, RunSignalRegisterError)
128{
129 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
130 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
131 .WillOnce(Throw(std::runtime_error("Mock error")));
132 EXPECT_THROW(run(), std::runtime_error);
133}
134
135TEST_F(BufferServiceTest, RunOk)
136{
137 ConfigInTest::config.bufFlushFull = true;
138 EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
139 EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
140 .WillOnce(Return());
141 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
142 .WillOnce(Return());
143 EXPECT_CALL(logBufferMock, setFullHandler(_)).WillOnce(Return());
144 EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
145 .WillOnce(Return());
146 EXPECT_CALL(dbusLoopMock,
147 addPropertyHandler(StrEq(ConfigInTest::config.hostState), _, _))
148 .WillOnce(Return());
149 EXPECT_CALL(dbusLoopMock, run).WillOnce(Return(0));
150 EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
151 EXPECT_CALL(*this, flush()).WillOnce(Return());
152 EXPECT_NO_THROW(run());
153}
154} // namespace