Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 1 | // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "patchpanel/counters_service.h" |
| 6 | |
| 7 | #include <memory> |
| 8 | #include <string> |
| 9 | #include <vector> |
| 10 | |
| 11 | #include <chromeos/dbus/service_constants.h> |
| 12 | #include <gmock/gmock.h> |
| 13 | #include <gtest/gtest.h> |
| 14 | |
| 15 | #include "patchpanel/fake_shill_client.h" |
| 16 | |
| 17 | namespace patchpanel { |
| 18 | namespace { |
| 19 | |
| 20 | using ::testing::Contains; |
| 21 | using ::testing::ElementsAreArray; |
| 22 | |
| 23 | class MockProcessRunner : public MinijailedProcessRunner { |
| 24 | public: |
| 25 | MockProcessRunner() = default; |
| 26 | ~MockProcessRunner() = default; |
| 27 | |
| 28 | MOCK_METHOD(int, |
| 29 | iptables, |
| 30 | (const std::string& table, |
| 31 | const std::vector<std::string>& argv, |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 32 | bool log_failures, |
| 33 | std::string* output), |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 34 | (override)); |
| 35 | MOCK_METHOD(int, |
| 36 | ip6tables, |
| 37 | (const std::string& table, |
| 38 | const std::vector<std::string>& argv, |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 39 | bool log_failures, |
| 40 | std::string* output), |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 41 | (override)); |
| 42 | }; |
| 43 | |
| 44 | class CountersServiceTest : public testing::Test { |
| 45 | protected: |
| 46 | void SetUp() override { |
| 47 | fake_shill_client_ = shill_helper_.FakeClient(); |
| 48 | counters_svc_ = |
| 49 | std::make_unique<CountersService>(fake_shill_client_.get(), &runner_); |
| 50 | } |
| 51 | |
| 52 | FakeShillClientHelper shill_helper_; |
| 53 | MockProcessRunner runner_; |
| 54 | std::unique_ptr<FakeShillClient> fake_shill_client_; |
| 55 | std::unique_ptr<CountersService> counters_svc_; |
| 56 | }; |
| 57 | |
| 58 | TEST_F(CountersServiceTest, OnNewDevice) { |
| 59 | // Makes the check commands return 1 (not found). |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 60 | EXPECT_CALL(runner_, iptables(_, Contains("-C"), _, _)) |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 61 | .WillRepeatedly(Return(1)); |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 62 | EXPECT_CALL(runner_, ip6tables(_, Contains("-C"), _, _)) |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 63 | .WillRepeatedly(Return(1)); |
| 64 | |
| 65 | // The following commands are expected when eth0 comes up. |
| 66 | const std::vector<std::vector<std::string>> expected_calls{ |
| 67 | {"-N", "rx_input_eth0", "-w"}, |
| 68 | {"-A", "INPUT", "-i", "eth0", "-j", "rx_input_eth0", "-w"}, |
| 69 | {"-A", "rx_input_eth0", "-w"}, |
| 70 | |
| 71 | {"-N", "rx_fwd_eth0", "-w"}, |
| 72 | {"-A", "FORWARD", "-i", "eth0", "-j", "rx_fwd_eth0", "-w"}, |
| 73 | {"-A", "rx_fwd_eth0", "-w"}, |
| 74 | |
| 75 | {"-N", "tx_postrt_eth0", "-w"}, |
| 76 | {"-A", "POSTROUTING", "-o", "eth0", "-m", "owner", "--socket-exists", |
| 77 | "-j", "tx_postrt_eth0", "-w"}, |
| 78 | {"-A", "tx_postrt_eth0", "-w"}, |
| 79 | |
| 80 | {"-N", "tx_fwd_eth0", "-w"}, |
| 81 | {"-A", "FORWARD", "-o", "eth0", "-j", "tx_fwd_eth0", "-w"}, |
| 82 | {"-A", "tx_fwd_eth0", "-w"}, |
| 83 | }; |
| 84 | |
| 85 | for (const auto& rule : expected_calls) { |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 86 | EXPECT_CALL(runner_, iptables("mangle", ElementsAreArray(rule), _, _)); |
| 87 | EXPECT_CALL(runner_, ip6tables("mangle", ElementsAreArray(rule), _, _)); |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")}; |
| 91 | fake_shill_client_->NotifyManagerPropertyChange(shill::kDevicesProperty, |
| 92 | brillo::Any(devices)); |
| 93 | } |
| 94 | |
| 95 | TEST_F(CountersServiceTest, OnSameDeviceAppearAgain) { |
| 96 | // Makes the check commands return 0 (we already have these rules). |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 97 | EXPECT_CALL(runner_, iptables(_, Contains("-C"), _, _)) |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 98 | .WillRepeatedly(Return(0)); |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 99 | EXPECT_CALL(runner_, ip6tables(_, Contains("-C"), _, _)) |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 100 | .WillRepeatedly(Return(0)); |
| 101 | |
| 102 | // Creating chains commands are expected but no more creating rules command |
| 103 | // (with "-I" or "-A") should come. |
Jie Jiang | cf5ce9c | 2020-07-14 17:22:03 +0900 | [diff] [blame^] | 104 | EXPECT_CALL(runner_, iptables(_, Contains("-N"), _, _)).Times(AnyNumber()); |
| 105 | EXPECT_CALL(runner_, ip6tables(_, Contains("-N"), _, _)).Times(AnyNumber()); |
Jie Jiang | cf74915 | 2020-07-09 22:20:58 +0900 | [diff] [blame] | 106 | |
| 107 | std::vector<dbus::ObjectPath> devices = {dbus::ObjectPath("/device/eth0")}; |
| 108 | fake_shill_client_->NotifyManagerPropertyChange(shill::kDevicesProperty, |
| 109 | brillo::Any(devices)); |
| 110 | } |
| 111 | |
| 112 | } // namespace |
| 113 | } // namespace patchpanel |