Open Lighting Architecture  0.9.0
 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
62  bool GetSocketAddress(ola::network::IPV4SocketAddress *address) const;
63  bool Close();
64  int ReadDescriptor() const { return m_dummy_sd; }
65  int WriteDescriptor() const { return m_dummy_sd; }
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;
78  ssize_t SendTo(ola::io::IOVecInterface *data,
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 EnableBroadcast();
92  bool SetMulticastInterface(const ola::network::IPV4Address &interface);
93  bool JoinMulticast(const ola::network::IPV4Address &interface,
94  const ola::network::IPV4Address &group,
95  bool loop = false);
96  bool LeaveMulticast(const ola::network::IPV4Address &interface,
97  const ola::network::IPV4Address &group);
98 
99  bool SetTos(uint8_t tos);
100 
101  void SetDiscardMode(bool discard_mode) { m_discard_mode = discard_mode; }
102 
103  // these are methods used for verification
104  void AddExpectedData(const uint8_t *data,
105  unsigned int size,
106  const ola::network::IPV4Address &ip,
107  uint16_t port);
108  void AddExpectedData(ola::io::IOQueue *queue,
109  const ola::network::IPV4SocketAddress &dest);
110 
111  // this can be fetched by calling PerformRead() on the socket
112  void InjectData(const uint8_t *data,
113  unsigned int size,
114  const ola::network::IPV4Address &ip,
115  uint16_t port);
116  void InjectData(const uint8_t *data,
117  unsigned int size,
118  const ola::network::IPV4SocketAddress &source);
119  void InjectData(ola::io::IOQueue *ioqueue,
120  const ola::network::IPV4SocketAddress &source);
121 
122  void Verify();
123 
124  bool CheckNetworkParamsMatch(bool init_called,
125  bool bound_to_port,
126  uint16_t port,
127  bool broadcast_set);
128 
129  void SetInterface(const ola::network::IPV4Address &interface);
130 
131  private:
132  typedef struct {
133  const uint8_t *data;
134  unsigned int size;
136  uint16_t port;
137  bool free_data;
138  } expected_call;
139 
140  typedef expected_call received_data;
141 
142  bool m_init_called;
143  // We need a sd so that calls to select continue to work. This isn't used
144  // for anything else.
145  int m_dummy_sd;
146  bool m_bound_to_port;
147  bool m_broadcast_set;
148  uint16_t m_port;
149  uint8_t m_tos;
150  mutable std::queue<expected_call> m_expected_calls;
151  mutable std::queue<received_data> m_received_data;
152  ola::network::IPV4Address m_interface;
153  bool m_discard_mode;
154 
155  uint8_t* IOQueueToBuffer(ola::io::IOQueue *ioqueue,
156  unsigned int *size) const;
157 
158  DISALLOW_COPY_AND_ASSIGN(MockUDPSocket);
159 };
160 
161 
166  public:
167  explicit SocketVerifier(MockUDPSocket *socket)
168  : m_socket(socket) {
169  }
170  ~SocketVerifier() {
171  m_socket->Verify();
172  }
173 
174  private:
175  MockUDPSocket *m_socket;
176 
177  DISALLOW_COPY_AND_ASSIGN(SocketVerifier);
178 };
179 } // namespace testing
180 } // namespace ola
181 #endif // INCLUDE_OLA_TESTING_MOCKUDPSOCKET_H_