1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "platform_device_test.h"
10 #include "platform_assert.h"
11 #include "platform_manager.h"
12
13 #define HDF_LOG_TAG platform_device_test
14
15 #define PLAT_DEV_WAIT_TIMEOUT 10
16
PlatformDeviceTestSetUpAll(void)17 void PlatformDeviceTestSetUpAll(void)
18 {
19 }
20
PlatformDeviceTestTearDownAll(void)21 void PlatformDeviceTestTearDownAll(void)
22 {
23 }
24
PlatformDeviceTestSetName(struct PlatformDevice * device)25 static int32_t PlatformDeviceTestSetName(struct PlatformDevice *device)
26 {
27 int32_t ret;
28
29 PLAT_LOGD("PlatformDeviceTestSetName: enter!");
30 // should set name success
31 ret = PlatformDeviceSetName(device, "platform_device_name_%d", 1);
32 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
33 ret = strcmp(device->name, "platform_device_name_1");
34 CHECK_EQ_RETURN(ret, 0, HDF_FAILURE);
35
36 // name should be null after clear
37 PlatformDeviceClearName(device);
38 CHECK_EQ_RETURN(device->name, NULL, HDF_FAILURE);
39
40 // should set name success
41 ret = PlatformDeviceSetName(device, "platform_device_name");
42 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
43 ret = strcmp(device->name, "platform_device_name");
44 CHECK_EQ_RETURN(ret, 0, HDF_FAILURE);
45
46 // clean the name after test
47 PlatformDeviceClearName(device);
48
49 PLAT_LOGD("PlatformDeviceTestSetName: exit!");
50 return HDF_SUCCESS;
51 }
52
PlatformDeviceTestGetDevice(struct PlatformDevice * device)53 static int32_t PlatformDeviceTestGetDevice(struct PlatformDevice *device)
54 {
55 int32_t ret;
56 int32_t refCntBeforeGet;
57 int32_t refCntAfterGet;
58 int32_t refCntAfterPut;
59
60 PLAT_LOGD("PlatformDeviceTestGetDevice: enter!");
61 device->name = "platform_device_test_get";
62 refCntBeforeGet = PlatformDeviceRefCount(device);
63 ret = PlatformDeviceGet(device);
64 // should get device success
65 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
66
67 refCntAfterGet = PlatformDeviceRefCount(device);
68 // ref count should increase by 1 after get
69 CHECK_EQ_RETURN(refCntAfterGet, refCntBeforeGet + 1, ret);
70
71 ret = PlatformDeviceGet(device);
72 // should get device success again
73 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
74 refCntAfterGet = PlatformDeviceRefCount(device);
75 // ref count should increase by 2 after double get
76 CHECK_EQ_RETURN(refCntAfterGet, refCntBeforeGet + 2, ret);
77
78 PlatformDevicePut(device);
79 refCntAfterPut = PlatformDeviceRefCount(device);
80 // ref count should decrease by 1 after put
81 CHECK_EQ_RETURN(refCntAfterPut, refCntBeforeGet + 1, ret);
82
83 PlatformDevicePut(device);
84 refCntAfterPut = PlatformDeviceRefCount(device);
85 // ref count should decrease by 2 after put
86 CHECK_EQ_RETURN(refCntAfterPut, refCntBeforeGet, ret);
87
88 PLAT_LOGD("PlatformDeviceTestGetDevice: exit!");
89 return HDF_SUCCESS;
90 }
91
PlatformDeviceTestWaitEvent(struct PlatformDevice * device)92 static int32_t PlatformDeviceTestWaitEvent(struct PlatformDevice *device)
93 {
94 int32_t ret;
95 uint32_t eventA = 0x1;
96 uint32_t eventB = 0x4;
97 uint32_t mask = eventA | eventB;
98 uint32_t events;
99
100 PLAT_LOGD("PlatformDeviceTestWaitEvent: enter!");
101 device->name = "platform_device_test_event";
102 // should not wait success before post
103 ret = PlatformDeviceWaitEvent(device, mask, PLAT_DEV_WAIT_TIMEOUT, &events);
104 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
105
106 // should post event success
107 ret = PlatformDevicePostEvent(device, eventA | eventB);
108 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
109
110 // should wait success after post
111 ret = PlatformDeviceWaitEvent(device, mask, PLAT_DEV_WAIT_TIMEOUT, &events);
112 PLAT_LOGD("PlatformDeviceTestWaitEvent: events:%x!", events);
113 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
114 CHECK_EQ_RETURN(events, eventA | eventB, ret);
115
116 PLAT_LOGD("PlatformDeviceTestWaitEvent: exit!");
117 return HDF_SUCCESS;
118 }
119
PlatformDeviceTestAddDevice(struct PlatformDevice * device)120 static int32_t PlatformDeviceTestAddDevice(struct PlatformDevice *device)
121 {
122 int32_t ret;
123 struct PlatformManager *manager = NULL;
124 struct PlatformDevice *deviceGet = NULL;
125
126 PLAT_LOGD("PlatformDeviceTestAddDevice: enter!");
127 device->name = "platform_device_test_add";
128 // should create manager success
129 ret = PlatformManagerCreate("platform_test_manager", &manager);
130 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
131
132 device->number = 0x5A; // a random number just for testing
133 device->manager = manager;
134 // should add platform device success
135 ret = PlatformDeviceAdd(device);
136 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
137
138 // should get the device added
139 deviceGet = PlatformManagerGetDeviceByNumber(manager, device->number);
140 CHECK_EQ_RETURN(deviceGet, device, ret);
141 PlatformDevicePut(deviceGet);
142
143 PlatformDeviceDel(device);
144 // should not get the device after del
145 deviceGet = PlatformManagerGetDeviceByNumber(manager, device->number);
146 CHECK_EQ_RETURN(deviceGet, NULL, ret);
147
148 PLAT_LOGD("PlatformDeviceTestAddDevice: exit!");
149 return HDF_SUCCESS;
150 }
151
TestDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)152 static int32_t TestDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
153 {
154 (void)client;
155 (void)cmd;
156 (void)data;
157 (void)reply;
158 return HDF_SUCCESS;
159 }
160
PlatformDeviceTestCreateService(struct PlatformDevice * device)161 static int32_t PlatformDeviceTestCreateService(struct PlatformDevice *device)
162 {
163 int32_t ret;
164
165 PLAT_LOGD("PlatformDeviceTestCreateService: enter!");
166 device->name = "platform_device_test_create_service";
167 ret = PlatformDeviceCreateService(device, TestDispatch);
168 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
169
170 CHECK_NE_RETURN(device->service, NULL, HDF_FAILURE);
171 CHECK_EQ_RETURN(device->service->Dispatch, TestDispatch, HDF_FAILURE);
172
173 PlatformDeviceDestroyService(device);
174 CHECK_EQ_RETURN(device->service, NULL, HDF_FAILURE);
175
176 PLAT_LOGD("PlatformDeviceTestCreateService: exit!");
177 return HDF_SUCCESS;
178 }
179
PlatformDeviceTestBindDevice(struct PlatformDevice * device)180 static int32_t PlatformDeviceTestBindDevice(struct PlatformDevice *device)
181 {
182 int32_t ret;
183 struct HdfDeviceObject hdfDev;
184 struct IDeviceIoService service;
185 struct PlatformDevice *devFromHdf = NULL;
186
187 PLAT_LOGD("PlatformDeviceTestBindDevice: enter!");
188 device->name = "platform_device_test_bind";
189 device->service = &service;
190 ret = PlatformDeviceBind(device, &hdfDev);
191 CHECK_EQ_RETURN(ret, HDF_SUCCESS, ret);
192 CHECK_EQ_RETURN(device->hdfDev, &hdfDev, HDF_FAILURE);
193 CHECK_EQ_RETURN(device->service, hdfDev.service, HDF_FAILURE);
194
195 devFromHdf = PlatformDeviceFromHdfDev(&hdfDev);
196 CHECK_EQ_RETURN(device, devFromHdf, HDF_FAILURE);
197
198 PlatformDeviceUnbind(device, &hdfDev);
199 CHECK_EQ_RETURN(device->hdfDev, NULL, ret);
200 CHECK_EQ_RETURN(hdfDev.service, NULL, ret);
201
202 PLAT_LOGD("PlatformDeviceTestBindDevice: exit!");
203 return HDF_SUCCESS;
204 }
205
PlatformDeviceTestReliability(struct PlatformDevice * device)206 static int32_t PlatformDeviceTestReliability(struct PlatformDevice *device)
207 {
208 int32_t ret;
209 uint32_t events;
210 struct HdfDeviceObject hdfDev;
211 struct PlatformDevice *devGet = NULL;
212
213 PLAT_LOGD("PlatformDeviceTestReliability: enter!");
214 device->name = "platform_device_test_reliability";
215 ret = PlatformDeviceInit(NULL);
216 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
217
218 PlatformDeviceUninit(NULL);
219
220 ret = PlatformDeviceSetName(NULL, "device_name");
221 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
222
223 ret = PlatformDeviceSetName(device, NULL);
224 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
225 PlatformDeviceClearName(device);
226
227 ret = PlatformDeviceGet(NULL);
228 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
229 PlatformDevicePut(NULL);
230
231 ret = PlatformDeviceRefCount(NULL);
232 CHECK_LT_RETURN(ret, 0, HDF_FAILURE);
233
234 ret = PlatformDevicePostEvent(NULL, 0x1);
235 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
236
237 ret = PlatformDeviceWaitEvent(NULL, 0x1, 1, &events);
238 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
239
240 ret = PlatformDeviceAdd(NULL);
241 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
242 PlatformDeviceDel(NULL);
243
244 ret = PlatformDeviceCreateService(NULL, TestDispatch);
245 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
246 PlatformDeviceDestroyService(NULL);
247
248 ret = PlatformDeviceBind(device, NULL);
249 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
250 ret = PlatformDeviceBind(NULL, &hdfDev);
251 CHECK_NE_RETURN(ret, HDF_SUCCESS, HDF_FAILURE);
252 PlatformDeviceUnbind(device, NULL);
253 PlatformDeviceUnbind(NULL, NULL);
254
255 devGet = PlatformDeviceFromHdfDev(NULL);
256 CHECK_NULL_RETURN(devGet, HDF_FAILURE);
257
258 PLAT_LOGD("PlatformDeviceTestReliability: exit!");
259 return HDF_SUCCESS;
260 }
261
262 struct PlatformDeviceTestEntry {
263 int cmd;
264 int32_t (*func)(struct PlatformDevice *device);
265 const char *name;
266 };
267
268 static struct PlatformDeviceTestEntry g_entry[] = {
269 { PLAT_DEVICE_TEST_SET_NAME, PlatformDeviceTestSetName, "PlatformDeviceTestReliability" },
270 { PLAT_DEVICE_TEST_GET_DEVICE, PlatformDeviceTestGetDevice, "PlatformDeviceTestGetDevice" },
271 { PLAT_DEVICE_TEST_WAIT_EVENT, PlatformDeviceTestWaitEvent, "PlatformDeviceTestWaitEvent" },
272 { PLAT_DEVICE_TEST_ADD_DEVICE, PlatformDeviceTestAddDevice, "PlatformDeviceTestAddDevice" },
273 { PLAT_DEVICE_TEST_CREATE_SERVICE, PlatformDeviceTestCreateService, "PlatformDeviceTestCreateService" },
274 { PLAT_DEVICE_TEST_BIND_DEVICE, PlatformDeviceTestBindDevice, "PlatformDeviceTestBindDevice" },
275 { PLAT_DEVICE_TEST_RELIABILITY, PlatformDeviceTestReliability, "PlatformDeviceTestReliability" },
276 };
277
PlatformDeviceTestExecute(int cmd)278 int PlatformDeviceTestExecute(int cmd)
279 {
280 uint32_t i;
281 int32_t ret = HDF_ERR_NOT_SUPPORT;
282 struct PlatformDevice device = {0};
283 struct PlatformDeviceTestEntry *entry = NULL;
284
285 if (cmd > PLAT_DEVICE_TEST_CMD_MAX) {
286 PLAT_LOGE("PlatformDeviceTestExecute: invalid cmd:%d", cmd);
287 ret = HDF_ERR_NOT_SUPPORT;
288 PLAT_LOGE("[PlatformDeviceTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
289 return ret;
290 }
291
292 for (i = 0; i < (sizeof(g_entry) / sizeof(g_entry[0])); i++) {
293 if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
294 continue;
295 }
296 entry = &g_entry[i];
297 break;
298 }
299
300 if (entry == NULL) {
301 PLAT_LOGE("PlatformDeviceTestExecute: no entry matched, cmd = %d!", cmd);
302 return HDF_ERR_NOT_SUPPORT;
303 }
304
305 if ((ret = PlatformDeviceInit(&device)) != HDF_SUCCESS) {
306 PLAT_LOGE("PlatformDeviceTestExecute: init failed, ret = %d!", ret);
307 return ret;
308 }
309
310 ret = entry->func(&device);
311 PlatformDeviceUninit(&device);
312
313 PLAT_LOGE("[PlatformDeviceTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
314 return ret;
315 }
316
PlatformDeviceTestExecuteAll(void)317 void PlatformDeviceTestExecuteAll(void)
318 {
319 int32_t i;
320 int32_t ret;
321 int32_t fails = 0;
322
323 for (i = 0; i < PLAT_DEVICE_TEST_CMD_MAX; i++) {
324 ret = PlatformDeviceTestExecute(i);
325 fails += (ret != HDF_SUCCESS) ? 1 : 0;
326 }
327
328 PLAT_LOGE("PlatformDeviceTestExecuteALL: **********PASS:%d FAIL:%d************\n\n",
329 PLAT_DEVICE_TEST_CMD_MAX - fails, fails);
330 }
331