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