1// Copyright 2014 The Chromium 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 "base/bind.h" 6#include "base/message_loop/message_loop.h" 7#include "base/run_loop.h" 8#include "base/strings/utf_string_conversions.h" 9#include "device/test/usb_test_gadget.h" 10#include "device/usb/usb_device.h" 11#include "device/usb/usb_device_handle.h" 12#include "testing/gtest/include/gtest/gtest.h" 13 14namespace device { 15 16namespace { 17 18class UsbDeviceHandleTest : public ::testing::Test { 19 public: 20 virtual void SetUp() { 21 if (!UsbTestGadget::IsTestEnabled()) { 22 return; 23 } 24 25 message_loop_.reset(new base::MessageLoopForIO); 26 27 gadget_ = UsbTestGadget::Claim(); 28 ASSERT_TRUE(gadget_.get()); 29 30 ASSERT_TRUE(gadget_->SetType(UsbTestGadget::ECHO)); 31 32 handle_ = gadget_->GetDevice()->Open(); 33 ASSERT_TRUE(handle_.get()); 34 } 35 36 virtual void TearDown() { 37 if (handle_.get()) { 38 handle_->Close(); 39 } 40 gadget_.reset(NULL); 41 message_loop_.reset(NULL); 42 } 43 44 protected: 45 scoped_refptr<UsbDeviceHandle> handle_; 46 47 private: 48 scoped_ptr<UsbTestGadget> gadget_; 49 scoped_ptr<base::MessageLoop> message_loop_; 50}; 51 52class TestCompletionCallback { 53 public: 54 TestCompletionCallback() 55 : callback_(base::Bind(&TestCompletionCallback::SetResult, 56 base::Unretained(this))) {} 57 58 void SetResult(UsbTransferStatus status, 59 scoped_refptr<net::IOBuffer> buffer, 60 size_t transferred) { 61 status_ = status; 62 transferred_ = transferred; 63 run_loop_.Quit(); 64 } 65 66 void WaitForResult() { run_loop_.Run(); } 67 68 const UsbTransferCallback& callback() const { return callback_; } 69 UsbTransferStatus status() const { return status_; } 70 size_t transferred() const { return transferred_; } 71 72 private: 73 const UsbTransferCallback callback_; 74 base::RunLoop run_loop_; 75 UsbTransferStatus status_; 76 size_t transferred_; 77}; 78 79TEST_F(UsbDeviceHandleTest, InterruptTransfer) { 80 if (!handle_.get()) { 81 return; 82 } 83 84 scoped_refptr<net::IOBufferWithSize> in_buffer(new net::IOBufferWithSize(64)); 85 TestCompletionCallback in_completion; 86 handle_->InterruptTransfer(USB_DIRECTION_INBOUND, 87 0x81, 88 in_buffer.get(), 89 in_buffer->size(), 90 5000, // 5 second timeout 91 in_completion.callback()); 92 93 scoped_refptr<net::IOBufferWithSize> out_buffer( 94 new net::IOBufferWithSize(in_buffer->size())); 95 TestCompletionCallback out_completion; 96 for (int i = 0; i < out_buffer->size(); ++i) { 97 out_buffer->data()[i] = i; 98 } 99 100 handle_->InterruptTransfer(USB_DIRECTION_OUTBOUND, 101 0x01, 102 out_buffer.get(), 103 out_buffer->size(), 104 5000, // 5 second timeout 105 out_completion.callback()); 106 out_completion.WaitForResult(); 107 ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status()); 108 ASSERT_EQ(static_cast<size_t>(out_buffer->size()), 109 out_completion.transferred()); 110 111 in_completion.WaitForResult(); 112 ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status()); 113 ASSERT_EQ(static_cast<size_t>(in_buffer->size()), 114 in_completion.transferred()); 115 for (int i = 0; i < in_buffer->size(); ++i) { 116 ASSERT_EQ(out_buffer->data()[i], in_buffer->data()[i]); 117 } 118} 119 120TEST_F(UsbDeviceHandleTest, BulkTransfer) { 121 if (!handle_.get()) { 122 return; 123 } 124 125 scoped_refptr<net::IOBufferWithSize> in_buffer( 126 new net::IOBufferWithSize(512)); 127 TestCompletionCallback in_completion; 128 handle_->BulkTransfer(USB_DIRECTION_INBOUND, 129 0x81, 130 in_buffer.get(), 131 in_buffer->size(), 132 5000, // 5 second timeout 133 in_completion.callback()); 134 135 scoped_refptr<net::IOBufferWithSize> out_buffer( 136 new net::IOBufferWithSize(in_buffer->size())); 137 TestCompletionCallback out_completion; 138 for (int i = 0; i < out_buffer->size(); ++i) { 139 out_buffer->data()[i] = i; 140 } 141 142 handle_->BulkTransfer(USB_DIRECTION_OUTBOUND, 143 0x01, 144 out_buffer.get(), 145 out_buffer->size(), 146 5000, // 5 second timeout 147 out_completion.callback()); 148 out_completion.WaitForResult(); 149 ASSERT_EQ(USB_TRANSFER_COMPLETED, out_completion.status()); 150 ASSERT_EQ(static_cast<size_t>(out_buffer->size()), 151 out_completion.transferred()); 152 153 in_completion.WaitForResult(); 154 ASSERT_EQ(USB_TRANSFER_COMPLETED, in_completion.status()); 155 ASSERT_EQ(static_cast<size_t>(in_buffer->size()), 156 in_completion.transferred()); 157 for (int i = 0; i < in_buffer->size(); ++i) { 158 ASSERT_EQ(out_buffer->data()[i], in_buffer->data()[i]); 159 } 160} 161 162} // namespace 163 164} // namespace device 165