From 9f485e913fb3afcba9106fa5424dead72a53bbd4 Mon Sep 17 00:00:00 2001 From: Maksim Ivanov Date: Wed, 26 Jul 2023 12:10:27 +0000 Subject: [PATCH] Unit-test libusb_get_active_config_descriptor (#848) Add a basic unit test for our libusb_get_active_config_descriptor() implementation (a.k.a LibusbJsProxy::LibusbGetActiveConfigDescriptor()). The input parameters for the test are taken from an arbitrary real-world reader (SCM SCR 3310). This commit is preparation for regression testing of #849. --- .../webport/src/libusb_js_proxy_unittest.cc | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/third_party/libusb/webport/src/libusb_js_proxy_unittest.cc b/third_party/libusb/webport/src/libusb_js_proxy_unittest.cc index af8b1bc22..026642f71 100644 --- a/third_party/libusb/webport/src/libusb_js_proxy_unittest.cc +++ b/third_party/libusb/webport/src/libusb_js_proxy_unittest.cc @@ -58,6 +58,7 @@ using testing::Invoke; using testing::InvokeWithoutArgs; using testing::Mock; using testing::MockFunction; +using testing::SizeIs; using testing::WithArgs; namespace google_smart_card { @@ -463,6 +464,134 @@ TEST_P(LibusbJsProxyTest, DeviceRefUnref) { FreeLibusbDevices(devices); } +// Test the behavior of `LibusbGetActiveConfigDescriptor()` on the parameters +// taken from the real SCM SCR 3310 device. +TEST_P(LibusbJsProxyTest, LibusbGetActiveConfigDescriptorScmScr3310) { + const std::vector kInterfaceExtraData{ + 0x36, 0x21, 0x00, 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0xa0, + 0x0f, 0x00, 0x00, 0xe0, 0x2e, 0x00, 0x00, 0x00, 0x80, 0x25, 0x00, + 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 0x01, 0x00, + 0x07, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01}; + + // Arrange. + global_context()->WillReplyToRequestWith( + "libusb", "listDevices", + /*arguments=*/Value(Value::Type::kArray), + /*result_to_reply_with=*/ + ArrayValueBuilder() + .Add(DictValueBuilder() + .Add("deviceId", 123) + .Add("vendorId", 1) + .Add("productId", 2) + .Get()) + .Get()); + std::vector devices = GetLibusbDevices(); + ASSERT_THAT(devices, SizeIs(1)); + global_context()->WillReplyToRequestWith( + "libusb", "getConfigurations", + /*arguments=*/ArrayValueBuilder().Add(123).Get(), + /*result_to_reply_with=*/ + ArrayValueBuilder() + .Add( + DictValueBuilder() + .Add("active", true) + .Add("configurationValue", 1) + .Add( + "interfaces", + ArrayValueBuilder() + .Add( + DictValueBuilder() + .Add("interfaceNumber", 0) + .Add("interfaceClass", 11) + .Add("interfaceSubclass", 0) + .Add("interfaceProtocol", 0) + .Add("extraData", kInterfaceExtraData) + .Add("endpoints", + ArrayValueBuilder() + .Add(DictValueBuilder() + .Add("endpointAddress", 1) + .Add("direction", "out") + .Add("type", "bulk") + .Add("maxPacketSize", 64) + .Get()) + .Add(DictValueBuilder() + .Add("endpointAddress", 130) + .Add("direction", "in") + .Add("type", "bulk") + .Add("maxPacketSize", 64) + .Get()) + .Add(DictValueBuilder() + .Add("endpointAddress", 131) + .Add("direction", "in") + .Add("type", "interrupt") + .Add("maxPacketSize", 16) + .Get()) + .Get()) + .Get()) + .Get()) + .Get()) + .Get()); + + // Act. + libusb_config_descriptor* descriptor = nullptr; + EXPECT_EQ(libusb()->LibusbGetActiveConfigDescriptor(devices[0], &descriptor), + LIBUSB_SUCCESS); + + // Assert. + ASSERT_TRUE(descriptor); + EXPECT_EQ(descriptor->bLength, sizeof(libusb_config_descriptor)); + EXPECT_EQ(descriptor->bDescriptorType, LIBUSB_DT_CONFIG); + EXPECT_EQ(descriptor->wTotalLength, sizeof(libusb_config_descriptor)); + EXPECT_EQ(descriptor->bConfigurationValue, 1); + EXPECT_EQ(descriptor->bNumInterfaces, 1); + EXPECT_EQ(descriptor->extra, nullptr); + EXPECT_EQ(descriptor->extra_length, 0); + const auto& interface = descriptor->interface[0]; + EXPECT_EQ(interface.num_altsetting, 1); + const auto& interface_descriptor = interface.altsetting[0]; + EXPECT_EQ(interface_descriptor.bLength, sizeof(libusb_interface_descriptor)); + EXPECT_EQ(interface_descriptor.bDescriptorType, LIBUSB_DT_INTERFACE); + EXPECT_EQ(interface_descriptor.bInterfaceNumber, 0); + EXPECT_EQ(interface_descriptor.bInterfaceClass, 11); + EXPECT_EQ(interface_descriptor.bInterfaceSubClass, 0); + EXPECT_EQ(interface_descriptor.bInterfaceProtocol, 0); + ASSERT_TRUE(interface_descriptor.extra); + ASSERT_GT(interface_descriptor.extra_length, 0); + EXPECT_EQ(std::vector( + interface_descriptor.extra, + interface_descriptor.extra + interface_descriptor.extra_length), + kInterfaceExtraData); + ASSERT_EQ(interface_descriptor.bNumEndpoints, 3); + const auto* endpoint = interface_descriptor.endpoint; + ASSERT_TRUE(endpoint); + EXPECT_EQ(endpoint[0].bLength, sizeof(libusb_endpoint_descriptor)); + EXPECT_EQ(endpoint[0].bDescriptorType, LIBUSB_DT_ENDPOINT); + EXPECT_EQ(endpoint[0].bEndpointAddress, 1); + EXPECT_EQ(endpoint[0].bmAttributes, LIBUSB_TRANSFER_TYPE_BULK); + EXPECT_EQ(endpoint[0].wMaxPacketSize, 64); + EXPECT_EQ(endpoint[0].extra, nullptr); + EXPECT_EQ(endpoint[0].extra_length, 0); + EXPECT_EQ(endpoint[1].bLength, sizeof(libusb_endpoint_descriptor)); + EXPECT_EQ(endpoint[1].bDescriptorType, LIBUSB_DT_ENDPOINT); + EXPECT_EQ(endpoint[1].bEndpointAddress, 130); + EXPECT_EQ(endpoint[1].bmAttributes, LIBUSB_TRANSFER_TYPE_BULK); + EXPECT_EQ(endpoint[1].wMaxPacketSize, 64); + EXPECT_EQ(endpoint[1].extra, nullptr); + EXPECT_EQ(endpoint[1].extra_length, 0); + EXPECT_EQ(endpoint[2].bLength, sizeof(libusb_endpoint_descriptor)); + EXPECT_EQ(endpoint[2].bDescriptorType, LIBUSB_DT_ENDPOINT); + EXPECT_EQ(endpoint[2].bEndpointAddress, 131); + EXPECT_EQ(endpoint[2].bmAttributes, LIBUSB_TRANSFER_TYPE_INTERRUPT); + EXPECT_EQ(endpoint[2].wMaxPacketSize, 16); + EXPECT_EQ(endpoint[2].extra, nullptr); + EXPECT_EQ(endpoint[2].extra_length, 0); + + // Cleanup. + libusb()->LibusbFreeConfigDescriptor(descriptor); + FreeLibusbDevices(devices); +} + // Test that `LibusbGetBusNumber()` initially returns the default bus number. TEST_P(LibusbJsProxyTest, BusNumber) { // Arrange.