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#include <lib/zx/socket.h> 10 11#include <unittest/unittest.h> 12#include <stddef.h> 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <limits.h> 17 18extern test_case_element* test_case_ddktl_device; 19extern test_case_element* test_case_ddktl_ethernet_device; 20 21namespace { 22 23void ddktl_test_output_func(const char* line, int len, void* arg) { 24 zx_handle_t h = *static_cast<zx_handle_t*>(arg); 25 zx::socket s(h); 26 // len is not actually the number of bytes to output 27 s.write(0u, line, strlen(line), nullptr); 28 // we don't on the socket so release it before it goes out of scope 29 h = s.release(); 30} 31 32static void inline update_test_report(bool success, test_report_t* report) { 33 report->n_tests++; 34 if (success) { 35 report->n_success++; 36 } else { 37 report->n_failed++; 38 } 39} 40 41zx_status_t ddktl_test_func(void* cookie, test_report_t* report, const void* arg, size_t arglen) { 42 auto dev = static_cast<zx_device_t*>(cookie); 43 44 test_protocol_t proto; 45 auto status = 46 device_get_protocol(dev, ZX_PROTOCOL_TEST, reinterpret_cast<void*>(&proto)); 47 if (status != ZX_OK) { 48 return status; 49 } 50 51 zx_handle_t output = proto.ops->get_output_socket(proto.ctx); 52 if (output != ZX_HANDLE_INVALID) { 53 unittest_set_output_function(ddktl_test_output_func, &output); 54 } 55 56 memset(report, 0, sizeof(*report)); 57 update_test_report(unittest_run_one_test(test_case_ddktl_device, TEST_ALL), report); 58 update_test_report(unittest_run_one_test(test_case_ddktl_ethernet_device, TEST_ALL), report); 59 return report->n_failed == 0 ? ZX_OK : ZX_ERR_INTERNAL; 60} 61 62} // namespace 63 64extern "C" zx_status_t ddktl_test_bind(void* ctx, zx_device_t* parent) { 65 test_protocol_t proto; 66 auto status = 67 device_get_protocol(parent, ZX_PROTOCOL_TEST, reinterpret_cast<void*>(&proto)); 68 if (status != ZX_OK) { 69 return status; 70 } 71 72 proto.ops->set_test_func(proto.ctx, ddktl_test_func, parent); 73 74 return ZX_OK; 75} 76