blob: 049313f0968596c98a48a9d389d8b323154bf488 [file] [log] [blame]
Wade Guthriecc53f232013-03-05 13:22:23 -08001// 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/netlink_socket.h"
6
Wade Guthriebb9fca22013-04-10 17:21:42 -07007#include <linux/netlink.h>
8
Wade Guthriecc53f232013-03-05 13:22:23 -08009#include <algorithm>
10#include <string>
11
12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
15#include "shill/byte_string.h"
16#include "shill/mock_sockets.h"
Wade Guthriebb9fca22013-04-10 17:21:42 -070017#include "shill/netlink_message.h"
Wade Guthriecc53f232013-03-05 13:22:23 -080018
19using std::min;
20using std::string;
21using testing::_;
22using testing::Invoke;
23using testing::Return;
24using testing::Test;
25
26namespace shill {
27
28class NetlinkSocketTest;
29
30const int kFakeFd = 99;
31
32class NetlinkSocketTest : public Test {
33 public:
34 NetlinkSocketTest() {}
35 virtual ~NetlinkSocketTest() {}
36
37 virtual void SetUp() {
38 mock_sockets_ = new MockSockets();
39 netlink_socket_.sockets_.reset(mock_sockets_);
40 }
41
42 virtual void InitializeSocket(int fd) {
43 EXPECT_CALL(*mock_sockets_, Socket(PF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC))
44 .WillOnce(Return(fd));
45 EXPECT_CALL(*mock_sockets_, SetReceiveBuffer(
46 fd, NetlinkSocket::kReceiveBufferSize)).WillOnce(Return(0));
47 EXPECT_CALL(*mock_sockets_, Bind(fd, _, sizeof(struct sockaddr_nl)))
48 .WillOnce(Return(0));
49 EXPECT_TRUE(netlink_socket_.Init());
50 }
51
52 protected:
53 MockSockets *mock_sockets_; // Owned by netlink_socket_.
54 NetlinkSocket netlink_socket_;
55};
56
57class FakeSocketRead {
58 public:
Wade Guthriebb9fca22013-04-10 17:21:42 -070059 explicit FakeSocketRead(const ByteString &next_read_string) {
Wade Guthriecc53f232013-03-05 13:22:23 -080060 next_read_string_ = next_read_string;
61 }
62 // Copies |len| bytes of |next_read_string_| into |buf| and clears
63 // |next_read_string_|.
64 ssize_t FakeSuccessfulRead(int sockfd, void *buf, size_t len, int flags,
65 struct sockaddr *src_addr, socklen_t *addrlen) {
66 if (!buf) {
67 return -1;
68 }
69 int read_bytes = min(len, next_read_string_.GetLength());
70 memcpy(buf, next_read_string_.GetConstData(), read_bytes);
71 next_read_string_.Clear();
72 return read_bytes;
73 }
74
75 private:
76 ByteString next_read_string_;
77};
78
79TEST_F(NetlinkSocketTest, InitWorkingTest) {
80 SetUp();
81 InitializeSocket(kFakeFd);
82 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
83}
84
85TEST_F(NetlinkSocketTest, InitBrokenSocketTest) {
86 SetUp();
87
88 const int kBadFd = -1;
89 EXPECT_CALL(*mock_sockets_, Socket(PF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC))
90 .WillOnce(Return(kBadFd));
91 EXPECT_CALL(*mock_sockets_, SetReceiveBuffer(_, _)).Times(0);
92 EXPECT_CALL(*mock_sockets_, Bind(_, _, _)).Times(0);
93 EXPECT_FALSE(netlink_socket_.Init());
94}
95
96TEST_F(NetlinkSocketTest, InitBrokenBufferTest) {
97 SetUp();
98
99 EXPECT_CALL(*mock_sockets_, Socket(PF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC))
100 .WillOnce(Return(kFakeFd));
101 EXPECT_CALL(*mock_sockets_, SetReceiveBuffer(
102 kFakeFd, NetlinkSocket::kReceiveBufferSize)).WillOnce(Return(-1));
103 EXPECT_CALL(*mock_sockets_, Bind(kFakeFd, _, sizeof(struct sockaddr_nl)))
104 .WillOnce(Return(0));
105 EXPECT_TRUE(netlink_socket_.Init());
106
107 // Destructor.
108 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
109}
110
111TEST_F(NetlinkSocketTest, InitBrokenBindTest) {
112 SetUp();
113
114 EXPECT_CALL(*mock_sockets_, Socket(PF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC))
115 .WillOnce(Return(kFakeFd));
116 EXPECT_CALL(*mock_sockets_, SetReceiveBuffer(
117 kFakeFd, NetlinkSocket::kReceiveBufferSize)).WillOnce(Return(0));
118 EXPECT_CALL(*mock_sockets_, Bind(kFakeFd, _, sizeof(struct sockaddr_nl)))
119 .WillOnce(Return(-1));
120 EXPECT_CALL(*mock_sockets_, Close(kFakeFd)).WillOnce(Return(0));
121 EXPECT_FALSE(netlink_socket_.Init());
122}
123
124TEST_F(NetlinkSocketTest, SendMessageTest) {
125 SetUp();
126 InitializeSocket(kFakeFd);
127
128 string message_string("This text is really arbitrary");
129 ByteString message(message_string.c_str(), message_string.size());
130
131 // Good Send.
132 EXPECT_CALL(*mock_sockets_,
133 Send(kFakeFd, message.GetConstData(), message.GetLength(), 0))
134 .WillOnce(Return(message.GetLength()));
135 EXPECT_TRUE(netlink_socket_.SendMessage(message));
136
137 // Short Send.
138 EXPECT_CALL(*mock_sockets_,
139 Send(kFakeFd, message.GetConstData(), message.GetLength(), 0))
140 .WillOnce(Return(message.GetLength() - 3));
141 EXPECT_FALSE(netlink_socket_.SendMessage(message));
142
143 // Bad Send.
144 EXPECT_CALL(*mock_sockets_,
145 Send(kFakeFd, message.GetConstData(), message.GetLength(), 0))
146 .WillOnce(Return(-1));
147 EXPECT_FALSE(netlink_socket_.SendMessage(message));
148
149 // Destructor.
150 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
151}
152
153TEST_F(NetlinkSocketTest, SequenceNumberTest) {
154 SetUp();
155
156 // Just a sequence number.
157 const uint32_t arbitrary_number = 42;
158 netlink_socket_.sequence_number_ = arbitrary_number;
159 EXPECT_EQ(arbitrary_number+1, netlink_socket_.GetSequenceNumber());
160
161 // Make sure we don't go to |NetlinkMessage::kBroadcastSequenceNumber|.
162 netlink_socket_.sequence_number_ = NetlinkMessage::kBroadcastSequenceNumber;
163 EXPECT_NE(NetlinkMessage::kBroadcastSequenceNumber,
164 netlink_socket_.GetSequenceNumber());
165}
166
167TEST_F(NetlinkSocketTest, GoodRecvMessageTest) {
168 SetUp();
169 InitializeSocket(kFakeFd);
170
171 ByteString message;
172 static const string next_read_string(
173 "Random text may include things like 'freaking fracking foo'.");
174 static const size_t read_size = next_read_string.size();
175 ByteString expected_results(next_read_string.c_str(), read_size);
176 FakeSocketRead fake_socket_read(expected_results);
177
178 // Expect one call to get the size...
179 EXPECT_CALL(*mock_sockets_,
180 RecvFrom(kFakeFd, _, _, MSG_TRUNC | MSG_PEEK, _, _))
181 .WillOnce(Return(read_size));
182
183 // ...and expect a second call to get the data.
184 EXPECT_CALL(*mock_sockets_,
185 RecvFrom(kFakeFd, _, read_size, 0, _, _))
186 .WillOnce(Invoke(&fake_socket_read, &FakeSocketRead::FakeSuccessfulRead));
187
188 EXPECT_TRUE(netlink_socket_.RecvMessage(&message));
189 EXPECT_TRUE(message.Equals(expected_results));
190
191 // Destructor.
192 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
193}
194
195TEST_F(NetlinkSocketTest, BadRecvMessageTest) {
196 SetUp();
197 InitializeSocket(kFakeFd);
198
199 ByteString message;
200 EXPECT_CALL(*mock_sockets_, RecvFrom(kFakeFd, _, _, _, _, _))
201 .WillOnce(Return(-1));
202 EXPECT_FALSE(netlink_socket_.RecvMessage(&message));
203
204 EXPECT_CALL(*mock_sockets_, Close(kFakeFd));
205}
206
207} // namespace shill.