connection_info_reader_unittest.cc revision 0951ccbfca977a9cf218b2e4308aa26fb4d06ef9
1// Copyright (c) 2013 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 "shill/connection_info_reader.h"
6
7#include <netinet/in.h>
8
9#include <base/files/file_util.h>
10#include <base/files/scoped_temp_dir.h>
11#include <base/strings/stringprintf.h>
12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
15using base::FilePath;
16using base::ScopedTempDir;
17using base::StringPrintf;
18using std::string;
19using std::vector;
20using testing::Return;
21
22namespace shill {
23
24namespace {
25
26// TODO(benchan): Test IPv6 addresses.
27
28const char *kConnectionInfoLines[] = {
29  "udp      17 30 src=192.168.1.1 dst=192.168.1.2 sport=9000 dport=53 "
30  "[UNREPLIED] src=192.168.1.2 dst=192.168.1.1 sport=53 dport=9000 use=2",
31  "tcp      6 299 ESTABLISHED src=192.168.2.1 dst=192.168.2.3 sport=8000 "
32  "dport=7000 src=192.168.2.3 dst=192.168.2.1 sport=7000 dport=8000 [ASSURED] "
33  "use=2",
34};
35
36}  // namespace
37
38class ConnectionInfoReaderUnderTest : public ConnectionInfoReader {
39 public:
40  // Mock out GetConnectionInfoFilePath to use a temporary created connection
41  // info file instead of the actual path in procfs (i.e.
42  // /proc/net/ip_conntrack).
43  MOCK_CONST_METHOD0(GetConnectionInfoFilePath, FilePath());
44};
45
46class ConnectionInfoReaderTest : public testing::Test {
47 protected:
48  IPAddress StringToIPv4Address(const string &address_string) {
49    IPAddress ip_address(IPAddress::kFamilyIPv4);
50    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
51    return ip_address;
52  }
53
54  IPAddress StringToIPv6Address(const string &address_string) {
55    IPAddress ip_address(IPAddress::kFamilyIPv6);
56    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
57    return ip_address;
58  }
59
60  void CreateConnectionInfoFile(const char **lines, size_t num_lines,
61                                const FilePath &dir_path, FilePath *file_path) {
62    ASSERT_TRUE(base::CreateTemporaryFileInDir(dir_path, file_path));
63    for (size_t i = 0; i < num_lines; ++i) {
64      string line = lines[i];
65      line += '\n';
66      ASSERT_TRUE(base::AppendToFile(*file_path, line.data(), line.size()));
67    }
68  }
69
70  void ExpectConnectionInfoEqual(const ConnectionInfo &info1,
71                                 const ConnectionInfo &info2) {
72    EXPECT_EQ(info1.protocol(), info2.protocol());
73    EXPECT_EQ(info1.time_to_expire_seconds(), info2.time_to_expire_seconds());
74    EXPECT_EQ(info1.is_unreplied(), info2.is_unreplied());
75    EXPECT_TRUE(info1.original_source_ip_address()
76                    .Equals(info2.original_source_ip_address()));
77    EXPECT_EQ(info1.original_source_port(), info2.original_source_port());
78    EXPECT_TRUE(info1.original_destination_ip_address()
79                    .Equals(info2.original_destination_ip_address()));
80    EXPECT_EQ(info1.original_destination_port(),
81              info2.original_destination_port());
82    EXPECT_TRUE(info1.reply_source_ip_address()
83                    .Equals(info2.reply_source_ip_address()));
84    EXPECT_EQ(info1.reply_source_port(), info2.reply_source_port());
85    EXPECT_TRUE(info1.reply_destination_ip_address()
86                    .Equals(info2.reply_destination_ip_address()));
87    EXPECT_EQ(info1.reply_destination_port(), info2.reply_destination_port());
88  }
89
90  ConnectionInfoReaderUnderTest reader_;
91};
92
93TEST_F(ConnectionInfoReaderTest, LoadConnectionInfo) {
94  vector<ConnectionInfo> info_list;
95  ScopedTempDir temp_dir;
96  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
97
98  // Loading a non-existent file should fail.
99  FilePath info_file("/non-existent-file");
100  EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
101  EXPECT_FALSE(reader_.LoadConnectionInfo(&info_list));
102
103  // Loading an empty file should succeed.
104  CreateConnectionInfoFile(kConnectionInfoLines, 0, temp_dir.path(),
105                           &info_file);
106  EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
107  EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
108  EXPECT_TRUE(info_list.empty());
109
110  // Loading a non-empty file should succeed.
111  CreateConnectionInfoFile(kConnectionInfoLines,
112                           arraysize(kConnectionInfoLines),
113                           temp_dir.path(),
114                           &info_file);
115  EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
116  EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
117  EXPECT_EQ(arraysize(kConnectionInfoLines), info_list.size());
118
119  ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
120                                           30,
121                                           true,
122                                           StringToIPv4Address("192.168.1.1"),
123                                           9000,
124                                           StringToIPv4Address("192.168.1.2"),
125                                           53,
126                                           StringToIPv4Address("192.168.1.2"),
127                                           53,
128                                           StringToIPv4Address("192.168.1.1"),
129                                           9000),
130                            info_list[0]);
131  ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_TCP,
132                                           299,
133                                           false,
134                                           StringToIPv4Address("192.168.2.1"),
135                                           8000,
136                                           StringToIPv4Address("192.168.2.3"),
137                                           7000,
138                                           StringToIPv4Address("192.168.2.3"),
139                                           7000,
140                                           StringToIPv4Address("192.168.2.1"),
141                                           8000),
142                            info_list[1]);
143}
144
145TEST_F(ConnectionInfoReaderTest, ParseConnectionInfo) {
146  ConnectionInfo info;
147
148  EXPECT_FALSE(reader_.ParseConnectionInfo("", &info));
149
150  EXPECT_TRUE(reader_.ParseConnectionInfo(kConnectionInfoLines[0], &info));
151  ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
152                                           30,
153                                           true,
154                                           StringToIPv4Address("192.168.1.1"),
155                                           9000,
156                                           StringToIPv4Address("192.168.1.2"),
157                                           53,
158                                           StringToIPv4Address("192.168.1.2"),
159                                           53,
160                                           StringToIPv4Address("192.168.1.1"),
161                                           9000),
162                            info);
163}
164
165TEST_F(ConnectionInfoReaderTest, ParseProtocol) {
166  int protocol = 0;
167
168  EXPECT_FALSE(reader_.ParseProtocol("", &protocol));
169  EXPECT_FALSE(reader_.ParseProtocol("a", &protocol));
170  EXPECT_FALSE(reader_.ParseProtocol("-1", &protocol));
171  EXPECT_FALSE(reader_.ParseProtocol(StringPrintf("%d", IPPROTO_MAX),
172                                     &protocol));
173
174  for (int i = 0; i < IPPROTO_MAX; ++i) {
175    EXPECT_TRUE(reader_.ParseProtocol(StringPrintf("%d", i), &protocol));
176    EXPECT_EQ(i, protocol);
177  }
178}
179
180TEST_F(ConnectionInfoReaderTest, ParseTimeToExpireSeconds) {
181  int64_t time_to_expire = 0;
182
183  EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("", &time_to_expire));
184  EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("a", &time_to_expire));
185  EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("-1", &time_to_expire));
186
187  EXPECT_TRUE(reader_.ParseTimeToExpireSeconds("100", &time_to_expire));
188  EXPECT_EQ(100, time_to_expire);
189}
190
191TEST_F(ConnectionInfoReaderTest, ParseIPAddress) {
192  IPAddress ip_address(IPAddress::kFamilyUnknown);
193  bool is_source = false;
194
195  EXPECT_FALSE(reader_.ParseIPAddress("", &ip_address, &is_source));
196  EXPECT_FALSE(reader_.ParseIPAddress("abc", &ip_address, &is_source));
197  EXPECT_FALSE(reader_.ParseIPAddress("src=", &ip_address, &is_source));
198  EXPECT_FALSE(reader_.ParseIPAddress("src=abc", &ip_address, &is_source));
199  EXPECT_FALSE(reader_.ParseIPAddress("dst=", &ip_address, &is_source));
200  EXPECT_FALSE(reader_.ParseIPAddress("dst=abc", &ip_address, &is_source));
201
202  EXPECT_TRUE(reader_.ParseIPAddress("src=192.168.1.1",
203                                     &ip_address, &is_source));
204  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.1")));
205  EXPECT_TRUE(is_source);
206  EXPECT_TRUE(reader_.ParseIPAddress("dst=192.168.1.2",
207                                     &ip_address, &is_source));
208  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.2")));
209  EXPECT_FALSE(is_source);
210}
211
212TEST_F(ConnectionInfoReaderTest, ParsePort) {
213  uint16_t port = 0;
214  bool is_source = false;
215
216  EXPECT_FALSE(reader_.ParsePort("", &port, &is_source));
217  EXPECT_FALSE(reader_.ParsePort("a", &port, &is_source));
218  EXPECT_FALSE(reader_.ParsePort("0", &port, &is_source));
219  EXPECT_FALSE(reader_.ParsePort("sport=", &port, &is_source));
220  EXPECT_FALSE(reader_.ParsePort("sport=a", &port, &is_source));
221  EXPECT_FALSE(reader_.ParsePort("sport=-1", &port, &is_source));
222  EXPECT_FALSE(reader_.ParsePort("sport=65536", &port, &is_source));
223  EXPECT_FALSE(reader_.ParsePort("dport=", &port, &is_source));
224  EXPECT_FALSE(reader_.ParsePort("dport=a", &port, &is_source));
225  EXPECT_FALSE(reader_.ParsePort("dport=-1", &port, &is_source));
226  EXPECT_FALSE(reader_.ParsePort("dport=65536", &port, &is_source));
227
228  EXPECT_TRUE(reader_.ParsePort("sport=53", &port, &is_source));
229  EXPECT_EQ(53, port);
230  EXPECT_TRUE(is_source);
231  EXPECT_TRUE(reader_.ParsePort("dport=80", &port, &is_source));
232  EXPECT_EQ(80, port);
233  EXPECT_FALSE(is_source);
234}
235
236}  // namespace shill
237