blob: b8d799d0a692e67c3ea990428544e5ba9203b830 [file] [log] [blame]
// Copyright 2024 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/socket_service_adaptor.h"
#include <memory>
#include <optional>
#include <vector>
#include <base/memory/ptr_util.h>
#include <base/memory/scoped_refptr.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
#include <patchpanel/proto_bindings/traffic_annotation.pb.h>
#include "patchpanel/mock_routing_service.h"
using testing::_;
using testing::Ge;
using testing::Return;
namespace patchpanel {
namespace {
class SocketServiceAdaptorTest : public testing::Test {
public:
SocketServiceAdaptorTest()
: mock_routing_svc_(new MockRoutingService),
adaptor_(mock_bus_, base::WrapUnique(mock_routing_svc_)) {}
protected:
void SetUp() override {}
scoped_refptr<dbus::MockBus> mock_bus_{
new dbus::MockBus{dbus::Bus::Options{}}};
MockRoutingService* mock_routing_svc_;
SocketServiceAdaptor adaptor_;
};
base::ScopedFD MakeFd() {
return base::ScopedFD(socket(AF_INET, SOCK_DGRAM, 0));
}
TEST_F(SocketServiceAdaptorTest, TagSocketInvalidFd) {
EXPECT_CALL(*mock_routing_svc_, TagSocket(_, _, _, _)).Times(0);
TagSocketRequest request;
auto response = adaptor_.TagSocket(request, base::ScopedFD(-1));
EXPECT_FALSE(response.success());
}
TEST_F(SocketServiceAdaptorTest, TagSocketStatus) {
EXPECT_CALL(*mock_routing_svc_, TagSocket(Ge(0), _, _, _))
.WillOnce(Return(true))
.WillOnce(Return(false));
TagSocketRequest request;
auto res1 = adaptor_.TagSocket(request, MakeFd());
EXPECT_TRUE(res1.success());
auto res2 = adaptor_.TagSocket(request, MakeFd());
EXPECT_FALSE(res2.success());
}
TEST_F(SocketServiceAdaptorTest, TagSocketNetworkId) {
EXPECT_CALL(*mock_routing_svc_,
TagSocket(Ge(0), std::optional<int>(23), _, _))
.WillOnce(Return(true));
TagSocketRequest request;
request.set_network_id(23);
auto response = adaptor_.TagSocket(request, MakeFd());
EXPECT_TRUE(response.success());
}
TEST_F(SocketServiceAdaptorTest, TagSocketVpnPolicy) {
EXPECT_CALL(*mock_routing_svc_,
TagSocket(Ge(0), _, VPNRoutingPolicy::kDefault, _))
.WillOnce(Return(true));
EXPECT_CALL(*mock_routing_svc_,
TagSocket(Ge(0), _, VPNRoutingPolicy::kRouteOnVPN, _))
.WillOnce(Return(true));
EXPECT_CALL(*mock_routing_svc_,
TagSocket(Ge(0), _, VPNRoutingPolicy::kBypassVPN, _))
.WillOnce(Return(true));
const std::vector<TagSocketRequest::VpnRoutingPolicy> policies = {
TagSocketRequest::DEFAULT_ROUTING,
TagSocketRequest::ROUTE_ON_VPN,
TagSocketRequest::BYPASS_VPN,
};
for (const auto policy : policies) {
TagSocketRequest request;
request.set_vpn_policy(policy);
auto response = adaptor_.TagSocket(request, MakeFd());
EXPECT_TRUE(response.success());
}
}
TEST_F(SocketServiceAdaptorTest, TagSocketTrafficAnnotation) {
const std::vector<TrafficAnnotationId> annotations = {
TrafficAnnotationId::kUnspecified,
TrafficAnnotationId::kShillPortalDetector,
TrafficAnnotationId::kShillCapportClient,
TrafficAnnotationId::kShillCarrierEntitlement,
};
for (const auto id : annotations) {
EXPECT_CALL(*mock_routing_svc_,
TagSocket(Ge(0), _, _, std::optional<TrafficAnnotationId>(id)))
.WillOnce(Return(true));
}
const std::vector<traffic_annotation::TrafficAnnotation::Id>
mojo_annotations = {
traffic_annotation::TrafficAnnotation::UNSPECIFIED,
traffic_annotation::TrafficAnnotation::SHILL_PORTAL_DETECTOR,
traffic_annotation::TrafficAnnotation::SHILL_CAPPORT_CLIENT,
traffic_annotation::TrafficAnnotation::SHILL_CARRIER_ENTITLEMENT,
};
for (const auto id : mojo_annotations) {
TagSocketRequest request;
auto ta = request.mutable_traffic_annotation();
ta->set_host_id(id);
auto response = adaptor_.TagSocket(request, MakeFd());
EXPECT_TRUE(response.success());
}
}
} // namespace
} // namespace patchpanel