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 <stdlib.h>
17#include <string.h>
18#include <errno.h>
19#include <securec.h>
20#include <gtest/gtest.h>
21#include "log.h"
22#include "utils.h"
23#include "KernelConstants.h"
24
25using namespace testing::ext;
26
27class MemApiTest : public testing::Test {
28};
29
30/**
31 * @tc.number SUB_KERNEL_MEM_MALLOC_0100
32 * @tc.name   malloc function alloc random bytes test
33 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
34 */
35HWTEST_F(MemApiTest, testMallocRandom, Function | MediumTest | Level1)
36{
37    size_t size;
38    void *mem = nullptr;
39
40    for (int i=0; i<100; i++) {
41        size = GetRandom(0x200000);
42        mem = malloc(size);
43        ASSERT_TRUE(mem != nullptr) << "mem == nullptr";
44
45        free(mem);
46    }
47}
48
49/**
50 * @tc.number SUB_KERNEL_MEM_MALLOC_0200
51 * @tc.name   malloc function alloc 0 bytes test
52 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
53 */
54HWTEST_F(MemApiTest, testMallocZero, Function | MediumTest | Level2)
55{
56    pid_t pid = fork();
57    ASSERT_TRUE(pid >= 0) << "Fork Error";
58    if (pid == 0) {
59        void *mem = malloc(0);
60        free(mem);
61
62        exit(0);
63    } else {
64        WaitProcExitedOK(pid);
65    }
66}
67
68/**
69 * @tc.number SUB_KERNEL_MEM_MALLOC_0300
70 * @tc.name   malloc function errno for ENOMEM test
71 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
72 */
73HWTEST_F(MemApiTest, testMallocENOMEM, Function | MediumTest | Level3)
74{
75    int i, k;
76    void *mem[100] = {nullptr};
77    size_t size = 0x08000000;
78
79    for (i = 0; i < 100; i++) {
80        mem[i] = malloc(size);
81        if (mem[i] == nullptr) {
82            LOG("mem[i] = NULL: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
83            break;
84        }
85    }
86
87    ASSERT_TRUE(i < 100);
88    ASSERT_TRUE(mem[i] == nullptr) << "mem[i] != NULL, i = " << i;
89    EXPECT_TRUE(errno == ENOMEM) << "ERROR: errno != ENOMEM, errno = " << errno << " ENOMEM = " << ENOMEM;
90
91    for (k = 0; k < i; k++) {
92        free(mem[k]);
93    }
94}
95
96/**
97 * @tc.number SUB_KERNEL_MEM_FREE_0100
98 * @tc.name   free function ptr is NULL test
99 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
100 */
101HWTEST_F(MemApiTest, testFreeNULL, Function | MediumTest | Level1)
102{
103    int pid = fork();
104    ASSERT_TRUE(pid >= 0) << " fork() < 0";
105    if (pid == 0) {
106        free(nullptr);
107        exit(0);
108    } else {
109        WaitProcExitedOK(pid);
110    }
111}
112
113/**
114 * @tc.number SUB_KERNEL_MEM_REALLOC_0100
115 * @tc.name   realloc function realloc memory test
116 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
117 */
118HWTEST_F(MemApiTest, testReallocMem, Function | MediumTest | Level3)
119{
120    size_t k, len, mlen, rlen;
121    void *mem = nullptr;
122    char *data = nullptr;
123    int i, failure;
124    char testChar = 0x36;
125    void *memp = nullptr;
126
127    failure = 0;
128    for (i = 1; i < 5; i++) {
129        mlen = GetRandom(0x200000);
130        mem = malloc(mlen);
131        ASSERT_TRUE(mem != nullptr) << "mem == NULL";
132
133        memset(mem, testChar, mlen);
134        rlen = GetRandom(0x200000);
135        memp = mem;
136        mem = realloc(mem, rlen);
137        if (mem == nullptr) {
138            free(memp);
139        } else {
140            memp = nullptr;
141        }
142        ASSERT_TRUE(mem != nullptr) << "mem == NULL, i = " << i;
143
144        len = mlen <= rlen ? mlen : rlen;
145
146        data = (char *)mem;
147        for (k = 0; k < len; k++) {
148            if (data[k] != testChar) {
149                failure = 1;
150                LOG("ERROR: data[k] != testChar, data[%d] = %d, testChar = %d", k, data[k], testChar);
151                break;
152            }
153        }
154        free(mem);
155
156        /* data[k] not equal to testChar */
157        if (failure != 0) {
158            ADD_FAILURE();
159        }
160    }
161}
162
163/**
164 * @tc.number SUB_KERNEL_MEM_REALLOC_0200
165 * @tc.name   realloc function parameter is NULL test
166 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
167 */
168HWTEST_F(MemApiTest, testReallocNULL, Function | MediumTest | Level3)
169{
170    char *mem = nullptr;
171    char *prev = nullptr;
172
173    pid_t pid = fork();
174    ASSERT_TRUE(pid >= 0) << "Fork Error";
175    if (pid == 0) {
176        for (int i = 0; i < 20; i++) {
177            size_t len = GetRandom(0x200000);
178            /* This call is equivalent to malloc(len) */
179            mem = (char *)realloc(nullptr, len);
180            prev = mem;
181            mem[0] = 0x31;
182            free(mem);
183
184            mem = (char *)realloc(nullptr, len);
185            if (mem != prev) {
186                LOG("mem != prev, mem = %p, prev = %p", mem, prev);
187                free(mem);
188                exit(1);
189            }
190            free(mem);
191        }
192        exit(0);
193    } else {
194        WaitProcExitedOK(pid);
195    }
196}
197
198/**
199 * @tc.number SUB_KERNEL_MEM_REALLOC_0300
200 * @tc.name   realloc function errno for ENOMEM test
201 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
202 */
203HWTEST_F(MemApiTest, testReallocENOMEM, Function | MediumTest | Level3)
204{
205    size_t len = 4096;
206    size_t large = 0x80000000;
207
208    void *mem = malloc(len);
209    ASSERT_TRUE(mem != nullptr) << "mem == NULL";
210    LOG("__LINE__ = %d, mem = %p, errno = %d", __LINE__, mem, errno);
211
212    void *reMem = realloc(mem, large);
213    EXPECT_TRUE(reMem == nullptr) << "reMem != NULL, reMem = " << reMem;
214    EXPECT_TRUE(errno == ENOMEM) << "ERROR: errno != ENOMEM, errno = " << errno << " ENOMEM = " << ENOMEM;
215
216    if (reMem != nullptr) {
217        mem = reMem;
218    }
219    free(mem);
220}
221
222/**
223 * @tc.number SUB_KERNEL_MEM_CALLOC_0100
224 * @tc.name   calloc function alloc random size memory block test
225 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
226 */
227HWTEST_F(MemApiTest, testCallocRandom, Function | MediumTest | Level3)
228{
229    char *mem = nullptr;
230    int i, sum = 0;
231    size_t k, len, nmemb = 32;
232
233    for (i = 0; i < 10; i++) {
234        len = GetRandom(64 * 1024);
235        mem = (char *)calloc(nmemb, len);
236        ASSERT_TRUE(mem != nullptr) << "mem == NULL, i = " << i;
237
238        for (k = 0; k < len * nmemb; k++) {
239            sum += mem[k];
240        }
241        EXPECT_TRUE(sum == 0) << "sum != 0, sum = " << sum;
242
243        free(mem);
244    }
245}
246
247/**
248 * @tc.number SUB_KERNEL_MEM_CALLOC_0200
249 * @tc.name   calloc function alloc zero size and zero memory block test
250 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
251 */
252HWTEST_F(MemApiTest, testCallocZero, Function | MediumTest | Level2)
253{
254    pid_t pid = fork();
255    ASSERT_TRUE(pid >= 0) << "Fork Error";
256    if (pid == 0) {
257        struct {
258            size_t nmemb;
259            size_t len;
260        } var[3] = {{32, 0}, {0, GetRandom(4096)}, {0, 0}};
261
262        for (int i=0; i<3; i++) {
263            void *mem = calloc(var[i].nmemb, var[i].len);
264            free(mem);
265        }
266        exit(0);
267    } else {
268        WaitProcExitedOK(pid);
269    }
270}
271
272/**
273 * @tc.number SUB_KERNEL_MEM_CALLOC_0300
274 * @tc.name   calloc function errno for ENOMEM test
275 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
276 */
277HWTEST_F(MemApiTest, testCallocENOMEM, Function | MediumTest | Level3)
278{
279    int i, k;
280    void *mem[100] = {nullptr};
281    size_t nmemb = 128;
282    size_t size = 1024 * 1024;
283
284    for (i = 0; i < 100; i++) {
285        mem[i] = calloc(nmemb, size);
286        if (mem[i] == nullptr) {
287            LOG("mem[i] = NULL: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
288            break;
289        }
290    }
291
292    ASSERT_TRUE(i < 100);
293    ASSERT_TRUE(mem[i] == nullptr) << "mem[i] != NULL, i = " << i;
294    EXPECT_TRUE(errno == ENOMEM) << "ERROR: errno != ENOMEM, errno = " << errno << " ENOMEM = " << ENOMEM;
295
296    for (k = 0; k < i; k++) {
297        free(mem[k]);
298    }
299}
300
301/**
302 * @tc.number SUB_KERNEL_MEM_VALLOC_0100
303 * @tc.name   valloc function alloc more than 4096 bytes test
304 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
305 */
306HWTEST_F(MemApiTest, testVallocBytes, Function | MediumTest | Level3)
307{
308    void *mem = nullptr;
309    int pageSize = 0x1000;
310    size_t len = 0;
311
312    for (int i = 0; i < 10; i++) {
313        len += 0x00100000;
314        mem = valloc(len);
315        EXPECT_TRUE(mem != nullptr);
316        EXPECT_TRUE((((unsigned long)mem) & (pageSize - 1)) == 0);
317
318        free(mem);
319    }
320}
321
322/**
323 * @tc.number SUB_KERNEL_MEM_VALLOC_0200
324 * @tc.name   valloc function alloc 0 byte test
325 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
326 */
327HWTEST_F(MemApiTest, testVallocZero, Function | MediumTest | Level2)
328{
329    pid_t pid = fork();
330    ASSERT_TRUE(pid >= 0) << "Fork Error";
331    if (pid == 0) {
332        void *mem = valloc(0);
333        free(mem);
334
335        exit(0);
336    } else {
337        WaitProcExitedOK(pid);
338    }
339}
340
341/**
342 * @tc.number SUB_KERNEL_MEM_VALLOC_0300
343 * @tc.name   valloc function errno for ENOMEM test
344 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
345 */
346HWTEST_F(MemApiTest, testVallocENOMEM, Function | MediumTest | Level3)
347{
348    int i, k;
349    void *mem[100] = {nullptr};
350    size_t size = 0x08000000;
351
352    for (i = 0; i < 100; i++) {
353        mem[i] = valloc(size);
354        if (mem[i] == nullptr) {
355            LOG("mem[i] = NULL: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
356            break;
357        }
358    }
359
360    ASSERT_TRUE(i < 100);
361    ASSERT_TRUE(mem[i] == nullptr) << "mem != NULL";
362    EXPECT_TRUE(errno == ENOMEM) << "ERROR: errno != ENOMEM, errno = " << errno << " ENOMEM = " << ENOMEM;
363
364    for (k = 0; k < i; k++) {
365        free(mem[k]);
366    }
367}
368
369/**
370 * @tc.number SUB_KERNEL_MEM_MEMALIHN_0100
371 * @tc.name   memalign function alloc memory for 2 ^ n align test
372 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
373 */
374HWTEST_F(MemApiTest, testMemalignTwoAlign, Function | MediumTest | Level2)
375{
376    void *mem = nullptr;
377    int i, align;
378    size_t len = 0x1000;
379
380    for (i = 2; i < 21; i++) {
381        align = 1 << i;
382        mem = memalign(align, len);
383        ASSERT_TRUE(mem != nullptr) << "mem == NULL";
384        EXPECT_TRUE((((unsigned long)mem) & (align - 1)) == 0);
385
386        free(mem);
387    }
388}
389
390/**
391 * @tc.number SUB_KERNEL_MEM_MEMALIHN_0200
392 * @tc.name   memalign function errno for EINVAL test
393 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
394 */
395HWTEST_F(MemApiTest, testMemalignEINVAL, Function | MediumTest | Level3)
396{
397    void *mem = nullptr;
398    int i, align;
399    size_t size = 0x1000;
400
401    mem = memalign(0, size);
402    EXPECT_TRUE(mem != nullptr) << "mem == nullptr";
403    free(mem);
404
405    for (i = 1; i < 10; i++) {
406        align = (1 << i) + 1;
407        mem = memalign(align, size);
408        ASSERT_TRUE(mem == nullptr) << "mem != nullptr";
409        EXPECT_TRUE(errno == EINVAL) << "ERROR: errno != EINVAL, errno = " << errno << " EINVAL = " << EINVAL;
410
411        free(mem);
412    }
413}
414
415/**
416 * @tc.number SUB_KERNEL_MEM_MEMALIHN_0300
417 * @tc.name   memalign function errno for ENOMEM test
418 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
419 */
420HWTEST_F(MemApiTest, testMemalignENOMEM, Function | MediumTest | Level3)
421{
422    int i, k;
423    int align = 4096;
424    void *mem[100] = {nullptr};
425    size_t size = 0x08000000;
426
427    for (i = 0; i < 100; i++) {
428        mem[i] = memalign(align, size);
429        if (mem[i] == nullptr) {
430            LOG("mem[i] = NULL: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
431            break;
432        }
433    }
434
435    ASSERT_TRUE(i < 100);
436    ASSERT_TRUE(mem[i] == nullptr) << "mem[i] != nullptr, i = " << i;
437    EXPECT_TRUE(errno == ENOMEM) << "ERROR: errno != ENOMEM, errno = " << errno << " ENOMEM = " << ENOMEM;
438
439    for (k = 0; k < i; k++) {
440        free(mem[k]);
441    }
442}
443
444/**
445 * @tc.number SUB_KERNEL_MEM_POSIX_MEMALIGN_0100
446 * @tc.name   posix_memalign function alloc memory for 2 ^ n align test
447 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
448 */
449HWTEST_F(MemApiTest, testPosixMemalignTwoAlign, Function | MediumTest | Level3)
450{
451    void *mem = nullptr;
452    int i, err;
453    size_t align;
454    size_t len = GetRandom(4096);
455
456    for (i = 2; i < 21; i++) {
457        align = 1 << i;
458
459        if (align % sizeof(void *)) {
460            continue;
461        }
462        err = posix_memalign(&mem, align, len);
463        ASSERT_TRUE(err == 0) << "err = " << err << ", i = " << i;
464        EXPECT_TRUE((((size_t)(uintptr_t)mem) & (align - 1)) == 0);
465
466        free(mem);
467    }
468}
469
470/**
471 * @tc.number SUB_KERNEL_MEM_POSIX_MEMALIGN_0200
472 * @tc.name   posix_memalign function alloc 0 byte test
473 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
474 */
475HWTEST_F(MemApiTest, testPosixMemalignZero, Function | MediumTest | Level2)
476{
477    void *mem = nullptr;
478    int align = 1024;
479
480    pid_t pid = fork();
481    ASSERT_TRUE(pid >= 0) << "Fork Error";
482    if (pid == 0) {
483        posix_memalign(&mem, align, 0);
484        free(mem);
485        exit(0);
486    } else {
487        WaitProcExitedOK(pid);
488    }
489}
490
491/**
492 * @tc.number SUB_KERNEL_MEM_POSIX_MEMALIGN_0300
493 * @tc.name   posix_memalign function errno for EINVAL test
494 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
495 */
496HWTEST_F(MemApiTest, testPosixMemalignEINVAL, Function | MediumTest | Level3)
497{
498    void *mem = nullptr;
499    int i, align, err;
500
501    err = posix_memalign(&mem, 0, 16);
502    EXPECT_TRUE((err != 0) && (err == EINVAL)) << "err = " << err;
503    LOG("__LINE__ = %d, ret = %d (0x%08x)", __LINE__, err, err);
504    if (err == 0) {
505        free(mem);
506    }
507
508    align = sizeof(void *) + 1;
509    err = posix_memalign(&mem, align, 16);
510    ASSERT_TRUE((err != 0) && (err == EINVAL)) << "err = " << err;
511    LOG("__LINE__ = %d, ret = %d (0x%08x), align = 0x%08x %d", __LINE__, err, err, align - 1, align);
512    free(mem);
513
514    for (i = 1; i < 10; i++) {
515        align = (1 << i) + 1;
516        err = posix_memalign(&mem, align, 16);
517        EXPECT_TRUE((err != 0) && (err == EINVAL)) << "err = " << err;
518        if (err == 0) {
519            free(mem);
520        }
521    }
522}
523
524/**
525 * @tc.number SUB_KERNEL_MEM_POSIX_MEMALIGN_0400
526 * @tc.name   posix_memalign function errno for ENOMEM test
527 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
528 */
529HWTEST_F(MemApiTest, testPosixMemalignENOMEM, Function | MediumTest | Level3)
530{
531    int i, k, err;
532    int align = 4096;
533    void *mem[100] = {nullptr};
534    size_t size = 0x08000000;
535
536    for (i = 0; i < 100; i++) {
537        err = posix_memalign(&mem[i], align, size);
538        if (mem[i] == nullptr) {
539            LOG("mem[i] = NULL: i = %d, errno = %d, ENOMEM = %d", i, errno, ENOMEM);
540            break;
541        }
542    }
543    ASSERT_TRUE(i < 100);
544    ASSERT_TRUE(mem[i] == nullptr) << "mem[i] != nullptr, i = " << i;
545    EXPECT_TRUE((err != 0) && (err == ENOMEM)) << "ERROR: errno != ENOMEM err = " << err;
546
547    for (k = 0; k < i; k++) {
548        free(mem[k]);
549    }
550}
551
552/**
553 * @tc.number SUB_KERNEL_MEM_OPEN_MEMSTREAM_0100
554 * @tc.name   open_memstream function test
555 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
556 */
557HWTEST_F(MemApiTest, testOpenMemstreamBase, Function | MediumTest | Level2)
558{
559    size_t i, len;
560    int failure = 0;
561    char *buf = nullptr;
562    const char wBuf[] = "A simple string to write";
563    char largeBuf[1024];
564    const int largeLen = 800;
565
566    FILE *stream = open_memstream(&buf, &len);
567    ASSERT_TRUE(stream != nullptr) << "stream == nullptr";
568    ASSERT_TRUE(buf != nullptr && len == 0) << "buf == nullptr or len != 0";
569
570    fprintf(stream, wBuf);
571    fflush(stream);
572    LOG("buf = %s, len = %d, buf[len] = 0x%02x", buf, len, buf[len]);
573    LOG("len = %ld, sizeof(wBuf) - 1 = %d", len, sizeof(wBuf) - 1);
574    EXPECT_TRUE(len == sizeof(wBuf) - 1) << "len != sizeof (wBuf) - 1";
575
576    for (i = 0; i < len; i++) {
577        if (buf[i] != wBuf[i]) {
578            failure = 1;
579            break;
580        }
581    }
582    EXPECT_TRUE(failure == 0) << "buf[i] != wBuf[i], buf[i] = " << buf[i] << " wBuf[i] = " << wBuf[i];
583    EXPECT_TRUE(ftello(stream) == len) << "ftello() != len";
584    EXPECT_TRUE(fseeko(stream, 0, SEEK_SET) == 0);
585    LOG("buf = %s, len = %d, buf[len] = 0x%02x", buf, len, buf[len]);
586
587    for (i = 0; i < largeLen; i++) {
588        largeBuf[i] = 0x36;
589    }
590    largeBuf[i] = 0;
591    fprintf(stream, largeBuf);
592    fflush(stream);
593
594    for (i = 0; i < len; i++) {
595        if (buf[i] != largeBuf[i]) {
596            failure = 1;
597            break;
598        }
599    }
600    EXPECT_TRUE(failure == 0) << "buf[i] != largeBuf[i], buf[i] = " << buf[i] << " largeBuf[i] = " << largeBuf[i];
601    LOG("buf = %p, len = %d, buf[len] = 0x%02x", buf, len, buf[len]);
602    EXPECT_TRUE(fclose(stream) == 0) << "fclose() != 0";
603    free(buf);
604}
605
606/**
607 * @tc.number SUB_KERNEL_MEM_MEMSET_0100
608 * @tc.name   memset function set buffer value test
609 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
610 */
611HWTEST_F(MemApiTest, testMemset, Function | MediumTest | Level1)
612{
613    char chr = 'A';
614    int i, len, failure;
615    len = GetRandom(1024);
616    errno_t err = EOK;
617
618    char buf[1024];
619    err = memset_s(buf, sizeof(buf), chr, len);
620    if(err != EOK) {
621        LOG("memset_s failed, err = %d\n", err);
622    }
623    failure = 0;
624    for (i = 0; i < len; i++) {
625        if (buf[i] != chr) {
626            failure = 1;
627            break;
628        }
629    }
630    ASSERT_TRUE(failure == 0) << "buf[i] != chr, buf[i] = " << buf[i] << " chr = " << chr;
631}
632
633/**
634 * @tc.number SUB_KERNEL_MEM_MEMCPY_0100
635 * @tc.name   memcpy function copy buffer test
636 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
637 */
638HWTEST_F(MemApiTest, testMemcpy, Function | MediumTest | Level2)
639{
640    char chr = 'A';
641    int i, len, failure;
642    char src[1024];
643    char dst[1024];
644
645    len = GetRandom(1024);
646
647    for (i = 0; i < len; i++) {
648        src[i] = chr + i % 26;
649    }
650
651    memcpy(dst, src, len);
652    failure = 0;
653    for (i = 0; i < len; i++) {
654        if (dst[i] != src[i]) {
655            failure = 1;
656            break;
657        }
658    }
659    ASSERT_TRUE(failure == 0) << "dst[i] != src[i], dst[i] = " << dst[i] << " src[i] = " << src[i];
660}
661
662/**
663 * @tc.number SUB_KERNEL_MEM_MEMCPY_0200
664 * @tc.name   memcpy function overlay copy test
665 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
666 */
667HWTEST_F(MemApiTest, testMemcpyOverlay, Function | MediumTest | Level3)
668{
669    int len;
670    char chr = 'A';
671    char buf[1024];
672
673    len = sizeof(buf);
674    for (int i = 0; i < len; i++) {
675        buf[i] = chr + GetRandom(26);
676    }
677
678    pid_t pid = fork();
679    ASSERT_TRUE(pid >= 0) << "Fork Error";
680
681    if (pid == 0) {
682        memcpy(&buf[16], &buf[0], len / 2);
683        for (int i = 0; i < 16; i++) {
684            if (buf[i + 16] != buf[i]) {
685                LOG("buf[i + 16] != buf[i], buf[i + 16] = %d, buf[i] = %d", buf[i + 16], buf[i]);
686                exit(1);
687            }
688        }
689        exit(0);
690    } else {
691        WaitProcExitedOK(pid);
692    }
693}
694
695/**
696 * @tc.number SUB_KERNEL_MEM_MEMMOVE_0100
697 * @tc.name   memmove function move buffer test
698 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
699 */
700HWTEST_F(MemApiTest, testMemmove, Function | MediumTest | Level2)
701{
702    char chr = 'A';
703    char buf[1024];
704    int i, len, failure;
705
706    len = sizeof(buf);
707    for (i = 0; i < len; i++) {
708        buf[i] = chr + GetRandom(26);
709    }
710    memmove(&buf[0], &buf[len / 2], len / 2);
711
712    failure = 0;
713    for (i = 0; i < len / 2; i++) {
714        if (buf[i] != buf[len / 2 + i]) {
715            failure = 1;
716            LOG("buf[i] != buf[len / 2 + i], buf[i] = %d, buf[len / 2 + i] = %d", buf[i], buf[len / 2 + i]);
717            break;
718        }
719    }
720    /* buf[i] not equal to buf[len / 2 + i] */
721    ASSERT_TRUE(failure == 0);
722}
723
724/**
725 * @tc.number SUB_KERNEL_MEM_MEMMOVE_0200
726 * @tc.name   memmove function overlay move buffer test
727 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
728 */
729HWTEST_F(MemApiTest, testMemmoveOverlay, Function | MediumTest | Level3)
730{
731    char chr = 'A';
732    char buf[1024];
733    char backup[1024];
734    int i, len, failure;
735
736    len = sizeof(buf);
737    for (i = 0; i < len; i++) {
738        buf[i] = chr + GetRandom(26);
739        backup[i] = buf[i];
740    }
741    memmove(&buf[16], &buf[0], len / 2);
742
743    failure = 0;
744    for (i = 0; i < len / 2; i++) {
745        if (buf[i + 16] != backup[i]) {
746            failure = 1;
747            LOG("buf[i + 16] != backup[i], buf[i + 16] = %d, backup[i] = %d", buf[i + 16], backup[i]);
748            break;
749        }
750    }
751    ASSERT_TRUE(failure == 0) << "buf[i + 16] != backup[i]";
752}
753
754
755/**
756 * @tc.number SUB_KERNEL_MEM_MEMCMP_0100
757 * @tc.name   memmove function move buffer test
758 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
759 */
760HWTEST_F(MemApiTest, testMemcmp, Function | MediumTest | Level2)
761{
762    char orign[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
763    char lt[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x77};
764    char eq[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
765    char gt[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x99};
766
767    int ret;
768    int len = sizeof(orign);
769
770    ret = memcmp(lt, orign, len);
771    ASSERT_TRUE(ret < 0);
772
773    ret = memcmp(eq, orign, len);
774    ASSERT_TRUE(ret == 0);
775
776    ret = memcmp(gt, orign, len);
777    ASSERT_TRUE(ret > 0);
778
779    ret = memcmp(gt, orign, 0);
780    ASSERT_TRUE(ret == 0);
781}
782
783/**
784 * @tc.number SUB_KERNEL_MEM_MEMRCHR_0100
785 * @tc.name   memrchr function find the last value in the string test
786 * @tc.desc   [C-L*-311] MUST NOT alter NDK API behavior.
787 */
788HWTEST_F(MemApiTest, testMemrchr, Function | MediumTest | Level2)
789{
790    char orign[] = "This is test string";
791    int len = sizeof(orign);
792
793    /* add the terminal characteric for the string */
794    orign[4] = '\0';
795    orign[7] = '\0';
796
797    char *last = (char *)memrchr(orign, 'k', len);
798    ASSERT_TRUE(last == nullptr);
799
800    char *first = (char *)memchr(orign, 's', len);
801    ASSERT_TRUE(first == &orign[3]);
802
803    last = (char *)memrchr(orign, 's', len);
804    ASSERT_TRUE(last == &orign[13]);
805}
806
807