Monero
net_load_tests.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 
33 #include <atomic>
34 
35 #include <boost/asio/io_service.hpp>
36 #include <boost/uuid/uuid_io.hpp>
37 
38 #include "include_base_utils.h"
39 #include "string_tools.h"
43 
44 #include "../unit_tests/unit_tests_utils.h"
45 
46 namespace net_load_tests
47 {
49  {
50  test_connection_context(): epee::net_utils::connection_context_base(boost::uuids::nil_uuid(), {}, false, false), m_closed(false) {}
51  static constexpr int handshake_command() noexcept { return 1001; }
52  static constexpr bool handshake_complete() noexcept { return true; }
53  size_t get_max_bytes(int command) const { return LEVIN_DEFAULT_MAX_PACKET_SIZE; }
54  volatile bool m_closed;
55  };
56 
61 
62  struct test_levin_commands_handler : public epee::levin::levin_commands_handler<test_connection_context>
63  {
65  //: m_return_code(LEVIN_OK)
66  //, m_last_command(-1)
67  {
68  }
69 
70  virtual int invoke(int command, const epee::span<const uint8_t> in_buff, epee::byte_stream& buff_out, test_connection_context& context)
71  {
72  //m_invoke_counter.inc();
73  //std::unique_lock<std::mutex> lock(m_mutex);
74  //m_last_command = command;
75  //m_last_in_buf = in_buff;
76  //buff_out = m_invoke_out_buf;
77  //return m_return_code;
78  return LEVIN_OK;
79  }
80 
81  virtual int notify(int command, const epee::span<const uint8_t> in_buff, test_connection_context& context)
82  {
83  //m_notify_counter.inc();
84  //std::unique_lock<std::mutex> lock(m_mutex);
85  //m_last_command = command;
86  //m_last_in_buf = in_buff;
87  //return m_return_code;
88  return LEVIN_OK;
89  }
90 
92  {
93  //m_callback_counter.inc();
94  //std::cout << "test_levin_commands_handler::callback()" << std::endl;
95  }
96 
98  {
100  //std::cout << "test_levin_commands_handler::on_connection_new()" << std::endl;
101  }
102 
104  {
106  //std::cout << "test_levin_commands_handler::on_connection_close()" << std::endl;
107  }
108 
109  //size_t invoke_counter() const { return m_invoke_counter.get(); }
110  //size_t notify_counter() const { return m_notify_counter.get(); }
111  //size_t callback_counter() const { return m_callback_counter.get(); }
114 
115  //int return_code() const { return m_return_code; }
116  //void return_code(int v) { m_return_code = v; }
117 
118  //const std::string& invoke_out_buf() const { return m_invoke_out_buf; }
119  //void invoke_out_buf(const std::string& v) { m_invoke_out_buf = v; }
120 
121  //int last_command() const { return m_last_command; }
122  //const std::string& last_in_buf() const { return m_last_in_buf; }
123 
124  protected:
125  //unit_test::call_counter m_invoke_counter;
126  //unit_test::call_counter m_notify_counter;
127  //unit_test::call_counter m_callback_counter;
130 
131  //std::mutex m_mutex;
132 
133  //int m_return_code;
134  //std::string m_invoke_out_buf;
135 
136  //int m_last_command;
137  //std::string m_last_in_buf;
138  };
139 
141  {
142  public:
143  open_close_test_helper(test_tcp_server& tcp_server, size_t open_request_target, size_t max_opened_connection_count)
144  : m_tcp_server(tcp_server)
145  , m_max_opened_connection_count(max_opened_connection_count)
149  , m_connections(open_request_target)
150  {
151  for (auto& conn_id : m_connections)
152  conn_id = boost::uuids::nil_uuid();
153  }
154 
155  bool handle_new_connection(const boost::uuids::uuid& connection_id, bool ignore_close_fails = false)
156  {
157  size_t idx = m_next_opened_conn_idx.fetch_add(1, std::memory_order_relaxed);
158  if (idx >= m_connections.size())
159  {
160  LOG_PRINT_L0("ERROR: connections overflow");
161  exit(1);
162  }
163  m_connections[idx] = connection_id;
164 
165  size_t prev_connection_count = m_opened_connection_count.fetch_add(1, std::memory_order_relaxed);
166  if (m_max_opened_connection_count <= prev_connection_count)
167  {
168  return close_next_connection(ignore_close_fails);
169  }
170 
171  return true;
172  }
173 
175  {
176  while (close_next_connection(false));
177  }
178 
179  bool close_next_connection(bool ignore_close_fails)
180  {
181  size_t idx = m_next_closed_conn_idx.fetch_add(1, std::memory_order_relaxed);
182  if (m_next_opened_conn_idx.load(std::memory_order_relaxed) <= idx)
183  {
184  LOG_PRINT_L0("Not enough opened connections");
185  return false;
186  }
187  if (m_connections[idx].is_nil())
188  {
189  LOG_PRINT_L0("Connection isn't opened");
190  return false;
191  }
192  if (!m_tcp_server.get_config_object().close(m_connections[idx]))
193  {
194  LOG_PRINT_L0("Close connection error: " << m_connections[idx]);
195  if (!ignore_close_fails)
196  {
197  return false;
198  }
199  }
200 
201  m_connections[idx] = boost::uuids::nil_uuid();
202  m_opened_connection_count.fetch_sub(1, std::memory_order_relaxed);
203  return true;
204  }
205 
206  size_t opened_connection_count() const { return m_opened_connection_count.load(std::memory_order_relaxed); }
207 
208  private:
211  std::atomic<size_t> m_opened_connection_count;
212  std::atomic<size_t> m_next_opened_conn_idx;
213  std::atomic<size_t> m_next_closed_conn_idx;
214  std::vector<boost::uuids::uuid> m_connections;
215  };
216 
217  const unsigned int min_thread_count = 2;
218  const std::string clt_port("36230");
219  const std::string srv_port("36231");
220 
222  {
230  };
231 
233  {
234  const static int ID = cmd_close_all_connections_id;
235 
236  struct request
237  {
240  };
241  };
242 
244  {
245  const static int ID = cmd_start_open_close_test_id;
246 
247  struct request
248  {
251 
256  };
257 
258  struct response
259  {
262  };
263  };
264 
266  {
267  const static int ID = cmd_get_statistics_id;
268 
269  struct request
270  {
273  };
274 
275  struct response
276  {
280 
282  KV_SERIALIZE(opened_connections_count)
283  KV_SERIALIZE(new_connection_counter)
284  KV_SERIALIZE(close_connection_counter)
286 
287  std::string to_string() const
288  {
289  std::stringstream ss;
290  ss << "opened_connections_count = " << opened_connections_count <<
291  ", new_connection_counter = " << new_connection_counter <<
292  ", close_connection_counter = " << close_connection_counter;
293  return ss.str();
294  }
295  };
296  };
297 
299  {
300  const static int ID = cmd_reset_statistics_id;
301 
302  struct request
303  {
306  };
307 
308  struct response
309  {
312  };
313  };
314 
316  {
317  const static int ID = cmd_shutdown_id;
318 
319  struct request
320  {
323  };
324  };
325 
327  {
328  const static int ID = cmd_send_data_requests_id;
329 
330  struct request
331  {
333 
335  KV_SERIALIZE(request_size)
337  };
338  };
339 
341  {
342  const static int ID = cmd_data_request_id;
343 
344  struct request
345  {
348 
352  };
353 
354  struct response
355  {
357 
361  };
362  };
363 }
epee::net_utils::connection< test_levin_protocol_handler > test_connection
Definition: net_load_tests.h:59
Definition: net_load_tests.h:62
bool close_next_connection(bool ignore_close_fails)
Definition: net_load_tests.h:179
virtual int notify(int command, const epee::span< const uint8_t > in_buff, test_connection_context &context)
Definition: net_load_tests.h:81
std::vector< boost::uuids::uuid > m_connections
Definition: net_load_tests.h:214
Definition: abstract_tcp_server2.h:322
Definition: net_load_tests.h:232
void inc() volatile
Definition: unit_tests_utils.h:48
Definition: net_load_tests.h:330
Definition: portable_binary_archive.hpp:29
Definition: net_load_tests.h:226
size_t get_max_bytes(int command) const
Definition: net_load_tests.h:53
uint64_t close_connection_counter
Definition: net_load_tests.h:279
::std::string string
Definition: gtest-port.h:1097
Definition: net_load_tests.h:228
Definition: net_load_tests.h:224
A partial drop-in replacement for std::ostream.
Definition: byte_stream.h:57
const std::string clt_port("36230")
epee::net_utils::boosted_tcp_server< test_levin_protocol_handler > test_tcp_server
Definition: net_load_tests.h:60
Definition: net_load_tests.h:227
std::string data
Definition: net_load_tests.h:346
Definition: net_utils_base.h:364
std::string data
Definition: base58.cpp:37
static const int ID
Definition: net_load_tests.h:245
Definition: net_load_tests.h:319
Definition: enums.h:67
Non-owning sequence of data. Does not deep copy.
Definition: span.h:54
std::atomic< size_t > m_opened_connection_count
Definition: net_load_tests.h:211
#define KV_SERIALIZE(varialble)
Definition: keyvalue_serialization.h:118
command_ids
Definition: net_load_tests.h:221
volatile bool m_closed
Definition: net_load_tests.h:54
Definition: net_load_tests.h:298
#define LEVIN_DEFAULT_MAX_PACKET_SIZE
Definition: levin_base.h:77
Definition: net_load_tests.h:340
Definition: net_load_tests.h:48
void close_remaining_connections()
Definition: net_load_tests.h:174
unit_test::call_counter m_close_connection_counter
Definition: net_load_tests.h:129
uint64_t response_size
Definition: net_load_tests.h:347
Definition: net_load_tests.h:344
uint64_t open_request_target
Definition: net_load_tests.h:249
const char * uuid
Definition: minissdp.c:598
Definition: net_load_tests.h:46
Definition: levin_base.h:90
the connection templated-class for one peer connection
Represents a single connection from a client.
Definition: abstract_tcp_server2.h:86
virtual int invoke(int command, const epee::span< const uint8_t > in_buff, epee::byte_stream &buff_out, test_connection_context &context)
Definition: net_load_tests.h:70
epee::levin::async_protocol_handler_config< test_connection_context > test_levin_protocol_handler_config
Definition: net_load_tests.h:58
unit_test::call_counter m_new_connection_counter
Definition: net_load_tests.h:128
unsigned __int64 uint64_t
Definition: stdint.h:136
connection_context_base()
Definition: net_utils_base.h:399
size_t close_connection_counter() const
Definition: net_load_tests.h:113
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
Definition: zmq.h:105
static constexpr int handshake_command() noexcept
Definition: net_load_tests.h:51
virtual void callback(test_connection_context &context)
Definition: net_load_tests.h:91
uint64_t opened_connections_count
Definition: net_load_tests.h:277
std::atomic< size_t > m_next_closed_conn_idx
Definition: net_load_tests.h:213
virtual void on_connection_new(test_connection_context &context)
Definition: net_load_tests.h:97
epee::levin::async_protocol_handler< test_connection_context > test_levin_protocol_handler
Definition: net_load_tests.h:57
test_levin_commands_handler()
Definition: net_load_tests.h:64
bool handle_new_connection(const boost::uuids::uuid &connection_id, bool ignore_close_fails=false)
Definition: net_load_tests.h:155
std::string data
Definition: net_load_tests.h:356
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
virtual void on_connection_close(test_connection_context &context)
Definition: net_load_tests.h:103
const std::string srv_port("36231")
Definition: net_load_tests.h:225
Definition: net_load_tests.h:302
open_close_test_helper(test_tcp_server &tcp_server, size_t open_request_target, size_t max_opened_connection_count)
Definition: net_load_tests.h:143
uint64_t request_size
Definition: net_load_tests.h:332
Definition: net_load_tests.h:229
Definition: levin_protocol_handler_async.h:77
Definition: levin_protocol_handler_async.h:80
Definition: net_load_tests.h:265
size_t opened_connection_count() const
Definition: net_load_tests.h:206
const unsigned int min_thread_count
Definition: net_load_tests.h:217
size_t m_max_opened_connection_count
Definition: net_load_tests.h:210
std::atomic< size_t > m_next_opened_conn_idx
Definition: net_load_tests.h:212
Definition: net_load_tests.h:326
uint64_t new_connection_counter
Definition: net_load_tests.h:278
Definition: net_load_tests.h:308
Definition: net_load_tests.h:275
std::string to_string(t_connection_type type)
Definition: connection_basic.cpp:76
Definition: net_load_tests.h:315
test_tcp_server & m_tcp_server
Definition: net_load_tests.h:209
#define END_KV_SERIALIZE_MAP()
Definition: keyvalue_serialization.h:116
Definition: net_load_tests.h:140
uint64_t max_opened_conn_count
Definition: net_load_tests.h:250
static const int ID
Definition: net_load_tests.h:234
test_connection_context()
Definition: net_load_tests.h:50
Definition: unit_tests_utils.h:40
#define LEVIN_OK
Definition: levin_base.h:102
#define BEGIN_KV_SERIALIZE_MAP()
Definition: keyvalue_serialization.h:43
Definition: net_load_tests.h:243
Definition: net_load_tests.h:354
static constexpr bool handshake_complete() noexcept
Definition: net_load_tests.h:52
size_t get() volatile const
Definition: unit_tests_utils.h:54
size_t new_connection_counter() const
Definition: net_load_tests.h:112
Definition: net_load_tests.h:223
Definition: net_load_tests.h:269
t_protocol_handler::config_type & get_config_object()
Definition: abstract_tcp_server2.h:390