Kea  1.9.9-git
mock_socketsession.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef UTIL_UNITTESTS_MOCKSOCKETSESSION_H
8 #define UTIL_UNITTESTS_MOCKSOCKETSESSION_H 1
9 
10 #include <exceptions/exceptions.h>
11 
12 #include <util/io/socketsession.h>
13 #include <util/io/sockaddr_util.h>
14 
15 #include <cassert>
16 #include <cstring>
17 #include <vector>
18 
19 #include <sys/socket.h>
20 #include <stdint.h>
21 
22 namespace isc {
23 namespace util {
24 namespace unittests {
25 
33 {
34 public:
36  is_connected_(false), connect_ok_(true), push_ok_(true),
37  close_ok_(true),
38  // These are not used until set, but we set them anyway here,
39  // partly to silence cppcheck, and partly to be cleaner. Put some
40  // invalid values in.
41  pushed_sock_(-1), pushed_family_(-1), pushed_type_(-1),
42  pushed_protocol_(-1)
43  {}
44 
45  virtual void connectToReceiver() {
46  if (!connect_ok_) {
48  "forwarding connection disabled for test");
49  }
50  if (is_connected_) {
51  isc_throw(isc::util::io::SocketSessionError, "duplicate connect");
52  }
53  is_connected_ = true;
54  }
55  virtual void close() {
56  if (!is_connected_) {
57  isc_throw(isc::util::io::SocketSessionError, "duplicate close");
58  }
59  is_connected_ = false;
60  }
61 
62  // Pushing a socket session. It copies the given session data
63  // so that the test code can check the values later via the getter
64  // methods. Complete deep copy will be created, so the caller doesn't
65  // have to keep the parameters valid after the call to this method.
66  virtual void push(int sock, int family, int type, int protocol,
67  const struct sockaddr& local_end,
68  const struct sockaddr& remote_end,
69  const void* data, size_t data_len)
70  {
71  if (!push_ok_) {
73  "socket session forwarding is disabled for test");
74  }
75  if (!is_connected_) {
77  "socket session is being pushed before connected");
78  }
79 
80  // Copy parameters for later checks
81  pushed_sock_ = sock;
82  pushed_family_ = family;
83  pushed_type_ = type;
84  pushed_protocol_ = protocol;
85  assert(io::internal::getSALength(local_end) <=
86  sizeof(pushed_local_end_ss_));
87  std::memcpy(&pushed_local_end_ss_, &local_end,
88  io::internal::getSALength(local_end));
89  assert(io::internal::getSALength(remote_end) <=
90  sizeof(pushed_remote_end_ss_));
91  std::memcpy(&pushed_remote_end_ss_, &remote_end,
92  io::internal::getSALength(remote_end));
93  pushed_data_.resize(data_len);
94  std::memcpy(&pushed_data_[0], data, data_len);
95  }
96 
97  // Allow the test code to check if the connection is established.
98  bool isConnected() const { return (is_connected_); }
99 
100  // Allow the test code to customize the forwarder behavior wrt whether
101  // a specific operation should succeed or fail.
102  void disableConnect() { connect_ok_ = false; }
103  void enableConnect() { connect_ok_ = true; }
104  void disableClose() { close_ok_ = false; }
105  void disablePush() { push_ok_ = false; }
106  void enablePush() { push_ok_ = true; }
107 
108  // Read-only accessors to recorded parameters to the previous successful
109  // call to push(). Return values are undefined if there has been no
110  // successful call to push().
111  // Note that we use convertSockAddr() to convert sockaddr_storage to
112  // sockaddr. It should be safe since we use the storage in its literal
113  // sense; it was originally filled with the binary image of another
114  // sockaddr structure, and we are going to return the image opaquely
115  // as a sockaddr structure without touching the data.
116  int getPushedSock() const { return (pushed_sock_); }
117  int getPushedFamily() const { return (pushed_family_); }
118  int getPushedType() const { return (pushed_type_); }
119  int getPushedProtocol() const { return (pushed_protocol_); }
120  const struct sockaddr& getPushedLocalend() const {
121  return (*io::internal::convertSockAddr(&pushed_local_end_ss_));
122  }
123  const struct sockaddr& getPushedRemoteend() const {
124  return (*io::internal::convertSockAddr(&pushed_remote_end_ss_));
125  }
126  const std::vector<uint8_t>& getPushedData() const {
127  return (pushed_data_);
128  }
129 
130 private:
131  bool is_connected_;
132  bool connect_ok_;
133  bool push_ok_;
134  bool close_ok_;
135  int pushed_sock_;
136  int pushed_family_;
137  int pushed_type_;
138  int pushed_protocol_;
139  struct sockaddr_storage pushed_local_end_ss_;
140  struct sockaddr_storage pushed_remote_end_ss_;
141  std::vector<uint8_t> pushed_data_;
142 };
143 
144 } // end of unittests
145 } // end of util
146 } // end of isc
147 #endif // UTIL_UNITTESTS_MOCKSOCKETSESSION_H
148 
149 // Local Variables:
150 // mode: c++
151 // End:
socklen_t getSALength(const struct sockaddr &sa)
Definition: sockaddr_util.h:26
An exception indicating general errors that takes place in the socket session related class objects...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
The "base" class of SocketSessionForwarder.
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual void push(int sock, int family, int type, int protocol, const struct sockaddr &local_end, const struct sockaddr &remote_end, const void *data, size_t data_len)
const struct sockaddr * convertSockAddr(const SAType *sa)
Definition: sockaddr_util.h:41
const std::vector< uint8_t > & getPushedData() const
const struct sockaddr & getPushedLocalend() const
const struct sockaddr & getPushedRemoteend() const