Open Lighting Architecture  0.9.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MockUDPSocket.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * MockUDPsocket.h
17  * Header file for the Mock UDP Socket class
18  * Copyright (C) 2010 Simon Newton
19  */
20 
21 #ifndef INCLUDE_OLA_TESTING_MOCKUDPSOCKET_H_
22 #define INCLUDE_OLA_TESTING_MOCKUDPSOCKET_H_
23 
24 #include <cppunit/extensions/HelperMacros.h>
25 
26 #include <ola/base/Macro.h>
28 #include <ola/network/Socket.h>
30 
31 #include <string>
32 #include <queue>
33 
34 namespace ola {
35 namespace testing {
36 
37 /*
38  * The MockUDPSocket allows one to stub out a UDP Socket for testing. The
39  * code-under-test can use this object as it would a UDP socket, and the code
40  * performing the test can verify that the data written matches what it
41  * expects. It does this by calling AddExpectedData(), e.g.
42  *
43  * // add the data we expect, you can call this more than once
44  * udp_socket.AddExpectedData(....);
45  * udp_socket.AddExpectedData(....);
46  * // this calls one of the SendTo methods
47  * MethodToTest(udp_socket);
48  * // verify all the expected data has been consumed
49  * udp_socket.Verify()
50  *
51  * You can also inject packets into the socket by calling InjectData(), this
52  * will trigger the on_read callback that was attached to the socket.
53  */
55  public:
56  MockUDPSocket();
57  ~MockUDPSocket() { Close(); }
58 
59  // These are the socket methods
60  bool Init();
61  bool Bind(const ola::network::IPV4SocketAddress &endpoint);
63  bool Close();
64  ola::io::DescriptorHandle ReadDescriptor() const { return m_dummy_handle; }
65  ola::io::DescriptorHandle WriteDescriptor() const { return m_dummy_handle; }
66  ssize_t SendTo(const uint8_t *buffer,
67  unsigned int size,
68  const ola::network::IPV4Address &ip,
69  unsigned short port) const;
70  ssize_t SendTo(const uint8_t *buffer,
71  unsigned int size,
72  const ola::network::IPV4SocketAddress &dest) const {
73  return SendTo(buffer, size, dest.Host(), dest.Port());
74  }
75  ssize_t SendTo(ola::io::IOVecInterface *data,
76  const ola::network::IPV4Address &ip,
77  unsigned short port) const;
79  const ola::network::IPV4SocketAddress &dest) const {
80  return SendTo(data, dest.Host(), dest.Port());
81  }
82 
83  bool RecvFrom(uint8_t *buffer, ssize_t *data_read) const;
84  bool RecvFrom(uint8_t *buffer,
85  ssize_t *data_read,
86  ola::network::IPV4Address &source) const; // NOLINT
87  bool RecvFrom(uint8_t *buffer,
88  ssize_t *data_read,
89  ola::network::IPV4Address &source, // NOLINT
90  uint16_t &port) const; // NOLINT
91  bool RecvFrom(uint8_t *buffer,
92  ssize_t *data_read,
94  bool EnableBroadcast();
96  bool JoinMulticast(const ola::network::IPV4Address &iface,
97  const ola::network::IPV4Address &group,
98  bool multicast_loop = false);
99  bool LeaveMulticast(const ola::network::IPV4Address &iface,
100  const ola::network::IPV4Address &group);
101 
102  bool SetTos(uint8_t tos);
103 
104  void SetDiscardMode(bool discard_mode) { m_discard_mode = discard_mode; }
105 
106  // these are methods used for verification
107  void AddExpectedData(const uint8_t *data,
108  unsigned int size,
109  const ola::network::IPV4Address &ip,
110  uint16_t port);
111  void AddExpectedData(ola::io::IOQueue *queue,
112  const ola::network::IPV4SocketAddress &dest);
113 
114  // this can be fetched by calling PerformRead() on the socket
115  void InjectData(const uint8_t *data,
116  unsigned int size,
117  const ola::network::IPV4Address &ip,
118  uint16_t port);
119  void InjectData(const uint8_t *data,
120  unsigned int size,
121  const ola::network::IPV4SocketAddress &source);
122  void InjectData(ola::io::IOQueue *ioqueue,
123  const ola::network::IPV4SocketAddress &source);
124 
125  void Verify();
126 
127  bool CheckNetworkParamsMatch(bool init_called,
128  bool bound_to_port,
129  uint16_t port,
130  bool broadcast_set);
131 
132  void SetInterface(const ola::network::IPV4Address &iface);
133 
134  private:
135  typedef struct {
136  const uint8_t *data;
137  unsigned int size;
139  uint16_t port;
140  bool free_data;
141  } expected_call;
142 
143  typedef expected_call received_data;
144 
145  bool m_init_called;
146  // We need a sd so that calls to select continue to work. This isn't used
147  // for anything else.
148  ola::io::DescriptorHandle m_dummy_handle;
149  bool m_bound_to_port;
150  bool m_broadcast_set;
151  uint16_t m_port;
152  uint8_t m_tos;
153  mutable std::queue<expected_call> m_expected_calls;
154  mutable std::queue<received_data> m_received_data;
155  ola::network::IPV4Address m_interface;
156  bool m_discard_mode;
157 
158  uint8_t* IOQueueToBuffer(ola::io::IOQueue *ioqueue,
159  unsigned int *size) const;
160 
161  DISALLOW_COPY_AND_ASSIGN(MockUDPSocket);
162 };
163 
164 
169  public:
170  explicit SocketVerifier(MockUDPSocket *socket)
171  : m_socket(socket) {
172  }
173  ~SocketVerifier() {
174  m_socket->Verify();
175  }
176 
177  private:
178  MockUDPSocket *m_socket;
179 
180  DISALLOW_COPY_AND_ASSIGN(SocketVerifier);
181 };
182 } // namespace testing
183 } // namespace ola
184 #endif // INCLUDE_OLA_TESTING_MOCKUDPSOCKET_H_