Skip to content

Commit f186414

Browse files
committed
test: put the generic parts from StaticContentsSock into a separate class
This allows reusing them in other mocked implementations.
1 parent 4b58d55 commit f186414

File tree

2 files changed

+79
-44
lines changed

2 files changed

+79
-44
lines changed

src/test/util/net.cpp

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -138,38 +138,31 @@ std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candida
138138
return candidates;
139139
}
140140

141-
StaticContentsSock::StaticContentsSock(const std::string& contents)
142-
: Sock{INVALID_SOCKET}, m_contents{contents}
143-
{
144-
}
141+
// Have different ZeroSock (or others that inherit from it) objects have different
142+
// m_socket because EqualSharedPtrSock compares m_socket and we want to avoid two
143+
// different objects comparing as equal.
144+
static std::atomic<SOCKET> g_mocked_sock_fd{0};
145145

146-
StaticContentsSock::~StaticContentsSock() { m_socket = INVALID_SOCKET; }
146+
ZeroSock::ZeroSock() : Sock{g_mocked_sock_fd++} {}
147147

148-
StaticContentsSock& StaticContentsSock::operator=(Sock&& other)
149-
{
150-
assert(false && "Move of Sock into MockSock not allowed.");
151-
return *this;
152-
}
148+
// Sock::~Sock() would try to close(2) m_socket if it is not INVALID_SOCKET, avoid that.
149+
ZeroSock::~ZeroSock() { m_socket = INVALID_SOCKET; }
153150

154-
ssize_t StaticContentsSock::Send(const void*, size_t len, int) const { return len; }
151+
ssize_t ZeroSock::Send(const void*, size_t len, int) const { return len; }
155152

156-
ssize_t StaticContentsSock::Recv(void* buf, size_t len, int flags) const
153+
ssize_t ZeroSock::Recv(void* buf, size_t len, int flags) const
157154
{
158-
const size_t consume_bytes{std::min(len, m_contents.size() - m_consumed)};
159-
std::memcpy(buf, m_contents.data() + m_consumed, consume_bytes);
160-
if ((flags & MSG_PEEK) == 0) {
161-
m_consumed += consume_bytes;
162-
}
163-
return consume_bytes;
155+
memset(buf, 0x0, len);
156+
return len;
164157
}
165158

166-
int StaticContentsSock::Connect(const sockaddr*, socklen_t) const { return 0; }
159+
int ZeroSock::Connect(const sockaddr*, socklen_t) const { return 0; }
167160

168-
int StaticContentsSock::Bind(const sockaddr*, socklen_t) const { return 0; }
161+
int ZeroSock::Bind(const sockaddr*, socklen_t) const { return 0; }
169162

170-
int StaticContentsSock::Listen(int) const { return 0; }
163+
int ZeroSock::Listen(int) const { return 0; }
171164

172-
std::unique_ptr<Sock> StaticContentsSock::Accept(sockaddr* addr, socklen_t* addr_len) const
165+
std::unique_ptr<Sock> ZeroSock::Accept(sockaddr* addr, socklen_t* addr_len) const
173166
{
174167
if (addr != nullptr) {
175168
// Pretend all connections come from 5.5.5.5:6789
@@ -183,38 +176,36 @@ std::unique_ptr<Sock> StaticContentsSock::Accept(sockaddr* addr, socklen_t* addr
183176
addr_in->sin_port = htons(6789);
184177
}
185178
}
186-
return std::make_unique<StaticContentsSock>("");
187-
};
179+
return std::make_unique<ZeroSock>();
180+
}
188181

189-
int StaticContentsSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
182+
int ZeroSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
190183
{
191184
std::memset(opt_val, 0x0, *opt_len);
192185
return 0;
193186
}
194187

195-
int StaticContentsSock::SetSockOpt(int, int, const void*, socklen_t) const { return 0; }
188+
int ZeroSock::SetSockOpt(int, int, const void*, socklen_t) const { return 0; }
196189

197-
int StaticContentsSock::GetSockName(sockaddr* name, socklen_t* name_len) const
190+
int ZeroSock::GetSockName(sockaddr* name, socklen_t* name_len) const
198191
{
199192
std::memset(name, 0x0, *name_len);
200193
return 0;
201194
}
202195

