blob: 224802b9b382d54e90fb12bf950e4c8138a84b14 [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().
28 void InjectTestLibUsbTransfer() {
29 transfer_.transfer_ = &test_transfer_;
30 }
31
32 // Pretends the transfer has been submitted and is still in progress.
33 void PretendTransferInProgress() {
34 original_transfer_state_ = transfer_.state_;
35 transfer_.state_ = UsbTransfer::kInProgress;
36 }
37
38 // Pretends the transfer is being cancelled.
39 void PretendTransferBeingCancelled() {
40 original_transfer_state_ = transfer_.state_;
41 transfer_.state_ = UsbTransfer::kCancelling;
42 }
43
44 UsbTransfer transfer_;
45 UsbTransfer::State original_transfer_state_;
46 libusb_transfer test_transfer_;
47};
48
49TEST_F(UsbTransferTest, DefaultConstructor) {
Ben Chan61ac5ba2014-08-29 18:06:43 -070050 EXPECT_EQ(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -070051 EXPECT_EQ(0, transfer_.buffer_length());
52 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
53 EXPECT_TRUE(transfer_.error().IsSuccess());
54}
55
56TEST_F(UsbTransferTest, GetType) {
57 EXPECT_EQ(kUsbTransferTypeUnknown, transfer_.GetType());
58
59 InjectTestLibUsbTransfer();
60
61 test_transfer_.type = LIBUSB_TRANSFER_TYPE_CONTROL;
62 EXPECT_EQ(kUsbTransferTypeControl, transfer_.GetType());
63
64 test_transfer_.type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
65 EXPECT_EQ(kUsbTransferTypeIsochronous, transfer_.GetType());
66
67 test_transfer_.type = LIBUSB_TRANSFER_TYPE_BULK;
68 EXPECT_EQ(kUsbTransferTypeBulk, transfer_.GetType());
69
70 test_transfer_.type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
71 EXPECT_EQ(kUsbTransferTypeInterrupt, transfer_.GetType());
72}
73
74TEST_F(UsbTransferTest, GetStatus) {
75 EXPECT_EQ(kUsbTransferStatusUnknown, transfer_.GetStatus());
76
77 InjectTestLibUsbTransfer();
78
79 test_transfer_.status = LIBUSB_TRANSFER_COMPLETED;
80 EXPECT_EQ(kUsbTransferStatusCompleted, transfer_.GetStatus());
81
82 test_transfer_.status = LIBUSB_TRANSFER_ERROR;
83 EXPECT_EQ(kUsbTransferStatusError, transfer_.GetStatus());
84
85 test_transfer_.status = LIBUSB_TRANSFER_TIMED_OUT;
86 EXPECT_EQ(kUsbTransferStatusTimedOut, transfer_.GetStatus());
87
88 test_transfer_.status = LIBUSB_TRANSFER_CANCELLED;
89 EXPECT_EQ(kUsbTransferStatusCancelled, transfer_.GetStatus());
90
91 test_transfer_.status = LIBUSB_TRANSFER_STALL;
92 EXPECT_EQ(kUsbTransferStatusStall, transfer_.GetStatus());
93
94 test_transfer_.status = LIBUSB_TRANSFER_NO_DEVICE;
95 EXPECT_EQ(kUsbTransferStatusNoDevice, transfer_.GetStatus());
96
97 test_transfer_.status = LIBUSB_TRANSFER_OVERFLOW;
98 EXPECT_EQ(kUsbTransferStatusOverflow, transfer_.GetStatus());
99}
100
101TEST_F(UsbTransferTest, GetLength) {
102 EXPECT_EQ(0, transfer_.GetLength());
103
104 InjectTestLibUsbTransfer();
105
106 test_transfer_.length = 20;
107 EXPECT_EQ(test_transfer_.length, transfer_.GetLength());
108}
109
110TEST_F(UsbTransferTest, GetActualLength) {
111 EXPECT_EQ(0, transfer_.GetLength());
112
113 InjectTestLibUsbTransfer();
114
115 test_transfer_.actual_length = 10;
116 EXPECT_EQ(test_transfer_.actual_length, transfer_.GetActualLength());
117}
118
Ben Chan72643922013-09-17 00:36:25 -0700119TEST_F(UsbTransferTest, IsCompletedWithExpectedLength) {
120 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(0));
121
122 InjectTestLibUsbTransfer();
123
124 test_transfer_.actual_length = 5;
125 test_transfer_.status = LIBUSB_TRANSFER_COMPLETED;
126 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
127
128 test_transfer_.actual_length = 10;
129 EXPECT_TRUE(transfer_.IsCompletedWithExpectedLength(10));
130
131 test_transfer_.status = LIBUSB_TRANSFER_ERROR;
132 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
133
134 test_transfer_.status = LIBUSB_TRANSFER_TIMED_OUT;
135 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
136
137 test_transfer_.status = LIBUSB_TRANSFER_CANCELLED;
138 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
139
140 test_transfer_.status = LIBUSB_TRANSFER_STALL;
141 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
142
143 test_transfer_.status = LIBUSB_TRANSFER_NO_DEVICE;
144 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
145
146 test_transfer_.status = LIBUSB_TRANSFER_OVERFLOW;
147 EXPECT_FALSE(transfer_.IsCompletedWithExpectedLength(10));
148}
149
Ben Chande490152013-05-29 17:05:49 -0700150TEST_F(UsbTransferTest, VerifyAllocated) {
151 EXPECT_FALSE(transfer_.VerifyAllocated());
152 EXPECT_EQ(UsbError::kErrorTransferNotAllocated, transfer_.error().type());
153}
154
155TEST_F(UsbTransferTest, AllocateAfterAllocate) {
156 InjectTestLibUsbTransfer();
157 EXPECT_FALSE(transfer_.Allocate(0));
158 EXPECT_EQ(UsbError::kErrorTransferAlreadyAllocated, transfer_.error().type());
159}
160
161TEST_F(UsbTransferTest, FreeBeforeAllocate) {
162 // Free() without calling Allocate() should be ok.
163 transfer_.Free();
164}
165
166TEST_F(UsbTransferTest, AllocateBuffer) {
167 // Allocate a zero-size buffer should be ok.
168 EXPECT_TRUE(transfer_.AllocateBuffer(0));
Ben Chan61ac5ba2014-08-29 18:06:43 -0700169 EXPECT_NE(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -0700170 EXPECT_EQ(0, transfer_.buffer_length());
171
172 // Re-allocate the buffer should be ok.
Ben Chan956f79b2014-08-06 17:11:01 -0700173 const uint8_t kTestData[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Ben Chande490152013-05-29 17:05:49 -0700174 EXPECT_TRUE(transfer_.AllocateBuffer(arraysize(kTestData)));
Ben Chan61ac5ba2014-08-29 18:06:43 -0700175 EXPECT_NE(nullptr, transfer_.buffer());
Ben Chande490152013-05-29 17:05:49 -0700176 EXPECT_EQ(arraysize(kTestData), transfer_.buffer_length());
177 // Write to the allocated buffer and then read from it to ensure the buffer
178 // is properly allocated.
179 memcpy(transfer_.buffer(), kTestData, arraysize(kTestData));
180 EXPECT_EQ(0, memcmp(transfer_.buffer(), kTestData, arraysize(kTestData)));
181}
182
183TEST_F(UsbTransferTest, AllocateBufferAfterSubmit) {
184 PretendTransferInProgress();
185 EXPECT_FALSE(transfer_.AllocateBuffer(0));
186 EXPECT_EQ(UsbTransfer::kInProgress, transfer_.state());
187 EXPECT_EQ(UsbError::kErrorTransferAlreadySubmitted, transfer_.error().type());
188}
189
190TEST_F(UsbTransferTest, SubmitBeforeAllocate) {
191 EXPECT_FALSE(transfer_.Submit(UsbTransfer::CompletionCallback()));
192 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
193 EXPECT_EQ(UsbError::kErrorTransferNotAllocated, transfer_.error().type());
194}
195
196TEST_F(UsbTransferTest, SubmitBeforeComplete) {
197 InjectTestLibUsbTransfer();
198 PretendTransferInProgress();
199 EXPECT_FALSE(transfer_.Submit(UsbTransfer::CompletionCallback()));
200 EXPECT_EQ(UsbTransfer::kInProgress, transfer_.state());
201 EXPECT_EQ(UsbError::kErrorTransferAlreadySubmitted, transfer_.error().type());
202}
203
204TEST_F(UsbTransferTest, CancelBeforeSubmit) {
205 EXPECT_FALSE(transfer_.Cancel());
206 EXPECT_EQ(UsbTransfer::kIdle, transfer_.state());
207 EXPECT_EQ(UsbError::kErrorTransferNotSubmitted, transfer_.error().type());
208}
209
210TEST_F(UsbTransferTest, CancelWhileBeingCancelled) {
211 PretendTransferBeingCancelled();
212 EXPECT_FALSE(transfer_.Cancel());
213 EXPECT_EQ(UsbTransfer::kCancelling, transfer_.state());
214 EXPECT_EQ(UsbError::kErrorTransferBeingCancelled, transfer_.error().type());
215}
216
217} // namespace mist