blob: 8df7ddc92f639c93cb96054123e20e4f5ecba313 [file] [log] [blame]
Ben Chande490152013-05-29 17:05:49 -07001// Copyright (c) 2013 The Chromium OS 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 "mist/usb_transfer.h"
6
7#include <libusb.h>
8
9#include <gtest/gtest.h>
10
11namespace mist {
12
13class UsbTransferTest : public testing::Test {
14 protected:
15 UsbTransferTest() : original_transfer_state_(UsbTransfer::kIdle) {}
16
17 void TearDown() {
18 // Take out the injected libusb_transfer to bypass the invocation of
19 // libusb_free_transfer() in UsbTransfer.
20 if (transfer_.transfer_ == &test_transfer_)
Ben Chan61ac5ba2014-08-29 18:06:43 -070021 transfer_.transfer_ = nullptr;
Ben Chande490152013-05-29 17:05:49 -070022
23 transfer_.state_ = original_transfer_state_;
24 }
25
26 // Temporarily injects a hand crafted libusb_transfer struct into |transfer_|
27 // for testing. The injected libusb_transfer struct is removed in TearDown().
Ben Chanc440db52017-09-26 06:30:47 -070028 void InjectTestLibUsbTransfer() { transfer_.transfer_ = &test_transfer_; }
Ben Chande490152013-05-29 17:05:49 -070029
30 // Pretends the transfer has been submitted and is still in progress.
31 void PretendTransferInProgress() {
32 original_transfer_state_ = transfer_.state_;
33 transfer_.state_ = UsbTransfer::kInProgress;
34 }
35
36 // Pretends the transfer is being cancelled.
37 void PretendTransferBeingCancelled() {
38 original_transfer_state_ = transfer_.state_;
39 transfer_.state_ = UsbTransfer::kCancelling;
40 }
41
42 UsbTransfer transfer_;
43 UsbTransfer::State original_transfer_state_;
44 libusb_transfer test_transfer_;
45};
46
47TEST_F(UsbTransferTest, DefaultConstructor) {
Ben Chan61ac5ba2014-08-29 18:06:43 -070048 EXPECT_EQ(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -070049 EXPECT_EQ(0, transfer_.buffer_length());
50 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
51 EXPECT_TRUE(transfer_.error().IsSuccess());
52}
53
54TEST_F(UsbTransferTest, GetType) {
55 EXPECT_EQ(kUsbTransferTypeUnknown, transfer_.GetType());
56
57 InjectTestLibUsbTransfer();
58
59 test_transfer_.type = LIBUSB_TRANSFER_TYPE_CONTROL;
60 EXPECT_EQ(kUsbTransferTypeControl, transfer_.GetType());
61
62 test_transfer_.type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
63 EXPECT_EQ(kUsbTransferTypeIsochronous, transfer_.GetType());
64
65 test_transfer_.type = LIBUSB_TRANSFER_TYPE_BULK;
66 EXPECT_EQ(kUsbTransferTypeBulk, transfer_.GetType());
67
68 test_transfer_.type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
69 EXPECT_EQ(kUsbTransferTypeInterrupt, transfer_.GetType());
70}
71
72TEST_F(UsbTransferTest, GetStatus) {
73 EXPECT_EQ(kUsbTransferStatusUnknown, transfer_.GetStatus());
74
75 InjectTestLibUsbTransfer();
76
77 test_transfer_.status = LIBUSB_TRANSFER_COMPLETED;
78 EXPECT_EQ(kUsbTransferStatusCompleted, transfer_.GetStatus());
79
80 test_transfer_.status = LIBUSB_TRANSFER_ERROR;
81 EXPECT_EQ(kUsbTransferStatusError, transfer_.GetStatus());
82
83 test_transfer_.status = LIBUSB_TRANSFER_TIMED_OUT;
84 EXPECT_EQ(kUsbTransferStatusTimedOut, transfer_.GetStatus());
85
86 test_transfer_.status = LIBUSB_TRANSFER_CANCELLED;
87 EXPECT_EQ(kUsbTransferStatusCancelled, transfer_.GetStatus());
88
89 test_transfer_.status = LIBUSB_TRANSFER_STALL;
90 EXPECT_EQ(kUsbTransferStatusStall, transfer_.GetStatus());
91
92 test_transfer_.status = LIBUSB_TRANSFER_NO_DEVICE;
93 EXPECT_EQ(kUsbTransferStatusNoDevice, transfer_.GetStatus());
94
95 test_transfer_.status = LIBUSB_TRANSFER_OVERFLOW;
96 EXPECT_EQ(kUsbTransferStatusOverflow, transfer_.GetStatus());
97}
98
99TEST_F(UsbTransferTest, GetLength) {
100 EXPECT_EQ(0, transfer_.GetLength());
101
102 InjectTestLibUsbTransfer();
103
104 test_transfer_.length = 20;
105 EXPECT_EQ(test_transfer_.length, transfer_.GetLength());
106}
107
108TEST_F(UsbTransferTest, GetActualLength) {
109 EXPECT_EQ(0, transfer_.GetLength());
110
111 InjectTestLibUsbTransfer();
112
113 test_transfer_.actual_length = 10;
114 EXPECT_EQ(test_transfer_.actual_length, transfer_.GetActualLength());
115}
116
Ben Chan72643922013-09-17 00:36:25 -0700117TEST_F(UsbTransferTest, IsCompletedWithExpectedLength) {
118 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(0));
119
120 InjectTestLibUsbTransfer();
121
122 test_transfer_.actual_length = 5;
123 test_transfer_.status = LIBUSB_TRANSFER_COMPLETED;
124 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
125
126 test_transfer_.actual_length = 10;
127 EXPECT_TRUE(transfer_.IsCompletedWithExpectedLength(10));
128
129 test_transfer_.status = LIBUSB_TRANSFER_ERROR;
130 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
131
132 test_transfer_.status = LIBUSB_TRANSFER_TIMED_OUT;
133 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
134
135 test_transfer_.status = LIBUSB_TRANSFER_CANCELLED;
136 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
137
138 test_transfer_.status = LIBUSB_TRANSFER_STALL;
139 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
140
141 test_transfer_.status = LIBUSB_TRANSFER_NO_DEVICE;
142 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
143
144 test_transfer_.status = LIBUSB_TRANSFER_OVERFLOW;
145 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
146}
147
Ben Chande490152013-05-29 17:05:49 -0700148TEST_F(UsbTransferTest, VerifyAllocated) {
149 EXPECT_FALSE(transfer_.VerifyAllocated());
150 EXPECT_EQ(UsbError::kErrorTransferNotAllocated, transfer_.error().type());
151}
152
153TEST_F(UsbTransferTest, AllocateAfterAllocate) {
154 InjectTestLibUsbTransfer();
155 EXPECT_FALSE(transfer_.Allocate(0));
156 EXPECT_EQ(UsbError::kErrorTransferAlreadyAllocated, transfer_.error().type());
157}
158
159TEST_F(UsbTransferTest, FreeBeforeAllocate) {
160 // Free() without calling Allocate() should be ok.
161 transfer_.Free();
162}
163
164TEST_F(UsbTransferTest, AllocateBuffer) {
165 // Allocate a zero-size buffer should be ok.
166 EXPECT_TRUE(transfer_.AllocateBuffer(0));
Ben Chan61ac5ba2014-08-29 18:06:43 -0700167 EXPECT_NE(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -0700168 EXPECT_EQ(0, transfer_.buffer_length());
169
170 // Re-allocate the buffer should be ok.
Ben Chan956f79b2014-08-06 17:11:01 -0700171 const uint8_t kTestData[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Ben Chande490152013-05-29 17:05:49 -0700172 EXPECT_TRUE(transfer_.AllocateBuffer(arraysize(kTestData)));
Ben Chan61ac5ba2014-08-29 18:06:43 -0700173 EXPECT_NE(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -0700174 EXPECT_EQ(arraysize(kTestData), transfer_.buffer_length());
175 // Write to the allocated buffer and then read from it to ensure the buffer
176 // is properly allocated.
177 memcpy(transfer_.buffer(), kTestData, arraysize(kTestData));
178 EXPECT_EQ(0, memcmp(transfer_.buffer(), kTestData, arraysize(kTestData)));
179}
180
181TEST_F(UsbTransferTest, AllocateBufferAfterSubmit) {
182 PretendTransferInProgress();
183 EXPECT_FALSE(transfer_.AllocateBuffer(0));
184 EXPECT_EQ(UsbTransfer::kInProgress, transfer_.state());
185 EXPECT_EQ(UsbError::kErrorTransferAlreadySubmitted, transfer_.error().type());
186}
187
188TEST_F(UsbTransferTest, SubmitBeforeAllocate) {
189 EXPECT_FALSE(transfer_.Submit(UsbTransfer::CompletionCallback()));
190 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
191 EXPECT_EQ(UsbError::kErrorTransferNotAllocated, transfer_.error().type());
192}
193
194TEST_F(UsbTransferTest, SubmitBeforeComplete) {
195 InjectTestLibUsbTransfer();
196 PretendTransferInProgress();
197 EXPECT_FALSE(transfer_.Submit(UsbTransfer::CompletionCallback()));
198 EXPECT_EQ(UsbTransfer::kInProgress, transfer_.state());
199 EXPECT_EQ(UsbError::kErrorTransferAlreadySubmitted, transfer_.error().type());
200}
201
202TEST_F(UsbTransferTest, CancelBeforeSubmit) {
203 EXPECT_FALSE(transfer_.Cancel());
204 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
205 EXPECT_EQ(UsbError::kErrorTransferNotSubmitted, transfer_.error().type());
206}
207
208TEST_F(UsbTransferTest, CancelWhileBeingCancelled) {
209 PretendTransferBeingCancelled();
210 EXPECT_FALSE(transfer_.Cancel());
211 EXPECT_EQ(UsbTransfer::kCancelling, transfer_.state());
212 EXPECT_EQ(UsbError::kErrorTransferBeingCancelled, transfer_.error().type());
213}
214
215} // namespace mist