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 #include <memory>
16 #include <gtest/gtest.h>
17 #include "buffer_splitter.h"
18 
19 using namespace testing::ext;
20 
21 using ConstCharPtr = std::unique_ptr<const char>::pointer;
22 
23 namespace {
24 class BufferSplitterUnittest : public ::testing::Test {
25 public:
SetUpTestCase()26     static void SetUpTestCase() {}
27 
TearDownTestCase()28     static void TearDownTestCase() {}
SetUp()29     void SetUp() {}
TearDown()30     void TearDown() {}
31 };
32 
33 struct TestElement {
34     int32_t index;
35     ConstCharPtr curLine;
36     size_t curLineSz;
37     ConstCharPtr curWord;
38     size_t curWordSz;
39 };
40 
41 /**
42  * @tc.name: memory plugin
43  * @tc.desc: Constructed function test.
44  * @tc.type: FUNC
45  */
HWTEST_F(BufferSplitterUnittest, constructorWithNullptr, TestSize.Level1)46 HWTEST_F(BufferSplitterUnittest, constructorWithNullptr, TestSize.Level1)
47 {
48     char* text = nullptr;
49     int readsize = 0;
50     BufferSplitter totalbuffer(text, readsize);
51     EXPECT_EQ(nullptr, totalbuffer.CurLine());
52     EXPECT_EQ((size_t)0, totalbuffer.CurLineSize());
53     EXPECT_EQ(nullptr, totalbuffer.CurWord());
54     EXPECT_EQ((size_t)0, totalbuffer.CurWordSize());
55 }
56 
57 /**
58  * @tc.name: memory plugin
59  * @tc.desc: Constructed function test.
60  * @tc.type: FUNC
61  */
HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer01, TestSize.Level1)62 HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer01, TestSize.Level1)
63 {
64     char text[] = {'\0'};
65     int readsize = sizeof(text);
66     BufferSplitter totalbuffer(text, readsize);
67     EXPECT_EQ(nullptr, totalbuffer.CurLine());
68     EXPECT_EQ((size_t)0, totalbuffer.CurLineSize());
69     EXPECT_EQ(nullptr, totalbuffer.CurWord());
70     EXPECT_EQ((size_t)0, totalbuffer.CurWordSize());
71 }
72 
73 /**
74  * @tc.name: memory plugin
75  * @tc.desc: Constructed function test.
76  * @tc.type: FUNC
77  */
HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer02, TestSize.Level1)78 HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer02, TestSize.Level1)
79 {
80     char text[] = {'\n'};
81     int readsize = sizeof(text);
82     BufferSplitter totalbuffer(text, readsize);
83     EXPECT_EQ(nullptr, totalbuffer.CurLine());
84     EXPECT_EQ((size_t)0, totalbuffer.CurLineSize());
85     EXPECT_EQ(nullptr, totalbuffer.CurWord());
86     EXPECT_EQ((size_t)0, totalbuffer.CurWordSize());
87 }
88 
89 /**
90  * @tc.name: memory plugin
91  * @tc.desc: Constructed function test.
92  * @tc.type: FUNC
93  */
HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer03, TestSize.Level1)94 HWTEST_F(BufferSplitterUnittest, constructorWith1lengthBuffer03, TestSize.Level1)
95 {
96     char text[] = {'3'};
97     int readsize = sizeof(text);
98     BufferSplitter totalbuffer(text, readsize);
99     EXPECT_EQ(nullptr, totalbuffer.CurLine());
100     EXPECT_EQ((size_t)0, totalbuffer.CurLineSize());
101     EXPECT_EQ(nullptr, totalbuffer.CurWord());
102     EXPECT_EQ((size_t)0, totalbuffer.CurWordSize());
103 }
104 
105 /**
106  * @tc.name: memory plugin
107  * @tc.desc: Constructed function test.
108  * @tc.type: FUNC
109  */
HWTEST_F(BufferSplitterUnittest, constructorWith1LineBuffer, TestSize.Level1)110 HWTEST_F(BufferSplitterUnittest, constructorWith1LineBuffer, TestSize.Level1)
111 {
112     char text[] = {'a', 'b', 'c', 'd', '\0'};
113     int readsize = sizeof(text);
114     BufferSplitter totalbuffer(text, readsize);
115 
116     TestElement expect = {0, text, 4, nullptr, 0};
117     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
118     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
119     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
120     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
121 }
122 
123 /**
124  * @tc.name: memory plugin
125  * @tc.desc: Constructed function test.
126  * @tc.type: FUNC
127  */
HWTEST_F(BufferSplitterUnittest, constructorWithMultipleLinesBuffer, TestSize.Level1)128 HWTEST_F(BufferSplitterUnittest, constructorWithMultipleLinesBuffer, TestSize.Level1)
129 {
130     char text[] = {'a', 'b', 'c', 'd', '\n', '1', '2', '3', '4', '5', '\0'};
131     TestElement expect = {0, text, 4, nullptr, 0};
132     int readsize = sizeof(text);
133     BufferSplitter totalbuffer(text, readsize);
134 
135     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
136     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
137     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
138     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
139 }
140 
141 /**
142  * @tc.name: memory plugin
143  * @tc.desc: Test NextLine().
144  * @tc.type: FUNC
145  */
HWTEST_F(BufferSplitterUnittest, NextLineWithOnlyOneLineBuffer, TestSize.Level1)146 HWTEST_F(BufferSplitterUnittest, NextLineWithOnlyOneLineBuffer, TestSize.Level1)
147 {
148     char text[] = {'a', 'b', 'c', 'd', '\0'};
149     TestElement expect = {0, text, 4, nullptr, 0};
150     int readsize = sizeof(text);
151     BufferSplitter totalbuffer(text, readsize);
152 
153     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
154     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
155     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
156     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
157 
158     EXPECT_FALSE(totalbuffer.NextLine());
159     EXPECT_EQ(nullptr, totalbuffer.CurLine());
160     EXPECT_EQ((size_t)0, totalbuffer.CurLineSize());
161 }
162 
163 /**
164  * @tc.name: memory plugin
165  * @tc.desc: Test NextLine().
166  * @tc.type: FUNC
167  */
HWTEST_F(BufferSplitterUnittest, NextLineWithMultipleLinesBuffer, TestSize.Level1)168 HWTEST_F(BufferSplitterUnittest, NextLineWithMultipleLinesBuffer, TestSize.Level1)
169 {
170     char text[] = {'a', 'b', 'c', 'd', '\n', '1', '2', '3', '4', '5', '6', '\0'};
171     TestElement expect[] = {{0, text, 4, nullptr, 0}, {5, &text[5], 6, nullptr, 0}};
172     int readsize = sizeof(text);
173     BufferSplitter totalbuffer(text, readsize);
174 
175     size_t i = 0;
176     do {
177         EXPECT_EQ(expect[i].curLine, totalbuffer.CurLine());
178         EXPECT_EQ(expect[i].curLineSz, totalbuffer.CurLineSize());
179         EXPECT_EQ(expect[i].curWord, totalbuffer.CurWord());
180         EXPECT_EQ(expect[i].curWordSz, totalbuffer.CurWordSize());
181         i++;
182     } while (totalbuffer.NextLine());
183 }
184 
185 /**
186  * @tc.name: memory plugin
187  * @tc.desc: Test NextWord().
188  * @tc.type: FUNC
189  */
HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer01, TestSize.Level1)190 HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer01, TestSize.Level1)
191 {
192     char text[] = {'a', 'b', ' ', 'c', 'd', '\0'};
193     TestElement expect = {0, text, 5, text, 2};
194     int readsize = sizeof(text);
195     BufferSplitter totalbuffer(text, readsize);
196 
197     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
198     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
199     EXPECT_TRUE(totalbuffer.NextWord(' '));
200     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
201     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
202 }
203 
204 /**
205  * @tc.name: memory plugin
206  * @tc.desc: Test NextWord().
207  * @tc.type: FUNC
208  */
HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer02, TestSize.Level1)209 HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer02, TestSize.Level1)
210 {
211     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\0'};
212     TestElement expect[] = {{0, text, 6, text, 2}, {0, text, 4, &text[3], 2}};
213     int readsize = sizeof(text);
214     BufferSplitter totalbuffer(text, readsize);
215 
216     EXPECT_EQ(expect[0].curLine, totalbuffer.CurLine());
217     EXPECT_EQ(expect[0].curLineSz, totalbuffer.CurLineSize());
218     size_t cnt = sizeof(expect) / sizeof(expect[0]);
219     for (size_t i = 0; i < cnt; i++) {
220         EXPECT_TRUE(totalbuffer.NextWord(' '));
221         EXPECT_EQ(expect[i].curWord, totalbuffer.CurWord());
222         EXPECT_EQ(expect[i].curWordSz, totalbuffer.CurWordSize());
223     }
224 }
225 
226 /**
227  * @tc.name: memory plugin
228  * @tc.desc: Test NextWord().
229  * @tc.type: FUNC
230  */
HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer03, TestSize.Level1)231 HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer03, TestSize.Level1)
232 {
233     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\0'};
234     TestElement expect = {0, text, 6, text, 6};
235     int readsize = sizeof(text);
236     BufferSplitter totalbuffer(text, readsize);
237 
238     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
239     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
240     EXPECT_TRUE(totalbuffer.NextWord('\0'));
241     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
242     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
243 }
244 
245 /**
246  * @tc.name: memory plugin
247  * @tc.desc: Test NextWord().
248  * @tc.type: FUNC
249  */
HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer04, TestSize.Level1)250 HWTEST_F(BufferSplitterUnittest, NextWordWithOnlyOneLineBuffer04, TestSize.Level1)
251 {
252     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\0'};
253     TestElement expect = {0, text, 6, nullptr, 0};
254     int readsize = sizeof(text);
255     BufferSplitter totalbuffer(text, readsize);
256 
257     EXPECT_EQ(expect.curLine, totalbuffer.CurLine());
258     EXPECT_EQ(expect.curLineSz, totalbuffer.CurLineSize());
259     EXPECT_FALSE(totalbuffer.NextWord('e'));
260     EXPECT_EQ(expect.curWord, totalbuffer.CurWord());
261     EXPECT_EQ(expect.curWordSz, totalbuffer.CurWordSize());
262 }
263 
264 /**
265  * @tc.name: memory plugin
266  * @tc.desc: Test NextWord().
267  * @tc.type: FUNC
268  */
HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer01, TestSize.Level1)269 HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer01, TestSize.Level1)
270 {
271     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\n', '1', '2', ' ', '3', '4', '5', ' ', '6', '\0'};
272     TestElement expect[] = {
273         {0, text, 6, text, 2}, {0, text, 6, &text[3], 2}, {0, text, 6, &text[7], 2}, {0, text, 4, &text[10], 3}};
274     int readsize = sizeof(text);
275     BufferSplitter totalbuffer(text, readsize);
276     size_t expectWordCnt = 2;
277     size_t curLineCnt = 0;
278     do {
279         for (size_t i = 0; i < expectWordCnt; i++) {
280             EXPECT_TRUE(totalbuffer.NextWord(' '));
281             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWord, totalbuffer.CurWord());
282             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWordSz, totalbuffer.CurWordSize());
283         }
284         curLineCnt++;
285     } while (totalbuffer.NextLine());
286 }
287 
288 /**
289  * @tc.name: memory plugin
290  * @tc.desc: Test NextWord().
291  * @tc.type: FUNC
292  */
HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer02, TestSize.Level1)293 HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer02, TestSize.Level1)
294 {
295     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\n', '1', '2', ' ', '3', '4', '5', ' ', '6', '\0'};
296     TestElement expect[] = {
297         {0, text, 6, text, 2}, {0, text, 6, nullptr, 0}, {0, text, 6, &text[7], 2}, {0, text, 4, nullptr, 0}};
298     int readsize = sizeof(text);
299     BufferSplitter totalbuffer(text, readsize);
300     size_t expectWordCnt = 2;
301     size_t curLineCnt = 0;
302     do {
303         for (size_t i = 0; i < expectWordCnt; i++) {
304             if (i == 0) {
305                 EXPECT_TRUE(totalbuffer.NextWord(' '));
306             }
307             if (i == 1) {
308                 EXPECT_FALSE(totalbuffer.NextWord('#'));
309             }
310             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWord, totalbuffer.CurWord());
311             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWordSz, totalbuffer.CurWordSize());
312         }
313         curLineCnt++;
314     } while (totalbuffer.NextLine());
315 }
316 
317 /**
318  * @tc.name: memory plugin
319  * @tc.desc: Test NextWord().
320  * @tc.type: FUNC
321  */
HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer03, TestSize.Level1)322 HWTEST_F(BufferSplitterUnittest, NextWordWithMultipleLinesBuffer03, TestSize.Level1)
323 {
324     char text[] = {'a', 'b', ' ', 'c', 'd', ' ', '\n', '1', '2', ' ', '3', '4', '5', ' ', '6', '\0'};
325     TestElement expect[] = {
326         {0, text, 6, nullptr, 0}, {0, text, 6, text, 2}, {0, text, 6, nullptr, 0}, {0, text, 6, &text[7], 2}};
327     int readsize = sizeof(text);
328     BufferSplitter totalbuffer(text, readsize);
329     size_t expectWordCnt = 2;
330     size_t curLineCnt = 0;
331     do {
332         for (size_t i = 0; i < expectWordCnt; i++) {
333             if (i == 0) {
334                 EXPECT_FALSE(totalbuffer.NextWord('#'));
335             }
336             if (i == 1) {
337                 EXPECT_TRUE(totalbuffer.NextWord(' '));
338             }
339             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWord, totalbuffer.CurWord());
340             EXPECT_EQ(expect[(curLineCnt * 2) + i].curWordSz, totalbuffer.CurWordSize());
341         }
342         curLineCnt++;
343     } while (totalbuffer.NextLine());
344 }
345 
346 /**
347  * @tc.name: memory plugin
348  * @tc.desc: Test the scene that actually used,parse /proc/meminfo.
349  * @tc.type: FUNC
350  */
351 namespace {
352 char g_kMockMeminfo[] = R"(
353 MemTotal:       16168736 kB
354 MemFree:         7154492 kB
355 MemAvailable:   15481028 kB
356 Buffers:         2397540 kB
357 Cached:          4711136 kB
358 SwapCached:        27628 kB
359 Active:          5556068 kB
360 Inactive:        1644560 kB
361 Active(anon):      62580 kB
362 Inactive(anon):    43352 kB
363 Active(file):    5493488 kB
364 Inactive(file):  1601208 kB
365 Unevictable:         388 kB
366 Mlocked:               0 kB
367 SwapTotal:      16777180 kB
368 SwapFree:       16500700 kB
369 Dirty:                 0 kB
370 Writeback:             0 kB
371 AnonPages:         87672 kB
372 Mapped:           116988 kB
373 Shmem:             13980 kB
374 KReclaimable:    1568904 kB
375 Slab:            1641176 kB
376 SReclaimable:    1568904 kB
377 SUnreclaim:        72272 kB
378 KernelStack:        7008 kB
379 PageTables:        28244 kB
380 NFS_Unstable:          0 kB
381 Bounce:                0 kB
382 WritebackTmp:          0 kB
383 CommitLimit:    24861548 kB
384 Committed_AS:    2569488 kB
385 VmallocTotal:   34359738367 kB
386 VmallocUsed:       34260 kB
387 VmallocChunk:          0 kB
388 Percpu:             2912 kB
389 HardwareCorrupted:     0 kB
390 AnonHugePages:         0 kB
391 ShmemHugePages:        0 kB
392 ShmemPmdMapped:        0 kB
393 FileHugePages:         0 kB
394 FilePmdMapped:         0 kB
395 CmaTotal:              0 kB
396 CmaFree:               0 kB
397 HugePages_Total:       0
398 HugePages_Free:        0
399 HugePages_Rsvd:        0
400 HugePages_Surp:        0
401 Hugepagesize:       2048 kB
402 Hugetlb:               0 kB
403 DirectMap4k:     1997488 kB
404 DirectMap2M:    14548992 kB
405 DirectMap1G:           0 kB)";
406 }
407 
HWTEST_F(BufferSplitterUnittest, MemInfoBufferTEST, TestSize.Level1)408 HWTEST_F(BufferSplitterUnittest, MemInfoBufferTEST, TestSize.Level1)
409 {
410     int readsize = sizeof(g_kMockMeminfo);
411     BufferSplitter totalbuffer(g_kMockMeminfo, readsize);
412 
413     struct CStrCmp {
414         bool operator()(const char* a, const char* b) const
415         {
416             return strcmp(a, b) < 0;
417         }
418     };
419     std::map<const char*, int, CStrCmp> meminfo_counters_ = {{"MemTotal", 16168736},
420                                                              {"Active", 5556068},
421                                                              {"Inactive(anon)", 43352},
422                                                              {"HugePages_Total", 0},
423                                                              {"DirectMap1G", 0}};
424 
425     do {
426         if (!totalbuffer.NextWord(':')) {
427             continue;
428         }
429         const_cast<char *>(totalbuffer.CurWord())[totalbuffer.CurWordSize()] = '\0';
430         auto it = meminfo_counters_.find(totalbuffer.CurWord());
431         if (it == meminfo_counters_.end()) {
432             continue;
433         }
434 
435         int counterId = it->second;
436         if (!totalbuffer.NextWord(' ')) {
437             continue;
438         }
439         auto value = static_cast<uint64_t>(strtoll(totalbuffer.CurWord(), nullptr, 10));
440         EXPECT_EQ((uint64_t)counterId, value);
441     } while (totalbuffer.NextLine());
442 }
443 } // namespace
444