| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <map> | |
| #include <string> | |
| #include <gtest/gtest.h> | |
| #include <minigbm/minigbm_helpers.h> | |
| #include "runtime_probe/functions/gpu.h" | |
| #include "runtime_probe/utils/function_test_utils.h" | |
| namespace runtime_probe { | |
| namespace { | |
| class MockGpuFunction : public GpuFunction { | |
| using GpuFunction::GpuFunction; | |
| public: | |
| int GbmDetectDeviceInfoPath(unsigned int detect_flags, | |
| const char* dev_node, | |
| ::GbmDeviceInfo* info) const override { | |
| info->dev_type_flags = fake_gbm_dev_type_flags_; | |
| return 0; | |
| } | |
| // The fake value of gbm device type flags. | |
| int fake_gbm_dev_type_flags_ = 0; | |
| }; | |
| class GpuFunctionTest : public BaseFunctionTest { | |
| protected: | |
| void SetPciDevice(const std::string& pci_device_id, | |
| const std::map<std::string, std::string> files) { | |
| SetSymbolicLink({"../../../devices/pci0000:00/0000:00:08.1", pci_device_id}, | |
| {"sys/bus/pci/devices", pci_device_id}); | |
| for (const auto& file : files) { | |
| SetFile( | |
| {"sys/devices/pci0000:00/0000:00:08.1", pci_device_id, file.first}, | |
| file.second); | |
| } | |
| } | |
| void SetPciDeviceDrm(const std::string& pci_device_id, | |
| const std::string& drm_device_name) { | |
| // Set a fake file to create the drm device directory. | |
| SetDirectory({"sys/devices/pci0000:00/0000:00:08.1", pci_device_id, "drm", | |
| drm_device_name}); | |
| } | |
| }; | |
| TEST_F(GpuFunctionTest, ProbeGpu) { | |
| auto probe_function = CreateProbeFunction<MockGpuFunction>(); | |
| SetPciDevice("0000:04:00.0", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| // Class code 0x300001(ProgIf is 0x01) should be probed. | |
| SetPciDevice("0000:08:00.0", { | |
| {"class", "0x030001"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| // Class code 0x030200 is for 3D controller. | |
| SetPciDevice("0000:09:00.0", { | |
| {"class", "0x030200"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| auto result = EvalProbeFunction(probe_function.get()); | |
| auto ans = CreateProbeResultFromJson(R"JSON( | |
| [ | |
| { | |
| "vendor": "0x1234", | |
| "device": "0x5678", | |
| "subsystem_vendor": "0x90ab", | |
| "subsystem_device": "0xcdef" | |
| }, | |
| { | |
| "vendor": "0x1234", | |
| "device": "0x5678", | |
| "subsystem_vendor": "0x90ab", | |
| "subsystem_device": "0xcdef" | |
| }, | |
| { | |
| "vendor": "0x1234", | |
| "device": "0x5678", | |
| "subsystem_vendor": "0x90ab", | |
| "subsystem_device": "0xcdef" | |
| } | |
| ] | |
| )JSON"); | |
| EXPECT_EQ(result, ans); | |
| } | |
| TEST_F(GpuFunctionTest, NonGpu) { | |
| auto probe_function = CreateProbeFunction<MockGpuFunction>(); | |
| // Non-display controller (class it not 0x30). | |
| SetPciDevice("0000:04:00.0", { | |
| {"class", "0x020000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| // Class code 0x038000(Subclass is 0x80) should not be probed. | |
| SetPciDevice("0000:08:00.0", { | |
| {"class", "0x038000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| auto result = EvalProbeFunction(probe_function.get()); | |
| auto ans = CreateProbeResultFromJson(R"JSON( | |
| [] | |
| )JSON"); | |
| EXPECT_EQ(result, ans); | |
| } | |
| TEST_F(GpuFunctionTest, MissField) { | |
| auto probe_function = CreateProbeFunction<MockGpuFunction>(); | |
| // Each of these miss one field so won't be probed. | |
| SetPciDevice("0000:04:00.0", { | |
| {"class", "0x030000"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| SetPciDevice("0000:04:00.1", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| SetPciDevice("0000:04:00.2", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| SetPciDevice("0000:04:00.3", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| }); | |
| auto result = EvalProbeFunction(probe_function.get()); | |
| auto ans = CreateProbeResultFromJson(R"JSON( | |
| [] | |
| )JSON"); | |
| EXPECT_EQ(result, ans); | |
| } | |
| TEST_F(GpuFunctionTest, MinigbmIsDGPU) { | |
| auto probe_function = CreateProbeFunction<MockGpuFunction>(); | |
| SetPciDevice("0000:04:00.0", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| SetPciDeviceDrm("0000:04:00.0", "renderD128"); | |
| probe_function->fake_gbm_dev_type_flags_ = GBM_DEV_TYPE_FLAG_DISCRETE; | |
| auto result = EvalProbeFunction(probe_function.get()); | |
| auto ans = CreateProbeResultFromJson(R"JSON( | |
| [ | |
| { | |
| "vendor": "0x1234", | |
| "device": "0x5678", | |
| "subsystem_vendor": "0x90ab", | |
| "subsystem_device": "0xcdef" | |
| } | |
| ] | |
| )JSON"); | |
| EXPECT_EQ(result, ans); | |
| } | |
| TEST_F(GpuFunctionTest, MinigbmIsIGPU) { | |
| auto probe_function = CreateProbeFunction<MockGpuFunction>(); | |
| SetPciDevice("0000:04:00.0", { | |
| {"class", "0x030000"}, | |
| {"vendor", "0x1234"}, | |
| {"device", "0x5678"}, | |
| {"subsystem_vendor", "0x90ab"}, | |
| {"subsystem_device", "0xcdef"}, | |
| }); | |
| SetPciDeviceDrm("0000:04:00.0", "renderD128"); | |
| probe_function->fake_gbm_dev_type_flags_ = 0; | |
| auto result = EvalProbeFunction(probe_function.get()); | |
| auto ans = CreateProbeResultFromJson(R"JSON( | |
| [] | |
| )JSON"); | |
| EXPECT_EQ(result, ans); | |
| } | |
| } // namespace | |
| } // namespace runtime_probe |