• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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