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