1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <dlfcn.h>
17 #include <gtest/gtest.h>
18 #include <sys/mman.h>
19 #include <sys/syscall.h>
20
21 #include "stack_writer.h"
22 #include "logging.h"
23
24 using namespace testing::ext;
25
26 namespace {
27 constexpr uint32_t BUFFER_SIZE = 1024;
28 constexpr uint32_t SMB_SIZE = 10 * 4096;
29 const std::string SMB_NAME = "stackwritertest";
30 const std::string PLUGIN_NAME = "stackwriter";
31 void* g_smbAddr = nullptr;
32 int g_smbFd = 0;
33
InitShareMemory()34 int InitShareMemory()
35 {
36 int fd = syscall(SYS_memfd_create, SMB_NAME.c_str(), 0);
37 CHECK_TRUE(fd >= 0, -1, "CreateBlock FAIL SYS_memfd_create");
38
39 int check = ftruncate(fd, SMB_SIZE);
40 if (check < 0) {
41 close(fd);
42 const int bufSize = 256;
43 char buf[bufSize] = { 0 };
44 strerror_r(errno, buf, bufSize);
45 PROFILER_LOG_ERROR(LOG_CORE, "CreateBlock ftruncate ERR : %s", buf);
46 return -1;
47 }
48
49 g_smbAddr = mmap(nullptr, SMB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
50 if (g_smbAddr == (reinterpret_cast<void *>(-1))) {
51 close(fd);
52 const int bufSize = 256;
53 char buf[bufSize] = { 0 };
54 strerror_r(errno, buf, bufSize);
55 PROFILER_LOG_ERROR(LOG_CORE, "CreateBlock g_smbAddr mmap ERR : %s", buf);
56 return -1;
57 }
58
59 ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr);
60
61 // initialize header infos
62 header_->info.readOffset_ = 0;
63 header_->info.writeOffset_ = 0;
64 header_->info.memorySize_ = SMB_SIZE - sizeof(ShareMemoryBlock::BlockHeader);
65 header_->info.bytesCount_ = 0;
66 header_->info.chunkCount_ = 0;
67
68 return fd;
69 }
70
71 class StackWriterTest : public ::testing::Test {
72 public:
SetUpTestCase()73 static void SetUpTestCase() {}
TearDownTestCase()74 static void TearDownTestCase() {}
75
SetUp()76 void SetUp()
77 {
78 g_smbFd = InitShareMemory();
79 }
TearDown()80 void TearDown()
81 {
82 g_smbFd = 0;
83 }
84 };
85
CheckBuffer(uint8_t * buffer,size_t size)86 bool CheckBuffer(uint8_t* buffer, size_t size)
87 {
88 ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr);
89 uint8_t* cmpaddr = (uint8_t*)g_smbAddr + sizeof(ShareMemoryBlock::BlockHeader) + header_->info.readOffset_;
90 cmpaddr = cmpaddr + sizeof(uint32_t);
91
92 header_->info.readOffset_ = header_->info.writeOffset_.load();
93 if (memcmp(buffer, cmpaddr, size) == 0) {
94 return true;
95 }
96 return false;
97 }
98
RandData(uint8_t * data,int size)99 void RandData(uint8_t* data, int size)
100 {
101 time_t tv = time(nullptr);
102 if (tv == -1) {
103 tv = 1;
104 }
105 unsigned int seed = (unsigned int)tv;
106 while (--size) {
107 data[size] = rand_r(&seed) / (uint8_t)(-1);
108 }
109 }
110
111 /**
112 * @tc.name: StackWriter
113 * @tc.desc: Write data to shared memory through writer.
114 * @tc.type: FUNC
115 */
116 HWTEST_F(StackWriterTest, WriteaNormalTest, TestSize.Level1)
117 {
118 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1);
119 EXPECT_NE(write->shareMemoryBlock_, nullptr);
120 uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
121 uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
122 uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
123
124 EXPECT_TRUE(write->Write((const void*)buffer1, sizeof(buffer1)));
125 EXPECT_TRUE(CheckBuffer(buffer1, sizeof(buffer1)));
126 EXPECT_TRUE(write->Write((const void*)buffer2, sizeof(buffer2)));
127 EXPECT_TRUE(CheckBuffer(buffer2, sizeof(buffer2)));
128 EXPECT_TRUE(write->Write((const void*)buffer3, sizeof(buffer3)));
129 EXPECT_TRUE(CheckBuffer(buffer3, sizeof(buffer3)));
130
131 EXPECT_FALSE(write->Write((const void*)buffer3, 0));
132 EXPECT_FALSE(write->Write(nullptr, 0));
133 }
134
135 /**
136 * @tc.name: StackWriter
137 * @tc.desc: Write failure process.
138 * @tc.type: FUNC
139 */
140 HWTEST_F(StackWriterTest, WriteaFalseTest, TestSize.Level1)
141 {
142 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, 0, -1);
143 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
144 uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
145 uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
146 uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
147
148 EXPECT_FALSE(write->Write((const void*)buffer1, sizeof(buffer1)));
149 EXPECT_FALSE(CheckBuffer(buffer1, sizeof(buffer1)));
150 EXPECT_FALSE(write->Write((const void*)buffer2, sizeof(buffer2)));
151 EXPECT_FALSE(CheckBuffer(buffer2, sizeof(buffer2)));
152 EXPECT_FALSE(write->Write((const void*)buffer3, sizeof(buffer3)));
153 EXPECT_FALSE(CheckBuffer(buffer3, sizeof(buffer3)));
154
155 EXPECT_FALSE(write->Write((const void*)buffer3, 0));
156 EXPECT_FALSE(write->Write(nullptr, 0));
157 }
158
159 /**
160 * @tc.name: StackWriter
161 * @tc.desc: Write data to shared memory through writer.
162 * @tc.type: FUNC
163 */
164 HWTEST_F(StackWriterTest, WriteProcessTest, TestSize.Level1)
165 {
166 uint8_t data[BUFFER_SIZE];
167 RandData(data, BUFFER_SIZE);
168 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1);
169 EXPECT_NE(write->shareMemoryBlock_, nullptr);
170 long bytes = BUFFER_SIZE;
171
172 EXPECT_GT(write->Write((const void*)data, sizeof(data)), 0);
173 EXPECT_TRUE(CheckBuffer(data, BUFFER_SIZE));
174 EXPECT_TRUE(write->Flush());
175 write->DoStats(bytes);
176 write->Report();
177
178 EXPECT_EQ((int)write->bytesCount_, bytes);
179 EXPECT_EQ((int)write->bytesPending_, bytes);
180 EXPECT_EQ((int)write->writeCount_, 1);
181 EXPECT_EQ((int)write->flushCount_, 1);
182
183 EXPECT_TRUE(write->Flush());
184 write->DoStats(bytes);
185 write->Report();
186
187 EXPECT_EQ((int)write->bytesCount_, bytes + bytes);
188 EXPECT_EQ((int)write->bytesPending_, bytes);
189 EXPECT_EQ((int)write->writeCount_, 2);
190 EXPECT_EQ((int)write->flushCount_, 2);
191 }
192
193 /**
194 * @tc.name: StackWriter
195 * @tc.desc: Write data to shared memory with blocked mode.
196 * @tc.type: FUNC
197 */
198 HWTEST_F(StackWriterTest, WriterSyncTest, TestSize.Level1)
199 {
200 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1, true);
201 EXPECT_NE(write->shareMemoryBlock_, nullptr);
202 uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
203 uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
204 uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
205 uint8_t buffer4[] = {0xCC, 0xDD, 0xBB, 0xEE};
206
207 EXPECT_FALSE(write->WriteWithPayloadTimeout(nullptr, 0, nullptr, 0, nullptr));
208 EXPECT_TRUE(write->WriteWithPayloadTimeout((const void*)buffer1, sizeof(buffer1),
209 (const void*)buffer2, sizeof(buffer2), nullptr));
210 EXPECT_TRUE(CheckBuffer(buffer1, sizeof(buffer1)));
211 write->blocked_ = false;
212 EXPECT_TRUE(write->WriteWithPayloadTimeout((const void*)buffer3, sizeof(buffer3),
213 (const void*)buffer4, sizeof(buffer4), nullptr));
214 EXPECT_TRUE(CheckBuffer(buffer3, sizeof(buffer3)));
215 EXPECT_FALSE(write->Write(nullptr, 0));
216 EXPECT_FALSE(write->WriteWithPayloadTimeout((const void*)buffer3, 0, nullptr, 0, nullptr));
217 EXPECT_FALSE(write->WriteWithPayloadTimeout(nullptr, 0, nullptr, 0, nullptr));
218 }
219
220 /**
221 * @tc.name: WriteWithPayloadTimeout
222 * @tc.desc: test WriteWithPayloadTimeout with normal case.
223 * @tc.type: FUNC
224 */
225 HWTEST_F(StackWriterTest, WriteWithPayloadTimeoutNormalTest, TestSize.Level1)
226 {
227 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1, false);
228 EXPECT_NE(write->shareMemoryBlock_, nullptr);
229
230 uint8_t buffer[] = {0xCC, 0xDD, 0xBB, 0xEE};
231 EXPECT_TRUE(write->WriteWithPayloadTimeout((const void*)buffer, sizeof(buffer),
232 (const void*)buffer, sizeof(buffer), nullptr));
233 EXPECT_TRUE(CheckBuffer(buffer, sizeof(buffer)));
234 }
235
236 /**
237 * @tc.name: WriteWithPayloadTimeout
238 * @tc.desc: test WriteWithPayloadTimeout with false case.
239 * @tc.type: FUNC
240 */
241 HWTEST_F(StackWriterTest, WriteWithPayloadTimeoutFalseTest, TestSize.Level1)
242 {
243 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, 0, -1, true);
244 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
245
246 uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD};
247 EXPECT_FALSE(write->WriteWithPayloadTimeout((const void*)buffer, sizeof(buffer),
248 (const void*)buffer, sizeof(buffer), nullptr));
249 EXPECT_FALSE(CheckBuffer(buffer, sizeof(buffer)));
250 EXPECT_FALSE(write->WriteWithPayloadTimeout((const void*)buffer, 0, nullptr, 0, nullptr));
251 EXPECT_FALSE(write->WriteWithPayloadTimeout(nullptr, 0, nullptr, 0, nullptr));
252 }
253
254 /**
255 * @tc.name: WriteTimeout
256 * @tc.desc: Write data to shared memory through writer.
257 * @tc.type: FUNC
258 */
259 HWTEST_F(StackWriterTest, WriteTimeoutNormalTest, TestSize.Level1)
260 {
261 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1);
262 EXPECT_NE(write->shareMemoryBlock_, nullptr);
263
264 uint8_t buffer[] = {0x55, 0xAA, 0x55, 0xAA};
265 EXPECT_TRUE(write->WriteTimeout((const void*)buffer, sizeof(buffer)));
266 EXPECT_TRUE(CheckBuffer(buffer, sizeof(buffer)));
267 EXPECT_FALSE(write->WriteTimeout((const void*)buffer, 0));
268 EXPECT_FALSE(write->WriteTimeout(nullptr, 0));
269 }
270
271 /**
272 * @tc.name: WriteTimeout
273 * @tc.desc: WriteTimeout failure test.
274 * @tc.type: FUNC
275 */
276 HWTEST_F(StackWriterTest, WriteTimeoutFalseTest, TestSize.Level1)
277 {
278 auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, 0, -1);
279 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
280
281 uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD};
282 EXPECT_FALSE(write->WriteTimeout((const void*)buffer, sizeof(buffer)));
283 EXPECT_FALSE(CheckBuffer(buffer, sizeof(buffer)));
284 EXPECT_FALSE(write->WriteTimeout((const void*)buffer, 0));
285 EXPECT_FALSE(write->WriteTimeout(nullptr, 0));
286 }
287
288 /**
289 * @tc.name: StackWriter
290 * @tc.desc: StackWriter failure test.
291 * @tc.type: FUNC
292 */
293 HWTEST_F(StackWriterTest, StackWriterFalseTest, TestSize.Level1)
294 {
295 auto write = std::make_shared<StackWriter>("", SMB_SIZE, 0, -1);
296 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
297
298 write = std::make_shared<StackWriter>(PLUGIN_NAME, 0, 0, -1);
299 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
300
301 write = std::make_shared<StackWriter>("", 0, 0, -1);
302 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
303
304 write = std::make_shared<StackWriter>("", SMB_SIZE, 0, -1, true);
305 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
306
307 write = std::make_shared<StackWriter>(PLUGIN_NAME, 0, 0, -1, true);
308 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
309
310 write = std::make_shared<StackWriter>("", 0, 0, -1, true);
311 EXPECT_EQ(write->shareMemoryBlock_, nullptr);
312 }
313 } // namespace