diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
commit | 040eee1aa49b49df4698d83a05af57c220127fd1 (patch) | |
tree | f635435954e6ccde5eee9893889e24f30ca68346 /src/lib/util/unittests/mock_socketsession.h | |
parent | Initial commit. (diff) | |
download | isc-kea-upstream.tar.xz isc-kea-upstream.zip |
Adding upstream version 2.2.0.upstream/2.2.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/util/unittests/mock_socketsession.h')
-rw-r--r-- | src/lib/util/unittests/mock_socketsession.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/util/unittests/mock_socketsession.h b/src/lib/util/unittests/mock_socketsession.h new file mode 100644 index 0000000..808cddb --- /dev/null +++ b/src/lib/util/unittests/mock_socketsession.h @@ -0,0 +1,151 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef UTIL_UNITTESTS_MOCKSOCKETSESSION_H +#define UTIL_UNITTESTS_MOCKSOCKETSESSION_H 1 + +#include <exceptions/exceptions.h> + +#include <util/io/socketsession.h> +#include <util/io/sockaddr_util.h> + +#include <cassert> +#include <cstring> +#include <vector> + +#include <sys/socket.h> +#include <stdint.h> + +namespace isc { +namespace util { +namespace unittests { + +/// \brief Mock socket session forwarder. +/// +/// It emulates the behavior of SocketSessionForwarder without involving +/// network communication, and allowing the tester to customize the behavior +/// and to examine forwarded data afterwards. +class MockSocketSessionForwarder : + public isc::util::io::BaseSocketSessionForwarder +{ +public: + MockSocketSessionForwarder() : + is_connected_(false), connect_ok_(true), push_ok_(true), + close_ok_(true), + // These are not used until set, but we set them anyway here, + // partly to silence cppcheck, and partly to be cleaner. Put some + // invalid values in. + pushed_sock_(-1), pushed_family_(-1), pushed_type_(-1), + pushed_protocol_(-1) + {} + + virtual void connectToReceiver() { + if (!connect_ok_) { + isc_throw(isc::util::io::SocketSessionError, "socket session " + "forwarding connection disabled for test"); + } + if (is_connected_) { + isc_throw(isc::util::io::SocketSessionError, "duplicate connect"); + } + is_connected_ = true; + } + virtual void close() { + if (!is_connected_) { + isc_throw(isc::util::io::SocketSessionError, "duplicate close"); + } + is_connected_ = false; + } + + // Pushing a socket session. It copies the given session data + // so that the test code can check the values later via the getter + // methods. Complete deep copy will be created, so the caller doesn't + // have to keep the parameters valid after the call to this method. + 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) + { + if (!push_ok_) { + isc_throw(isc::util::io::SocketSessionError, + "socket session forwarding is disabled for test"); + } + if (!is_connected_) { + isc_throw(isc::util::io::SocketSessionError, + "socket session is being pushed before connected"); + } + + // Copy parameters for later checks + pushed_sock_ = sock; + pushed_family_ = family; + pushed_type_ = type; + pushed_protocol_ = protocol; + assert(io::internal::getSALength(local_end) <= + sizeof(pushed_local_end_ss_)); + std::memcpy(&pushed_local_end_ss_, &local_end, + io::internal::getSALength(local_end)); + assert(io::internal::getSALength(remote_end) <= + sizeof(pushed_remote_end_ss_)); + std::memcpy(&pushed_remote_end_ss_, &remote_end, + io::internal::getSALength(remote_end)); + pushed_data_.resize(data_len); + std::memcpy(&pushed_data_[0], data, data_len); + } + + // Allow the test code to check if the connection is established. + bool isConnected() const { return (is_connected_); } + + // Allow the test code to customize the forwarder behavior wrt whether + // a specific operation should succeed or fail. + void disableConnect() { connect_ok_ = false; } + void enableConnect() { connect_ok_ = true; } + void disableClose() { close_ok_ = false; } + void disablePush() { push_ok_ = false; } + void enablePush() { push_ok_ = true; } + + // Read-only accessors to recorded parameters to the previous successful + // call to push(). Return values are undefined if there has been no + // successful call to push(). + // Note that we use convertSockAddr() to convert sockaddr_storage to + // sockaddr. It should be safe since we use the storage in its literal + // sense; it was originally filled with the binary image of another + // sockaddr structure, and we are going to return the image opaquely + // as a sockaddr structure without touching the data. + int getPushedSock() const { return (pushed_sock_); } + int getPushedFamily() const { return (pushed_family_); } + int getPushedType() const { return (pushed_type_); } + int getPushedProtocol() const { return (pushed_protocol_); } + const struct sockaddr& getPushedLocalend() const { + return (*io::internal::convertSockAddr(&pushed_local_end_ss_)); + } + const struct sockaddr& getPushedRemoteend() const { + return (*io::internal::convertSockAddr(&pushed_remote_end_ss_)); + } + const std::vector<uint8_t>& getPushedData() const { + return (pushed_data_); + } + +private: + bool is_connected_; + bool connect_ok_; + bool push_ok_; + bool close_ok_; + int pushed_sock_; + int pushed_family_; + int pushed_type_; + int pushed_protocol_; + struct sockaddr_storage pushed_local_end_ss_; + struct sockaddr_storage pushed_remote_end_ss_; + std::vector<uint8_t> pushed_data_; +}; + +} // end of unittests +} // end of util +} // end of isc +#endif // UTIL_UNITTESTS_MOCKSOCKETSESSION_H + +// Local Variables: +// mode: c++ +// End: |