blob: 5b9e449c5c9e079181b9ed04f991681acdce1a64 [file] [log] [blame]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "patchpanel/proto_utils.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <base/functional/callback_helpers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
#include "patchpanel/address_manager.h"
#include "patchpanel/arc_service.h"
#include "patchpanel/crostini_service.h"
namespace patchpanel {
class ProtoUtilsTest : public testing::Test {
protected:
void SetUp() override { addr_mgr_ = std::make_unique<AddressManager>(); }
std::unique_ptr<AddressManager> addr_mgr_;
};
TEST_F(ProtoUtilsTest, FillTerminaAllocationProto) {
const auto termina_ipv4_subnet =
*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.24/30");
const auto termina_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.92.26");
const auto gateway_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.92.25");
const auto container_ipv4_subnet =
*net_base::IPv4CIDR::CreateFromCIDRString("100.115.92.192/28");
const auto container_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.92.193");
const uint32_t subnet_index = 0;
const auto mac_addr = addr_mgr_->GenerateMacAddress(subnet_index);
auto ipv4_subnet = addr_mgr_->AllocateIPv4Subnet(
AddressManager::GuestType::kTerminaVM, subnet_index);
auto lxd_subnet =
addr_mgr_->AllocateIPv4Subnet(AddressManager::GuestType::kLXDContainer);
auto termina_device = std::make_unique<CrostiniService::CrostiniDevice>(
CrostiniService::VMType::kTermina, "vmtap0", mac_addr,
std::move(ipv4_subnet), std::move(lxd_subnet));
TerminaVmStartupResponse proto;
FillTerminaAllocationProto(*termina_device, &proto);
ASSERT_EQ("vmtap0", proto.tap_device_ifname());
EXPECT_EQ(termina_ipv4_address,
net_base::IPv4Address::CreateFromBytes(proto.ipv4_address()));
EXPECT_EQ(gateway_ipv4_address, net_base::IPv4Address::CreateFromBytes(
proto.gateway_ipv4_address()));
EXPECT_EQ(termina_ipv4_subnet.address(),
net_base::IPv4Address::CreateFromBytes(proto.ipv4_subnet().addr()));
EXPECT_EQ(termina_ipv4_subnet.prefix_length(),
proto.ipv4_subnet().prefix_len());
EXPECT_EQ(container_ipv4_address, net_base::IPv4Address::CreateFromBytes(
proto.container_ipv4_address()));
EXPECT_EQ(container_ipv4_subnet.address(),
net_base::IPv4Address::CreateFromBytes(
proto.container_ipv4_subnet().addr()));
EXPECT_EQ(container_ipv4_subnet.prefix_length(),
proto.container_ipv4_subnet().prefix_len());
}
TEST_F(ProtoUtilsTest, FillParallelsAllocationProto) {
const uint32_t subnet_index = 0;
const auto parallels_ipv4_subnet =
*net_base::IPv4CIDR::CreateFromCIDRString("100.115.93.0/29");
const auto parallels_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.93.2");
const auto mac_addr = addr_mgr_->GenerateMacAddress(subnet_index);
auto ipv4_subnet = addr_mgr_->AllocateIPv4Subnet(
AddressManager::GuestType::kParallelsVM, subnet_index);
auto parallels_device = std::make_unique<CrostiniService::CrostiniDevice>(
CrostiniService::VMType::kParallels, "vmtap1", mac_addr,
std::move(ipv4_subnet), nullptr);
ParallelsVmStartupResponse proto;
FillParallelsAllocationProto(*parallels_device, &proto);
ASSERT_EQ("vmtap1", proto.tap_device_ifname());
EXPECT_EQ(parallels_ipv4_address,
net_base::IPv4Address::CreateFromBytes(proto.ipv4_address()));
EXPECT_EQ(parallels_ipv4_subnet.address(),
net_base::IPv4Address::CreateFromBytes(proto.ipv4_subnet().addr()));
EXPECT_EQ(parallels_ipv4_subnet.prefix_length(),
proto.ipv4_subnet().prefix_len());
}
TEST_F(ProtoUtilsTest, FillBruschettaAllocationProto) {
const auto bruschetta_ipv4_subnet =
*net_base::IPv4CIDR::CreateFromCIDRString("100.115.93.0/29");
const auto bruschetta_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.93.2");
const auto gateway_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.93.1");
auto ipv4_subnet =
std::make_unique<Subnet>(bruschetta_ipv4_subnet, base::DoNothing());
// TODO(b/279994478): Add kBruschetta at VMType.
CrostiniService::CrostiniDevice bruschetta_device(
CrostiniService::VMType::kParallels, "vmtap1", {}, std::move(ipv4_subnet),
nullptr);
BruschettaVmStartupResponse proto;
FillBruschettaAllocationProto(bruschetta_device, &proto);
ASSERT_EQ("vmtap1", proto.tap_device_ifname());
EXPECT_EQ(bruschetta_ipv4_address,
net_base::IPv4Address::CreateFromBytes(proto.ipv4_address()));
EXPECT_EQ(gateway_ipv4_address, net_base::IPv4Address::CreateFromBytes(
proto.gateway_ipv4_address()));
EXPECT_EQ(bruschetta_ipv4_subnet.address(),
net_base::IPv4Address::CreateFromBytes(proto.ipv4_subnet().addr()));
EXPECT_EQ(bruschetta_ipv4_subnet.prefix_length(),
proto.ipv4_subnet().prefix_len());
}
TEST_F(ProtoUtilsTest, FillBorealisAllocationProto) {
const auto borealis_ipv4_subnet =
*net_base::IPv4CIDR::CreateFromCIDRString("100.115.93.0/29");
const auto borealis_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.93.2");
const auto gateway_ipv4_address =
*net_base::IPv4Address::CreateFromString("100.115.93.1");
auto ipv4_subnet =
std::make_unique<Subnet>(borealis_ipv4_subnet, base::DoNothing());
CrostiniService::CrostiniDevice borealis_device(
CrostiniService::VMType::kBorealis, "vmtap1", {}, std::move(ipv4_subnet),
nullptr);
BorealisVmStartupResponse proto;
FillBorealisAllocationProto(borealis_device, &proto);
ASSERT_EQ("vmtap1", proto.tap_device_ifname());
EXPECT_EQ(borealis_ipv4_address,
net_base::IPv4Address::CreateFromBytes(proto.ipv4_address()));
EXPECT_EQ(gateway_ipv4_address, net_base::IPv4Address::CreateFromBytes(
proto.gateway_ipv4_address()));
EXPECT_EQ(borealis_ipv4_subnet.address(),
net_base::IPv4Address::CreateFromBytes(proto.ipv4_subnet().addr()));
EXPECT_EQ(borealis_ipv4_subnet.prefix_length(),
proto.ipv4_subnet().prefix_len());
}
TEST_F(ProtoUtilsTest, FillNetworkClientInfoProto) {
DownstreamClientInfo info;
info.mac_addr = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
info.ipv4_addr = net_base::IPv4Address(127, 0, 0, 1);
info.ipv6_addresses.push_back(
*net_base::IPv6Address::CreateFromString("fe80::1"));
info.ipv6_addresses.push_back(
*net_base::IPv6Address::CreateFromString("fe80::3"));
info.hostname = "test_host";
info.vendor_class = "test_vendor_class";
NetworkClientInfo proto;
FillNetworkClientInfoProto(info, &proto);
EXPECT_EQ(proto.mac_addr(),
std::string({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}));
EXPECT_EQ(proto.ipv4_addr(), std::string({127, 0, 0, 1}));
EXPECT_EQ(proto.ipv6_addresses().size(), 2);
EXPECT_EQ(proto.ipv6_addresses()[0],
net_base::IPv6Address::CreateFromString("fe80::1")->ToByteString());
EXPECT_EQ(proto.ipv6_addresses()[1],
net_base::IPv6Address::CreateFromString("fe80::3")->ToByteString());
EXPECT_EQ(proto.hostname(), "test_host");
EXPECT_EQ(proto.vendor_class(), "test_vendor_class");
}
} // namespace patchpanel