• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <hilog_adapter.h>
17 #include <stdlib.h>
18 #include "functionalext.h"
19 #include "test.h"
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <time.h>
23 #include <errno.h>
24 #include <pthread.h>
25 #include <sys/un.h>
26 #include <bits/alltypes.h>
27 #include <sys/socket.h>
28 #include <linux/socket.h>
29 #include <fcntl.h>
30 #include <dirent.h>
31 #include <securec.h>
32 #include <libc.h>
33 
34 #define MUSL_LOG_TYPE LOG_CORE
35 #define MUSL_LOG_DOMAIN 0xD003F00
36 #define MUSL_LOG_TAG "MUSL"
37 #define LOG_ERROR (6)
38 #define CLOSE_FD_COUNT (1024)
39 
40 #define ENABLE_LOG "param set musl.log.enable true"
41 #define LOG_LEVEL_ERROR "param set musl.log.level ERROR"
42 
43 #define MUSL_LOGE(...) ((void)HiLogAdapterPrint(MUSL_LOG_TYPE, LOG_ERROR, MUSL_LOG_DOMAIN, MUSL_LOG_TAG, __VA_ARGS__))
44 
45 #define PRINT_STRING_A "HilogAdapterPrinttest_a"
46 #define PRINT_STRING_B "HilogAdapterPrinttest_b"
47 #define PRINT_STRING_C "HilogAdapterPrinttest_c"
48 
49 #define ZERO (0)
50 #define TWO (2)
51 #define THREE (3)
52 #define NEGATIVE_ONE (-1)
53 #define INVALID_SOCKET (-1)
54 #define THREAD_COUNT (10)
55 #define STR_LENGTH (20)
56 char str[THREAD_COUNT][STR_LENGTH];
57 
GenerateRandomString(char * randomString,int index)58 void GenerateRandomString(char* randomString, int index)
59 {
60     #define RANDOM_STRING_LENGTH (16)
61     #define RANDOM_STRING_END (18)
62     #define RANDOM_STRING_START (2)
63     // 将索引转换为字符串并拼接到随机字符串前面
64     (void)sprintf_s(randomString, STR_LENGTH, "%02d", index);
65 
66     char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
67     int r = 0;
68     int num = 0;
69     int fd = open("/dev/random", O_RDONLY);
70     if (fd == NEGATIVE_ONE) {
71         strcpy_s(randomString + RANDOM_STRING_START, RANDOM_STRING_LENGTH, "MUSLHILOGFIXED");
72     } else {
73         for (int i = RANDOM_STRING_START; i < RANDOM_STRING_LENGTH; i++) {
74             read(fd, &r, sizeof(int));
75             // 非安全场景,使用种子确保随机字符串每次运行都不一样
76             randomString[i] = charset[r % (sizeof(charset) - 1)];
77         }
78     }
79     close(fd);
80     randomString[RANDOM_STRING_END] = '\0'; // 添加字符串结尾符
81 }
82 
83 // 检查是否有相应的日志生成,如果有当前日志,则返回true,如果没有则返回false
CheckHiLogPrint(char * needToMatch)84 bool CheckHiLogPrint(char *needToMatch)
85 {
86     #define COMMAND_SIZE (50)
87     #define READ_SIZE (49)
88     #define BUFFER_SIZE (1024)
89     #define FAIL_CLOSE (-1)
90     bool flag = false;
91     // 1. 通过system函数读取当前hilog日志信息
92     char command[] = "/bin/hilog -x | grep ";
93     char finalCommand[COMMAND_SIZE];
94     int res = snprintf_s(finalCommand, COMMAND_SIZE, READ_SIZE, "%s%s", command, needToMatch);
95     if (res == NEGATIVE_ONE) {
96         printf("CheckHiLogPrint command generate snprintf_s failed\n");
97         return false;
98     }
99     finalCommand[READ_SIZE] = '\0';
100     char buffer[BUFFER_SIZE];
101     FILE* pipe;
102     pipe = popen(finalCommand, "r");
103     if (pipe == NULL) {
104         printf("CheckHiLogPrint: Failed to run command\n");
105         return false;
106     }
107 
108     // 读取命令输出并打印
109     while (fgets(buffer, BUFFER_SIZE, pipe) != NULL) {
110         printf("%s", buffer);
111         flag = true;
112     }
113 
114     // 关闭管道并获取返回值
115     int returnValue = pclose(pipe);
116     if (returnValue == FAIL_CLOSE) {
117         printf("CheckHiLogPrint pclose failed returnValue=-1 errno=%d\n", errno);
118     }
119     return flag;
120 }
121 
122 // 子线程打印日志执行的函数
FunctionPrintLog(void * arg)123 void* FunctionPrintLog(void* arg)
124 {
125     int index = (int)arg;
126     int ret = HiLogAdapterPrint(MUSL_LOG_TYPE, LOG_ERROR, MUSL_LOG_DOMAIN, MUSL_LOG_TAG,
127         "FunctionPrintLog %{public}s", str[index]);
128     return NULL;
129 }
130 /**
131  * @tc.name     : HiLogAdapterPrint_0010
132  * @tc.desc     : Test HiLogAdapterPrint after musl_log_reset
133  * @tc.level    : Level 2
134  */
HiLogAdapterPrint_0010(void)135 static void HiLogAdapterPrint_0010(void)
136 {
137     musl_log_reset();
138     int ret = HiLogAdapterPrint(MUSL_LOG_TYPE, LOG_ERROR, MUSL_LOG_DOMAIN, MUSL_LOG_TAG, PRINT_STRING_A);
139     EXPECT_NE("HiLogAdapterPrint_0010", ret, 0);
140     // 同时也要查看hilog
141     EXPECT_EQ("HiLogAdapterPrint_0010", CheckHiLogPrint(PRINT_STRING_A), true);
142     ret = HiLogAdapterPrint(MUSL_LOG_TYPE, LOG_INFO, MUSL_LOG_DOMAIN, MUSL_LOG_TAG, PRINT_STRING_B);
143     EXPECT_EQ("HiLogAdapterPrint_0010", ret, -1);
144 }
145 
146 /**
147  * @tc.name     : HilogAdapterPrint_0020
148  * @tc.desc     : Test single thread HilogAdapterPrint after hilog fd close
149  * @tc.level    : Level 2
150  */
HilogAdapterPrint_0020(void)151 static void HilogAdapterPrint_0020(void)
152 {
153     musl_log_reset();
154     // We need to refresh the hilog socket to close previous socket
155     RefreshHiLogSocketFd();
156     // 前置条件:校验g_socketFd无效
157     EXPECT_EQ("HilogAdapterPrint_0020 CheckHilogInvalid", CheckHilogValid(), ZERO);
158     int ret = HiLogAdapterPrint(MUSL_LOG_TYPE, LOG_ERROR, MUSL_LOG_DOMAIN, MUSL_LOG_TAG, PRINT_STRING_C);
159     // 检查g_socketFd有效
160     EXPECT_NE("HilogAdapterPrint_0020 CheckHilogValid", CheckHilogValid(), ZERO);
161     // 检查write正常
162     EXPECT_GT("HiLogAdapterPrint_0020", ret, 0);
163     bool result = CheckHiLogPrint(PRINT_STRING_C);
164     // 检查有日志生成
165     EXPECT_EQ("HilogAdapterPrint_0020_CheckHiLogPrint", result, true);
166 }
167 
168 /**
169  * @tc.name     : HilogAdapterPrint_0030
170  * @tc.desc     : dls3阶段初始化异常时,线程自己初始化成功,
171  *     单线程:预期是能够替换g_socketFd,并能够正常打印日志
172  *     多线程:预期是能够替换g_socketFd,并能够正常打印日志,且fd未发生泄漏
173  * @tc.level    : Level 2
174  */
HilogAdapterPrint_0030(void)175 static void HilogAdapterPrint_0030(void)
176 {
177     musl_log_reset();
178     // 关闭socketFd
179     RefreshHiLogSocketFd();
180     // 前置条件:校验g_socketFd无效
181     EXPECT_EQ("HilogAdapterPrint_0030 CheckHilogInvalid", CheckHilogValid(), ZERO);
182     pthread_t threads[THREAD_COUNT];
183     int threadCreateResult = -1;
184     printf("libc.can_do_threads=%d\n", libc.can_do_threads);
185     // 创建线程并发打印,每个线程打印的日志都不能丢
186     for (int i = ZERO; i < THREAD_COUNT; i++) {
187         // 生成一个随机字符串,然后将下标通过值传递给子线程,让子线程拿到全局的数据
188         GenerateRandomString(str[i], i);
189         if (libc.can_do_threads) {
190             threadCreateResult = pthread_create(&threads[i], NULL, FunctionPrintLog, (void *)i);
191         }
192         if (threadCreateResult != 0) {
193             fprintf(stderr, "Failed to create thread %d errno=%d\n", i, errno);
194             FunctionPrintLog((void *)i);
195         }
196     }
197 
198     // 检查g_socketFd有效
199     EXPECT_NE("HilogAdapterPrint_0030 CheckHilogValid", CheckHilogValid(), ZERO);
200     // 等待线程执行完毕
201     for (int i = ZERO; i < THREAD_COUNT; i++) {
202         if (libc.can_do_threads && pthread_join(threads[i], NULL) != 0) {
203             fprintf(stderr, "Failed to join thread %d\n", i);
204         }
205         // 在这里判断当前日志是否打印成功
206         bool result = CheckHiLogPrint(str[i]);
207         EXPECT_EQ("HilogAdapterPrint_0030_CheckHiLogPrint", result, true);
208     }
209 }
210 
main(void)211 int main(void)
212 {
213     // 解除限制
214     system("/bin/hilog -Q pidoff");
215     system("/bin/hilog -Q domainoff");
216 
217     system(ENABLE_LOG);
218     system(LOG_LEVEL_ERROR);
219     HiLogAdapterPrint_0010();
220     HilogAdapterPrint_0020();
221     HilogAdapterPrint_0030();
222 
223     // 恢复限制
224     system("/bin/hilog -Q pidon");
225     system("/bin/hilog -Q domainon");
226 	return t_status;
227 }
228