blob: 44f5fde057ac3dd83c6f429183a808e6f64d5c16 [file] [log] [blame]
// 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 <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <base/containers/span.h>
#include <base/files/file_path.h>
#include <base/strings/stringprintf.h>
#include <brillo/variant_dictionary.h>
#include <dbus/shill/dbus-constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "runtime_probe/function_templates/network.h"
#include "runtime_probe/utils/function_test_utils.h"
#include "shill/dbus-constants.h"
namespace runtime_probe {
namespace {
using ::testing::_;
using ::testing::Eq;
using ::testing::Pointee;
using ::testing::Return;
class MockNetworkFunction : public NetworkFunction {
using NetworkFunction::NetworkFunction;
public:
NAME_PROBE_FUNCTION("mock_network");
MOCK_METHOD(std::optional<std::string>,
GetNetworkType,
(),
(const, override));
};
class NetworkFunctionTest : public BaseFunctionTest {
protected:
void SetNetworkDevice(const std::string& dev_name,
const std::string& network_type) {
const std::string bus_dev =
"/sys/devices/pci0000:00/0000:00:08.1" + dev_name;
const std::string bus_dev_relative_to_sys = "../../../";
SetSymbolicLink(bus_dev, {"/sys/class/net", dev_name, "device"});
// The symbolic link is for getting the bus type.
SetSymbolicLink({bus_dev_relative_to_sys, "bus", "pci"},
{bus_dev, "subsystem"});
SetFile({bus_dev, "device"}, "0x1111");
SetFile({bus_dev, "vendor"}, "0x2222");
SetFile({bus_dev, "class"}, "0x010203");
shill_devices_["/dev/" + dev_name] = {{shill::kInterfaceProperty, dev_name},
{shill::kTypeProperty, network_type}};
mock_context()->SetShillProxies(shill_devices_);
}
std::map<std::string, brillo::VariantDictionary> shill_devices_;
};
TEST_F(NetworkFunctionTest, ProbeNetwork) {
SetNetworkDevice("wlan0", shill::kTypeWifi);
auto probe_function = CreateProbeFunction<NetworkFunction>();
auto result = EvalProbeFunction(probe_function.get());
EXPECT_EQ(result.size(), 1);
EXPECT_TRUE(result[0].GetDict().FindString("path"));
EXPECT_TRUE(result[0].GetDict().FindString("bus_type"));
}
TEST_F(NetworkFunctionTest, ProbeNetworkByType) {
SetNetworkDevice("wlan0", shill::kTypeWifi);
SetNetworkDevice("eth0", shill::kTypeEthernet);
SetNetworkDevice("wwan0", shill::kTypeCellular);
const std::set<std::string> expected_types{
shill::kTypeWifi, shill::kTypeEthernet, shill::kTypeCellular};
// Probe all.
{
auto probe_function = CreateProbeFunction<NetworkFunction>();
auto result = EvalProbeFunction(probe_function.get());
std::set<std::string> result_types;
for (const auto& each_result : result) {
auto* type = each_result.GetDict().FindString("type");
if (type) {
result_types.insert(*type);
}
}
EXPECT_EQ(result_types, expected_types);
}
// Filter by each type.
for (const auto& expected_type : expected_types) {
base::Value::Dict arg;
arg.Set("device_type", expected_type);
auto probe_function = CreateProbeFunction<NetworkFunction>(arg);
auto result = EvalProbeFunction(probe_function.get());
EXPECT_EQ(result.size(), 1);
EXPECT_THAT(result[0].GetDict().FindString("type"),
Pointee(Eq(expected_type)));
}
// TODO(b/269822306): The below two do the same thing as the above, but use
// the old interface to pass the type. Remove this after we done the
// migration.
// Probe all.
{
auto probe_function = CreateProbeFunction<MockNetworkFunction>();
EXPECT_CALL(*probe_function, GetNetworkType())
.WillOnce(Return(std::nullopt));
auto result = EvalProbeFunction(probe_function.get());
std::set<std::string> result_types;
for (const auto& each_result : result) {
auto* type = each_result.GetDict().FindString("type");
if (type) {
result_types.insert(*type);
}
}
EXPECT_EQ(result_types, expected_types);
}
// Filter by each type.
for (const auto& expected_type : expected_types) {
auto probe_function = CreateProbeFunction<MockNetworkFunction>();
EXPECT_CALL(*probe_function, GetNetworkType())
.WillOnce(Return(expected_type));
auto result = EvalProbeFunction(probe_function.get());
EXPECT_EQ(result.size(), 1);
EXPECT_THAT(result[0].GetDict().FindString("type"),
Pointee(Eq(expected_type)));
}
}
TEST_F(NetworkFunctionTest, CreateNetworkFunctionFailed) {
base::Value::Dict arg;
arg.Set("device_type", "unknown_type");
auto probe_function = CreateProbeFunction<NetworkFunction>(arg);
EXPECT_FALSE(probe_function);
}
} // namespace
} // namespace runtime_probe