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