blob: e227167a9922258021181ba1f2b8cdd63f7965bd [file] [log] [blame]
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento9a8d7d82019-03-15 20:14:25 -04002/*
Davide Pesaventod8521aa2023-09-17 14:21:27 -04003 * Copyright (c) 2014-2023, Regents of the University of California.
Alexander Afanasyeve1e6f2a2014-04-25 11:28:12 -07004 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070018 */
19
Alexander Afanasyev39d98072014-05-04 12:46:29 -070020#include "handles/tcp-bulk-insert-handle.hpp"
Davide Pesavento164ae3b2023-11-11 22:00:23 -050021
Weiqi Shif0330d52014-07-09 10:54:27 -070022#include "../repo-storage-fixture.hpp"
Shuo Chenca329182014-03-19 18:05:18 -070023#include "../dataset-fixtures.hpp"
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070024
Davide Pesavento164ae3b2023-11-11 22:00:23 -050025#include <boost/asio/ip/tcp.hpp>
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070026#include <boost/test/unit_test.hpp>
27
Davide Pesavento11904062022-04-14 22:33:28 -040028namespace repo::tests {
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070029
30BOOST_AUTO_TEST_SUITE(TcpBulkInsertHandle)
31
32class TcpClient
33{
34public:
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070035 void
36 start(const std::string& host, const std::string& port)
37 {
Davide Pesavento164ae3b2023-11-11 22:00:23 -050038 boost::asio::ip::tcp::resolver resolver(ioCtx);
39 boost::system::error_code ec;
40 auto results = resolver.resolve(host, port, ec);
41 if (ec) {
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070042 BOOST_FAIL("Cannot resolve [" + host + ":" + port + "]");
Davide Pesavento164ae3b2023-11-11 22:00:23 -050043 }
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070044
Davide Pesavento164ae3b2023-11-11 22:00:23 -050045 socket.async_connect(*results.begin(), std::bind(&TcpClient::handleConnect, this, _1));
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070046 }
47
48 virtual void
Davide Pesavento164ae3b2023-11-11 22:00:23 -050049 handleConnect(const boost::system::error_code& error)
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070050 {
weijia yuan3aa8d2b2018-03-06 15:35:57 -080051 if (error) {
Davide Pesavento164ae3b2023-11-11 22:00:23 -050052 BOOST_FAIL("TCP connection failed");
weijia yuan3aa8d2b2018-03-06 15:35:57 -080053 }
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070054 }
55
56public:
Davide Pesaventod8521aa2023-09-17 14:21:27 -040057 boost::asio::io_context ioCtx;
58 boost::asio::ip::tcp::socket socket{ioCtx};
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070059};
60
61template<class Dataset>
62class TcpBulkInsertFixture : public TcpClient,
Weiqi Shif0330d52014-07-09 10:54:27 -070063 public RepoStorageFixture,
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070064 public Dataset
65{
66public:
67 TcpBulkInsertFixture()
Davide Pesaventod8521aa2023-09-17 14:21:27 -040068 : scheduler(ioCtx)
69 , bulkInserter(ioCtx, *handle)
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070070 {
Davide Pesavento8891c832019-03-20 23:20:35 -040071 guardEvent = scheduler.schedule(2_s, std::bind(&TcpBulkInsertFixture::fail, this, "Test timed out"));
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070072 }
73
Davide Pesavento7df36bd2023-10-28 19:32:43 -040074 void
Davide Pesavento164ae3b2023-11-11 22:00:23 -050075 handleConnect(const boost::system::error_code& error) override
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070076 {
Davide Pesavento164ae3b2023-11-11 22:00:23 -050077 TcpClient::handleConnect(error);
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070078
79 // This value may need to be adjusted if some dataset exceeds 100k
80 socket.set_option(boost::asio::socket_base::send_buffer_size(100000));
81
82 // Initially I wrote the following to use scatter-gather approach (using
83 // std::vector<const_buffer> and a single socket.async_send operation). Unfortunately, as
84 // described in http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/overview/implementation.html,
85 // scatter-gather is limited to at most `min(64,IOV_MAX)` buffers to be transmitted
86 // in a single operation
weijia yuan3aa8d2b2018-03-06 15:35:57 -080087 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040088 socket.async_send(boost::asio::buffer((*i)->wireEncode()),
weijia yuan3aa8d2b2018-03-06 15:35:57 -080089 std::bind(&TcpBulkInsertFixture::onSendFinished, this, _1, false));
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070090 }
weijia yuan3aa8d2b2018-03-06 15:35:57 -080091 onSendFinished(error, true);
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -070092 }
93
94 void
95 onSendFinished(const boost::system::error_code& error, bool isFinal)
96 {
97 if (error) {
98 BOOST_FAIL("TCP connection aborted");
99 return;
100 }
101
102 if (isFinal) {
Davide Pesavento8891c832019-03-20 23:20:35 -0400103 guardEvent.cancel();
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700104
105 // In case there are some outstanding handlers
Davide Pesavento8891c832019-03-20 23:20:35 -0400106 scheduler.schedule(1_s, [this] { stop(); });
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700107 }
108 }
109
110 void
111 fail(const std::string& info)
112 {
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400113 ioCtx.stop();
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700114 BOOST_FAIL(info);
115 }
116
117 void
118 stop()
119 {
120 // Terminate test
121 socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
122 socket.close();
123
124 bulkInserter.stop();
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400125 // may be ioCtx.stop() as well
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700126 }
127
128public:
129 Scheduler scheduler;
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400130 ndn::scheduler::EventId guardEvent;
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700131 repo::TcpBulkInsertHandle bulkInserter;
132};
133
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800134BOOST_FIXTURE_TEST_CASE_TEMPLATE(BulkInsertAndRead, T, CommonDatasets, TcpBulkInsertFixture<T>)
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700135{
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700136 // start bulk inserter
137 this->bulkInserter.listen("localhost", "17376");
138
139 // start test
140 this->start("localhost", "17376");
141
142 // actually run the test
Davide Pesaventod8521aa2023-09-17 14:21:27 -0400143 this->ioCtx.run();
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700144
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700145 // Read (all items should exist)
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800146 for (auto i = this->interests.begin(); i != this->interests.end(); ++i) {
147 BOOST_CHECK_EQUAL(*this->handle->readData(i->first), *i->second);
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700148 }
149}
150
Alexander Afanasyevb0c78ea2014-04-15 18:12:04 -0700151BOOST_AUTO_TEST_SUITE_END()
152
Davide Pesavento11904062022-04-14 22:33:28 -0400153} // namespace repo::tests