• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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 <hwext/gtest-ext.h>
18 #include <hwext/gtest-tag.h>
19 #include <sys/mman.h>
20 #include <sys/syscall.h>
21 
22 #include "stack_writer.h"
23 #include "logging.h"
24 
25 using namespace testing::ext;
26 
27 namespace {
28 constexpr uint32_t BUFFER_SIZE = 1024;
29 constexpr uint32_t SMB_SIZE = 10 * 4096;
30 const std::string SMB_NAME = "stackwritertest";
31 const std::string PLUGIN_NAME = "stackwriter";
32 void* g_smbAddr = nullptr;
33 int g_smbFd = 0;
34 
InitShareMemory()35 int InitShareMemory()
36 {
37     int fd = syscall(SYS_memfd_create, SMB_NAME.c_str(), 0);
38     CHECK_TRUE(fd >= 0, -1, "CreateBlock FAIL SYS_memfd_create");
39 
40     int check = ftruncate(fd, SMB_SIZE);
41     if (check < 0) {
42         close(fd);
43         const int bufSize = 256;
44         char buf[bufSize] = { 0 };
45         strerror_r(errno, buf, bufSize);
46         HILOG_ERROR(LOG_CORE, "CreateBlock ftruncate ERR : %s", buf);
47         return -1;
48     }
49 
50     g_smbAddr = mmap(nullptr, SMB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
51     if (g_smbAddr == (reinterpret_cast<void *>(-1))) {
52         close(fd);
53         const int bufSize = 256;
54         char buf[bufSize] = { 0 };
55         strerror_r(errno, buf, bufSize);
56         HILOG_ERROR(LOG_CORE, "CreateBlock g_smbAddr mmap ERR : %s", buf);
57         return -1;
58     }
59 
60     ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr);
61 
62     // initialize header infos
63     header_->info.readOffset_ = 0;
64     header_->info.writeOffset_ = 0;
65     header_->info.memorySize_ = SMB_SIZE - sizeof(ShareMemoryBlock::BlockHeader);
66     header_->info.bytesCount_ = 0;
67     header_->info.chunkCount_ = 0;
68 
69     return fd;
70 }
71 
72 class StackWriterTest : public ::testing::Test {
73 public:
SetUpTestCase()74     static void SetUpTestCase() {}
TearDownTestCase()75     static void TearDownTestCase() {}
76 
SetUp()77     void SetUp()
78     {
79         g_smbFd = InitShareMemory();
80     }
TearDown()81     void TearDown()
82     {
83         g_smbFd = 0;
84     }
85 };
86 
CheckBuffer(uint8_t * buffer,size_t size)87 bool CheckBuffer(uint8_t* buffer, size_t size)
88 {
89     ShareMemoryBlock::BlockHeader* header_ = reinterpret_cast<ShareMemoryBlock::BlockHeader*>(g_smbAddr);
90     uint8_t* cmpaddr = (uint8_t*)g_smbAddr + sizeof(ShareMemoryBlock::BlockHeader) + header_->info.readOffset_;
91     cmpaddr = cmpaddr + sizeof(uint32_t);
92 
93     header_->info.readOffset_ = header_->info.writeOffset_;
94     if (memcmp(buffer, cmpaddr, size) == 0) {
95         return true;
96     }
97     return false;
98 }
99 
RandData(uint8_t * data,int size)100 void RandData(uint8_t* data, int size)
101 {
102     time_t tv = time(nullptr);
103     if (tv == -1) {
104         tv = 1;
105     }
106     unsigned int seed = (unsigned int)tv;
107     while (--size) {
108         data[size] = rand_r(&seed) / (uint8_t)(-1);
109     }
110 }
111 
112 /**
113  * @tc.name: StackWriter
114  * @tc.desc: Write data to shared memory through writer.
115  * @tc.type: FUNC
116  */
117 HWTEST_F(StackWriterTest, WriteaNormalTest, TestSize.Level1)
118 {
119     auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1);
120     EXPECT_NE(write->shareMemoryBlock_, nullptr);
121     uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
122     uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
123     uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
124 
125     EXPECT_TRUE(write->Write((const void*)buffer1, sizeof(buffer1)));
126     EXPECT_TRUE(CheckBuffer(buffer1, sizeof(buffer1)));
127     EXPECT_TRUE(write->Write((const void*)buffer2, sizeof(buffer2)));
128     EXPECT_TRUE(CheckBuffer(buffer2, sizeof(buffer2)));
129     EXPECT_TRUE(write->Write((const void*)buffer3, sizeof(buffer3)));
130     EXPECT_TRUE(CheckBuffer(buffer3, sizeof(buffer3)));
131 
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(nullptr, 0));
156 }
157 
158 /**
159  * @tc.name: StackWriter
160  * @tc.desc: Write data to shared memory through writer.
161  * @tc.type: FUNC
162  */
163 HWTEST_F(StackWriterTest, WriteProcessTest, TestSize.Level1)
164 {
165     uint8_t data[BUFFER_SIZE];
166     RandData(data, BUFFER_SIZE);
167     auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1);
168     EXPECT_NE(write->shareMemoryBlock_, nullptr);
169     long bytes = BUFFER_SIZE;
170 
171     EXPECT_GT(write->Write((const void*)data, sizeof(data)), 0);
172     EXPECT_TRUE(CheckBuffer(data, BUFFER_SIZE));
173     EXPECT_TRUE(write->Flush());
174     write->DoStats(bytes);
175     write->Report();
176 
177     EXPECT_EQ((int)write->bytesCount_, bytes);
178     EXPECT_EQ((int)write->bytesPending_, bytes);
179     EXPECT_EQ((int)write->writeCount_, 1);
180     EXPECT_EQ((int)write->flushCount_, 1);
181 
182     EXPECT_TRUE(write->Flush());
183     write->DoStats(bytes);
184     write->Report();
185 
186     EXPECT_EQ((int)write->bytesCount_, bytes + bytes);
187     EXPECT_EQ((int)write->bytesPending_, bytes);
188     EXPECT_EQ((int)write->writeCount_, 2);
189     EXPECT_EQ((int)write->flushCount_, 2);
190 }
191 
192 /**
193  * @tc.name: StackWriter
194  * @tc.desc: Write data to shared memory with blocked mode.
195  * @tc.type: FUNC
196  */
197 HWTEST_F(StackWriterTest, WriterSyncTest, TestSize.Level1)
198 {
199     auto write = std::make_shared<StackWriter>(PLUGIN_NAME, SMB_SIZE, g_smbFd, -1, true);
200     EXPECT_NE(write->shareMemoryBlock_, nullptr);
201     uint8_t buffer1[] = {0x55, 0xAA, 0x55, 0xAA};
202     uint8_t buffer2[] = {0x11, 0x22, 0x33, 0x44};
203     uint8_t buffer3[] = {0xAA, 0xBB, 0xCC, 0xDD};
204     uint8_t buffer4[] = {0xCC, 0xDD, 0xBB, 0xEE};
205 
206     EXPECT_TRUE(write->WriteWithPayloadTimeout((const void*)buffer1, sizeof(buffer1),
207         (const void*)buffer2, sizeof(buffer2)));
208     EXPECT_TRUE(CheckBuffer(buffer1, sizeof(buffer1)));
209     EXPECT_TRUE(write->WriteWithPayloadTimeout((const void*)buffer3, sizeof(buffer3),
210         (const void*)buffer4, sizeof(buffer4)));
211     EXPECT_TRUE(CheckBuffer(buffer3, sizeof(buffer3)));
212     EXPECT_FALSE(write->Write(nullptr, 0));
213 }
214 } // namespace
215