blob: 5b9e77d10748ff07e921f1c742bcf1e26b5217f9 [file] [log] [blame]
// 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 "patchpanel/counters_service.h"
#include <memory>
#include <string>
#include <vector>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "patchpanel/fake_shill_client.h"
namespace patchpanel {
namespace {
using ::testing::Contains;
using ::testing::ElementsAreArray;
class MockProcessRunner : public MinijailedProcessRunner {
public:
MockProcessRunner() = default;
~MockProcessRunner() = default;
MOCK_METHOD(int,
iptables,
(const std::string& table,
const std::vector<std::string>& argv,
bool log_failures,
std::string* output),
(override));
MOCK_METHOD(int,
ip6tables,
(const std::string& table,
const std::vector<std::string>& argv,
bool log_failures,
std::string* output),
(override));
};
class CountersServiceTest : public testing::Test {
protected:
void SetUp() override {
fake_shill_client_ = shill_helper_.FakeClient();
counters_svc_ =
std::make_unique<CountersService>(fake_shill_client_.get(), &runner_);
}
FakeShillClientHelper shill_helper_;
MockProcessRunner runner_;
std::unique_ptr<FakeShillClient> fake_shill_client_;
std::unique_ptr<CountersService> counters_svc_;
};
TEST_F(CountersServiceTest, OnNewDevice) {
// Makes the check commands return 1 (not found).
EXPECT_CALL(runner_, iptables(_, Contains("-C"), _, _))
.WillRepeatedly(Return(1));
EXPECT_CALL(runner_, ip6tables(_, Contains("-C"), _, _))
.WillRepeatedly(Return(1));
// The following commands are expected when eth0 comes up.
const std::vector<std::vector<std::string>> expected_calls{
{"-N", "rx_input_eth0", "-w"},
{"-A", "INPUT", "-i", "eth0", "-j", "rx_input_eth0", "-w"},
{"-A", "rx_input_eth0", "-w"},
{"-N", "rx_fwd_eth0", "-w"},
{"-A", "FORWARD", "-i", "eth0", "-j", "rx_fwd_eth0", "-w"},
{"-A", "rx_fwd_eth0", "-w"},
{"-N", "tx_postrt_eth0", "-w"},
{"-A", "POSTROUTING", "-o", "eth0", "-m", "owner", "--socket-exists",
"-j", "tx_postrt_eth0", "-w"},
{"-A", "tx_postrt_eth0", "-w"},
{"-N", "tx_fwd_eth0", "-w"},
{"-A", "FORWARD", "-o", "eth0", "-j", "tx_fwd_eth0", "-w"},
{"-A", "tx_fwd_eth0", "-w"},
};
for (const auto& rule : expected_calls) {
EXPECT_CALL(runner_, iptables("mangle", ElementsAreArray(rule), _, _));
EXPECT_CALL(runner_, ip6tables("mangle", ElementsAreArray(rule), _, _));
}
std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")};
fake_shill_client_->NotifyManagerPropertyChange(shill::kDevicesProperty,
brillo::Any(devices));
}
TEST_F(CountersServiceTest, OnSameDeviceAppearAgain) {
// Makes the check commands return 0 (we already have these rules).
EXPECT_CALL(runner_, iptables(_, Contains("-C"), _, _))
.WillRepeatedly(Return(0));
EXPECT_CALL(runner_, ip6tables(_, Contains("-C"), _, _))
.WillRepeatedly(Return(0));
// Creating chains commands are expected but no more creating rules command
// (with "-I" or "-A") should come.
EXPECT_CALL(runner_, iptables(_, Contains("-N"), _, _)).Times(AnyNumber());
EXPECT_CALL(runner_, ip6tables(_, Contains("-N"), _, _)).Times(AnyNumber());
std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")};
fake_shill_client_->NotifyManagerPropertyChange(shill::kDevicesProperty,
brillo::Any(devices));
}
} // namespace
} // namespace patchpanel