blob: 551287589673fb93fefebb6bcf3365bfbae5ffda [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "usb/request-cpp.h"
#include <unittest/unittest.h>
namespace {
using Request = usb::Request<void>;
constexpr size_t kParentReqSize = sizeof(usb_request_t);
constexpr size_t kReqSize = Request::RequestSize(kParentReqSize);
bool TrivialLifetimeTest() {
BEGIN_TEST;
usb::RequestQueue<void> queue;
usb::UnownedRequestQueue<void> unowned_queue;
END_TEST;
}
bool SingleRequestTest() {
BEGIN_TEST;
std::optional<Request> request;
ASSERT_EQ(Request::Alloc(&request, 0, 0, kReqSize),
ZX_OK);
usb::RequestQueue<void> queue;
EXPECT_TRUE(queue.pop() == std::nullopt);
queue.push(std::move(*request));
EXPECT_TRUE(queue.pop() != std::nullopt);
EXPECT_TRUE(queue.pop() == std::nullopt);
END_TEST;
}
bool MultipleRequestTest() {
BEGIN_TEST;
usb::RequestQueue<void> queue;
for (size_t i = 0; i < 10; i++) {
std::optional<Request> request;
ASSERT_EQ(Request::Alloc(&request, 0, 0, kReqSize),
ZX_OK);
queue.push(std::move(*request));
}
for (size_t i = 0; i < 10; i++) {
EXPECT_TRUE(queue.pop() != std::nullopt);
}
EXPECT_TRUE(queue.pop() == std::nullopt);
END_TEST;
}
bool ReleaseTest() {
BEGIN_TEST;
usb::RequestQueue<void> queue;
for (size_t i = 0; i < 10; i++) {
std::optional<Request> request;
ASSERT_EQ(Request::Alloc(&request, 0, 0, kReqSize),
ZX_OK);
queue.push(std::move(*request));
}
queue.release();
EXPECT_TRUE(queue.pop() == std::nullopt);
END_TEST;
}
bool MultipleLayerTest() {
BEGIN_TEST;
constexpr size_t kBaseReqSize = sizeof(usb_request_t);
constexpr size_t kFirstLayerReqSize = Request::RequestSize(kBaseReqSize);
constexpr size_t kSecondLayerReqSize = Request::RequestSize(kFirstLayerReqSize);
usb::RequestQueue<void> queue;
for (size_t i = 0; i < 10; i++) {
std::optional<Request> request;
ASSERT_EQ(Request::Alloc(&request, 0, 0, kSecondLayerReqSize, kBaseReqSize),
ZX_OK);
queue.push(std::move(*request));
}
usb::UnownedRequestQueue<void> queue2;
size_t count = 0;
for (auto request = queue.pop(); request; request = queue.pop()) {
usb::UnownedRequest unowned(request->take(), kFirstLayerReqSize);
queue2.push(std::move(unowned));
++count;
}
EXPECT_EQ(count, 10);
count = 0;
for (auto unowned = queue2.pop(); unowned; unowned = queue2.pop()) {
Request request(unowned->take(), kFirstLayerReqSize);
queue.push(std::move(request));
++count;
}
EXPECT_EQ(count, 10);
END_TEST;
}
bool MultipleLayerWithStorageTest() {
BEGIN_TEST;
using FirstLayerReq = usb::Request<uint64_t>;
using SecondLayerReq = usb::UnownedRequest<char>;
constexpr size_t kBaseReqSize = sizeof(usb_request_t);
constexpr size_t kFirstLayerReqSize = FirstLayerReq::RequestSize(kBaseReqSize);
constexpr size_t kSecondLayerReqSize = SecondLayerReq::RequestSize(kFirstLayerReqSize);
usb::RequestQueue<uint64_t> queue;
for (size_t i = 0; i < 10; i++) {
std::optional<FirstLayerReq> request;
ASSERT_EQ(FirstLayerReq::Alloc(&request, 0, 0, kSecondLayerReqSize, kBaseReqSize),
ZX_OK);
*request->private_storage() = i;
EXPECT_EQ(*request->private_storage(), i);
queue.push(std::move(*request));
}
usb::UnownedRequestQueue<char> queue2;
size_t count = 0;
for (auto request = queue.pop(); request; request = queue.pop()) {
SecondLayerReq unowned(request->take(), kFirstLayerReqSize);
*unowned.private_storage() = static_cast<char>('a' + count);
queue2.push(std::move(unowned));
++count;
}
EXPECT_EQ(count, 10);
count = 0;
for (auto unowned = queue2.pop(); unowned; unowned = queue2.pop()) {
EXPECT_EQ(*unowned->private_storage(), static_cast<char>('a' + count));
FirstLayerReq request(unowned->take(), kBaseReqSize);
EXPECT_EQ(*request.private_storage(), count);
queue.push(std::move(request));
++count;
}
EXPECT_EQ(count, 10);
END_TEST;
}
} // namespace
BEGIN_TEST_CASE(UsbRequestQueueTests)
RUN_TEST_SMALL(TrivialLifetimeTest)
RUN_TEST_SMALL(SingleRequestTest)
RUN_TEST_SMALL(MultipleRequestTest)
RUN_TEST_SMALL(ReleaseTest)
RUN_TEST_SMALL(MultipleLayerTest)
RUN_TEST_SMALL(MultipleLayerWithStorageTest)
END_TEST_CASE(UsbRequestQueueTests);