203-
bool StaticContentsSock::SetNonBlocking() const { return true; }
196+
bool ZeroSock::SetNonBlocking() const { return true; }
204197

205-
bool StaticContentsSock::IsSelectable() const { return true; }
198+
bool ZeroSock::IsSelectable() const { return true; }
206199

207-
bool StaticContentsSock::Wait(std::chrono::milliseconds timeout,
208-
Event requested,
209-
Event* occurred) const
200+
bool ZeroSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
210201
{
211202
if (occurred != nullptr) {
212203
*occurred = requested;
213204
}
214205
return true;
215206
}
216207

217-
bool StaticContentsSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
208+
bool ZeroSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
218209
{
219210
for (auto& [sock, events] : events_per_sock) {
220211
(void)sock;
@@ -223,7 +214,29 @@ bool StaticContentsSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSo
223214
return true;
224215
}
225216

226-
bool StaticContentsSock::IsConnected(std::string&) const
217+
ZeroSock& ZeroSock::operator=(Sock&& other)
227218
{
228-
return true;
219+
assert(false && "Move of Sock into ZeroSock not allowed.");
220+
return *this;
221+
}
222+
223+
StaticContentsSock::StaticContentsSock(const std::string& contents)
224+
: m_contents{contents}
225+
{
226+
}
227+
228+
ssize_t StaticContentsSock::Recv(void* buf, size_t len, int flags) const
229+
{
230+
const size_t consume_bytes{std::min(len, m_contents.size() - m_consumed)};
231+
std::memcpy(buf, m_contents.data() + m_consumed, consume_bytes);
232+
if ((flags & MSG_PEEK) == 0) {
233+
m_consumed += consume_bytes;
234+
}
235+
return consume_bytes;
236+
}
237+
238+
StaticContentsSock& StaticContentsSock::operator=(Sock&& other)
239+
{
240+
assert(false && "Move of Sock into StaticContentsSock not allowed.");
241+
return *this;
229242
}

src/test/util/net.h

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,15 @@ constexpr auto ALL_NETWORKS = std::array{
134134
};
135135

136136
/**
137-
* A mocked Sock alternative that returns a statically contained data upon read and succeeds
138-
* and ignores all writes. The data to be returned is given to the constructor and when it is
139-
* exhausted an EOF is returned by further reads.
137+
* A mocked Sock alternative that succeeds on all operations.
138+
* Returns infinite amount of 0x0 bytes on reads.
140139
*/
141-
class StaticContentsSock : public Sock
140+
class ZeroSock : public Sock
142141
{
143142
public:
144-
explicit StaticContentsSock(const std::string& contents);
145-
146-
~StaticContentsSock() override;
143+
ZeroSock();
147144

148-
StaticContentsSock& operator=(Sock&& other) override;
145+
~ZeroSock() override;
149146

150147
ssize_t Send(const void*, size_t len, int) const override;
151148

@@ -175,9 +172,34 @@ class StaticContentsSock : public Sock
175172

176173
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;
177174

178-
bool IsConnected(std::string&) const override;
175+
private:
176+
ZeroSock& operator=(Sock&& other) override;
177+
};
178+
179+
/**
180+
* A mocked Sock alternative that returns a statically contained data upon read and succeeds
181+
* and ignores all writes. The data to be returned is given to the constructor and when it is
182+
* exhausted an EOF is returned by further reads.
183+
*/
184+
class StaticContentsSock : public ZeroSock
185+
{
186+
public:
187+
explicit StaticContentsSock(const std::string& contents);
188+
189+
/**
190+
* Return parts of the contents that was provided at construction until it is exhausted
191+
* and then return 0 (EOF).
192+
*/
193+
ssize_t Recv(void* buf, size_t len, int flags) const override;
194+
195+
bool IsConnected(std::string&) const override
196+
{
197+
return true;
198+
}
179199

180200
private:
201+
StaticContentsSock& operator=(Sock&& other) override;
202+
181203
const std::string m_contents;
182204
mutable size_t m_consumed{0};
183205
};

0 commit comments

Comments
 (0)