// Copyright 2020 The Chromium OS 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 "typecd/port.h"

#include <string>

#include <base/files/scoped_temp_dir.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "typecd/test_constants.h"
#include "typecd/test_utils.h"

namespace {
constexpr char kInvalidDataRole1[] = "xsadft [hasdr]";
constexpr char kInvalidDataRole2[] = "]asdf[ dsdd";
constexpr char kValidDataRole1[] = "device";
constexpr char kValidDataRole2[] = "[host] device";
constexpr char kValidDataRole3[] = "host [device]";

constexpr char kValidPowerRole1[] = "[source] sink";
constexpr char kValidPowerRole2[] = "source [sink]";
constexpr char kInvalidPowerRole1[] = "asdf#//%sxdfa";
}  // namespace

namespace typecd {

class PortTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    temp_dir_ = scoped_temp_dir_.GetPath();
  }

 public:
  base::FilePath temp_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

// Check that basic Port creation, partner addition/deletion works.
TEST_F(PortTest, BasicAdd) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);
  EXPECT_NE(nullptr, port);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  EXPECT_NE(nullptr, port->partner_);
  port->RemovePartner();
  EXPECT_EQ(nullptr, port->partner_);
}

// Check GetDataRole() for various sysfs values.
TEST_F(PortTest, GetDataRole) {
  // Set up fake sysfs directory for the port..
  auto port_path = temp_dir_.Append("port0");
  ASSERT_TRUE(base::CreateDirectory(port_path));

  auto data_role_path = port_path.Append("data_role");
  ASSERT_TRUE(base::WriteFile(data_role_path, kValidDataRole1,
                              strlen(kValidDataRole1)));

  // Create a port.
  auto port = std::make_unique<Port>(base::FilePath(port_path), 0);
  ASSERT_NE(nullptr, port);

  EXPECT_EQ(DataRole::kDevice, port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(data_role_path, kValidDataRole2,
                              strlen(kValidDataRole2)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(DataRole::kHost, port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kValidDataRole3,
                              strlen(kValidDataRole3)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(DataRole::kDevice, port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kInvalidDataRole1,
                              strlen(kInvalidDataRole1)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(DataRole::kNone, port->GetDataRole());

  ASSERT_TRUE(base::WriteFile(port_path.Append("data_role"), kInvalidDataRole2,
                              strlen(kInvalidDataRole2)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(DataRole::kNone, port->GetDataRole());
}

// Check GetPowerRole() for various sysfs values.
TEST_F(PortTest, GetPowerRole) {
  // Set up fake sysfs directory for the port..
  auto port_path = temp_dir_.Append("port0");
  ASSERT_TRUE(base::CreateDirectory(port_path));

  auto data_role_path = port_path.Append("power_role");
  ASSERT_TRUE(base::WriteFile(data_role_path, kValidPowerRole1,
                              strlen(kValidPowerRole1)));

  // Create a port.
  auto port = std::make_unique<Port>(base::FilePath(port_path), 0);
  ASSERT_NE(nullptr, port);

  EXPECT_EQ(PowerRole::kSource, port->GetPowerRole());

  ASSERT_TRUE(base::WriteFile(data_role_path, kValidPowerRole2,
                              strlen(kValidPowerRole2)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(PowerRole::kSink, port->GetPowerRole());

  ASSERT_TRUE(base::WriteFile(data_role_path, kInvalidPowerRole1,
                              strlen(kInvalidPowerRole1)));
  // Fake a port changed event.
  port->PortChanged();
  EXPECT_EQ(PowerRole::kNone, port->GetPowerRole());
}

// Check that DP Alt Mode Entry checks work as expected for a true case:
TEST_F(PortTest, DPAltModeEntryCheckTrue) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));

  // Set up fake sysfs paths for 1 alt mode.
  // Set the number of alt modes supported.
  port->partner_->SetNumAltModes(1);

  // Add the DP alt mode.
  std::string mode0_dirname =
      base::StringPrintf("port%d-partner.%d", 0, kDPAltModeIndex);
  auto mode0_path = temp_dir_.Append(mode0_dirname);
  ASSERT_TRUE(CreateFakeAltMode(mode0_path, kDPAltModeSID, kDPVDO_WD19TB,
                                kDPVDOIndex_WD19TB));
  port->AddRemovePartnerAltMode(mode0_path, true);

  AddAnkerUSB3p2Gen2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry checks work as expected for a specific false
// case: The Startech dock DP VDO doesn't advertise DFP_D, so we *shouldn't*
// enter DP alternate mode, despite it supporting the DP SID.
TEST_F(PortTest, DPAltModeEntryCheckFalseWithDPSID) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddStartechDock(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_FALSE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry checks work as expected for false cases.
TEST_F(PortTest, DPAltModeEntryCheckFalse) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  port->AddPartner(base::FilePath(kFakePort0PartnerSysPath));
  port->partner_->SetNumAltModes(0);

  // Check the case where the partner doesn't support any alt modes.
  EXPECT_FALSE(port->CanEnterDPAltMode(nullptr));

  port->partner_->SetNumAltModes(1);

  // Set up fake sysfs paths for 1 alt mode.
  // Add the TBT alt mode.
  std::string mode_dirname = base::StringPrintf("port%d-partner.%d", 0, 0);
  auto mode_path = temp_dir_.Append(mode_dirname);
  ASSERT_TRUE(
      CreateFakeAltMode(mode_path, kTBTAltModeVID, kTBTVDO, kTBTVDOIndex));
  port->AddRemovePartnerAltMode(mode_path, true);

  EXPECT_FALSE(port->CanEnterDPAltMode(nullptr));
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode and the CalDigit
// TBT4 cable supports up to USB4 so it should enter DP alternate mode and the
// cable will not be flagged as invalid
TEST_F(PortTest, DPAltModeEntryCalDigitTBT4ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddCalDigitTBT4Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode and the Anker
// USB3.2 Gen2 cable supports USB3 so it should enter DP alternate mode and
// the cable will not be flagged as invalid
TEST_F(PortTest, DPAltModeEntryAnkerUsb3Gen2ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddAnkerUSB3p2Gen2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode and the HP
// USB3.2 Gen1 cable supports up to USB3.2 Gen1 so it should enter DP
// alternate mode and the cable will not be flagged as invalid
TEST_F(PortTest, DPAltModeEntryHPUsb3Gen1ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddHPUSB3p2Gen1Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode and the Apple
// TBT3 Pro cable supports up to USB4 so it should enter DP alternate mode
// and the cable will not be flagged as invalid
TEST_F(PortTest, DPAltModeEntryAppleTBT3ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddAppleTBT3ProCable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a failing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode but, an unbranded
// USB2 cable is not considered as a cable object in typecd. It should still try
// to enter alternate mode but the cable will be flagged as invalid
TEST_F(PortTest, DPAltModeEntryUnbrandedUSB2ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddUnbrandedUSB2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_TRUE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a failing case.
// Case: The WIMAXIT Type-C display supports DP alternate mode but, a tested
// Nekteck cable only supports up to USB2. The typec daemon should still try
// to enter alternate mode but the cable will be flagged as invalid
TEST_F(PortTest, DPAltModeEntryNekteckUSB2ToDisplay) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddNekteckUSB2PassiveCable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_TRUE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: The Thinkpad Dock supports DP alternate mode and a tested unbranded
// TBT3 cable supports up to USB3.2 Gen2 so it should enter DP alternate mode
// and the cable will not be flagged as invalid
TEST_F(PortTest, DPAltModeEntryTBT3ToDock) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddThinkpadTBT3Dock(*port);
  AddUnbrandedTBT3Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a failing case.
// Case: The Thinkpad Dock supports DP alternate mode but a tested unbranded
// USB2 cable is not recognized by the typec daemon. It should try to enter
// DP alternate mode but the cable will be flagged as invalid.
TEST_F(PortTest, DPAltModeEntryUnbrandedUSB2ToDock) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddThinkpadTBT3Dock(*port);
  AddUnbrandedUSB2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_TRUE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a failing case.
// Case: The Thinkpad Dock supports DP alternate mode but a tested Nekteck
// type-c cable only supports up to USB2. The typec daemon should try to
// enter DP alternate mode but the cable will be flagged as invalid.
TEST_F(PortTest, DPAltModeEntryNekteckUSB2ToDock) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddThinkpadTBT3Dock(*port);
  AddNekteckUSB2PassiveCable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_TRUE(invalid_dpalt_cable);
}

// Check that DP Alt Mode Entry works with cable check for a passing case.
// Case: A small Cable Matters dock uses a captive cable. The type-c daemon
// will not recognize a cable for this dock, but because the partner notes it
// uses a captive cable typecd should enter DP Alt Mode without flagging the
// cable as invalid
TEST_F(PortTest, DPAltModeEntryCableMattersDock) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddCableMattersDock(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// working case:
// - Startech.com TB3DK2DPW Alpine Ridge Dock.
// - StarTech Passive Cable 40 Gbps PD 2.0
TEST_F(PortTest, TBTCompatibilityModeEntryCheckTrueStartech) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddStartechTB3DK2DPWDock(*port);
  AddStartech40GbpsCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterTBTCompatibilityMode());
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// non-working case:
// - Startech.com TB3DK2DPW Alpine Ridge Dock.
// - Nekteck USB 2.0 cable (5A).
TEST_F(PortTest, TBTCompatibilityModeEntryCheckFalseStartech) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddStartechTB3DK2DPWDock(*port);
  AddNekteckUSB2PassiveCable(*port);

  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterTBTCompatibilityMode());
}

// Check that TBT Compat Mode Entry checks work as expected for the following
// working case:
// - Dell WD19TB dock.
TEST_F(PortTest, TBTCompatibilityModeEntryCheckTrueWD19TB) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddDellWD19TBDock(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterTBTCompatibilityMode());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Belkin TBT3 Passive Cable 40Gbps.
TEST_F(PortTest, USB4EntryTrueGatkexPassiveTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddIntelUSB4GatkexCreekDock(*port);
  AddBelkinTBT3PassiveCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Hongju Full USB 3.1 Gen 1 5A passive cable..
TEST_F(PortTest, USB4EntryTrueGatkexPassiveNonTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddIntelUSB4GatkexCreekDock(*port);
  AddHongjuUSB3p1Gen1Cable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// non-working case:
// - Intel Gatkex Creek USB4 dock.
// - Nekteck USB 2.0 5A Passive Cable.
TEST_F(PortTest, USB4EntryFalseGatkexPassiveNonTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddIntelUSB4GatkexCreekDock(*port);
  AddNekteckUSB2PassiveCable(*port);

  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// non-working case:
// - Intel Gatkex Creek USB4 dock.
// - Belkin TBT3 Active Cable 40Gbps.
//
// NOTE: This case is interesting because the TBT3 cable fails as it doesn't
// support Rounded Data rates.
TEST_F(PortTest, USB4EntryFalseGatkexActiveTBT3Cable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddIntelUSB4GatkexCreekDock(*port);
  AddBelkinTBT3ActiveCable(*port);

  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterUSB4());
}

// Check that USB4 mode checks work as expected for the following
// working case:
// - Intel Gatkex Creek USB4 dock.
// - Apple Thunderbolt 3 Pro Cable.
TEST_F(PortTest, USB4EntryTrueGatkexAppleTBT3ProCable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddIntelUSB4GatkexCreekDock(*port);
  AddAppleTBT3ProCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
}

// Check that USB4 device will enter TBT3 mode if the  cable does not support
// USB4.
// Case: Thunderbolt 4 OWC dock connected with Belkin active TBT3 cable.
TEST_F(PortTest, USB4ToTBT) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddBelkinTBT3ActiveCable(*port);

  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterUSB4());
  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterTBTCompatibilityMode());
}

// Check that USB4 device will enter DPAltMode if the cable does not support
// USB4 or TBT.
// Case: Thunderbolt 4 OWC dock connected with unbranded USB2 cable.
TEST_F(PortTest, USB4ToDPAltMode) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddUnbrandedUSB2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterUSB4());
  EXPECT_EQ(ModeEntryResult::kCableError, port->CanEnterTBTCompatibilityMode());
  // Cable is flagged as invalid, but typecd will still enter DPAltMode. For
  // DPAltMode, the cable check is not a condition for mode entry.
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_TRUE(invalid_dpalt_cable);
}

// Check that CableLimitingUSBSpeed works for "false" case.
// Case: Thunderbolt 4 OWC dock connected with CalDigit Thunderbolt 4 cable.
TEST_F(PortTest, USB4LimitedByCableFalse) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddCalDigitTBT4Cable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
  EXPECT_FALSE(port->CableLimitingUSBSpeed());
}

// Check that CableLimitingUSBSpeed works for "true" case.
// Case: Thunderbolt 4 OWC dock connected with Cable Matters USB4 20Gbps cable.
TEST_F(PortTest, USB4LimitedByCableTrue) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddCableMatters20GbpsCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
  EXPECT_TRUE(port->CableLimitingUSBSpeed());
}

// Check that CableLimitingUSBSpeed works for "false" case with passive TBT3
// (USB 3.2 Gen2) Cable.
// Case: Thunderbolt 4 OWC dock connected with unbranded TBT3 cable.
TEST_F(PortTest, USB4LimitedByTBT3PassiveCableFalse) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddUnbrandedTBT3Cable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
  EXPECT_FALSE(port->CableLimitingUSBSpeed());
}

// Check that CableLimitingUSBSpeed works for "false" case with passive TBT4
// (USB 3.2 Gen2) LRD Cable.
// Case: Thunderbolt 4 OWC dock connected with Cable Matters TBT4 LRD cable.
TEST_F(PortTest, USB4LimitedByTBT4PassiveLRDCableFalse) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddCableMattersTBT4LRDCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
  EXPECT_FALSE(port->CableLimitingUSBSpeed());
}

// Check that CableLimitingUSBSpeed works for a case with AMA VDO.
// Case: WIMAXIT display connected with Anker USB 3.2 Gen2 cable.
TEST_F(PortTest, BillboardOnlyDisplayNotLimitedByCable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddWimaxitDisplay(*port);
  AddAnkerUSB3p2Gen2Cable(*port);

  bool invalid_dpalt_cable = false;
  EXPECT_TRUE(port->CanEnterDPAltMode(&invalid_dpalt_cable));
  EXPECT_FALSE(invalid_dpalt_cable);
  EXPECT_FALSE(port->CableLimitingUSBSpeed());
}

// Check that CableLimitingUSBSpeed() returns false for cases using a TBT3
// active cable for USB4.
// Case: Thunderbolt 4 OWC dock with Apple Thunderbolt 3 Pro Cable.
TEST_F(PortTest, CableLimitingSpeedOWCDockAppleTBT3ProCable) {
  auto port = std::make_unique<Port>(base::FilePath(kFakePort0SysPath), 0);

  AddOWCTBT4Dock(*port);
  AddAppleTBT3ProCable(*port);

  EXPECT_EQ(ModeEntryResult::kSuccess, port->CanEnterUSB4());
  EXPECT_FALSE(port->CableLimitingUSBSpeed());
}

}  // namespace typecd
