1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/device.h>
6 #include <ddk/driver.h>
7 #include <ddk/binding.h>
8 #include <ddk/protocol/test.h>
9
10 #include <unittest/unittest.h>
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <limits.h>
16
17 extern struct test_case_element* test_case_ddk_metadata;
18 extern struct test_case_element* test_case_ddk_usb_request;
19
20 zx_device_t* ddk_test_dev;
21
ddk_test_output_func(const char * line,int len,void * arg)22 static void ddk_test_output_func(const char* line, int len, void* arg) {
23 zx_handle_t h = *(zx_handle_t*)arg;
24 // len is not actually the number of bytes to output
25 zx_socket_write(h, 0u, line, strlen(line), NULL);
26 }
27
update_test_report(bool success,test_report_t * report)28 static void update_test_report(bool success, test_report_t* report) {
29 report->n_tests++;
30 if (success) {
31 report->n_success++;
32 } else {
33 report->n_failed++;
34 }
35 }
36
ddk_test_func(void * cookie,test_report_t * report)37 static zx_status_t ddk_test_func(void* cookie, test_report_t* report) {
38 zx_device_t* dev = (zx_device_t*)cookie;
39
40 test_protocol_t proto;
41 zx_status_t status = device_get_protocol(dev, ZX_PROTOCOL_TEST, &proto);
42 if (status != ZX_OK) {
43 return status;
44 }
45
46 zx_handle_t output;
47 proto.ops->get_output_socket(proto.ctx, &output);
48 if (output != ZX_HANDLE_INVALID) {
49 unittest_set_output_function(ddk_test_output_func, &output);
50 }
51
52 memset(report, 0, sizeof(*report));
53 update_test_report(unittest_run_one_test(test_case_ddk_metadata, TEST_ALL), report);
54 update_test_report(unittest_run_one_test(test_case_ddk_usb_request, TEST_ALL), report);
55 unittest_restore_output_function();
56 zx_handle_close(output);
57 return report->n_failed == 0 ? ZX_OK : ZX_ERR_INTERNAL;
58 }
59
ddk_test_bind(void * ctx,zx_device_t * parent)60 zx_status_t ddk_test_bind(void* ctx, zx_device_t* parent) {
61 test_protocol_t proto;
62 zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_TEST, &proto);
63 if (status != ZX_OK) {
64 return status;
65 }
66
67 ddk_test_dev = parent;
68 proto.ops->set_test_func(proto.ctx, &(test_func_t){ddk_test_func, parent});
69 return ZX_OK;
70 }
71