20 #include <ripple/app/rdb/RelationalDBInterface_shards.h>
21 #include <ripple/beast/utility/temp_dir.h>
22 #include <ripple/core/ConfigSections.h>
23 #include <ripple/nodestore/DummyScheduler.h>
24 #include <ripple/nodestore/Manager.h>
25 #include <ripple/nodestore/impl/DecodedBlob.h>
26 #include <ripple/protocol/jss.h>
27 #include <ripple/rpc/ShardArchiveHandler.h>
28 #include <test/jtx/CaptureLogs.h>
29 #include <test/jtx/Env.h>
30 #include <test/jtx/TrustedPublisherServer.h>
31 #include <test/jtx/envconfig.h>
32 #include <test/nodestore/TestBase.h>
62 testcase(
"testSingleDownloadAndStateDB");
68 section.set(
"path", tempDir.
path());
69 section.set(
"max_historical_shards",
"20");
70 c->setupControl(
true,
true,
true);
74 BEAST_EXPECT(handler);
77 std::string const rawUrl =
"https://foo:443/1.tar.lz4";
81 handler->add(1, {url, rawUrl});
88 *handler->sqlDB_, [&](
std::string const& url,
int state) {
89 BEAST_EXPECT(state == 1);
90 BEAST_EXPECT(url == rawUrl);
94 BEAST_EXPECT(rowCount == 1);
106 testcase(
"testDownloadsAndStateDB");
112 section.set(
"path", tempDir.
path());
113 section.set(
"max_historical_shards",
"20");
114 c->setupControl(
true,
true,
true);
118 BEAST_EXPECT(handler);
122 {1,
"https://foo:443/1.tar.lz4"},
123 {2,
"https://foo:443/2.tar.lz4"},
124 {3,
"https://foo:443/3.tar.lz4"}};
126 for (
auto const& entry : dl)
130 handler->add(entry.first, {url, entry.second});
138 *handler->sqlDB_, [&](
std::string const& url,
int state) {
139 BEAST_EXPECT(state == dl[pos].first);
140 BEAST_EXPECT(url == dl[pos].second);
144 BEAST_EXPECT(pos == dl.size());
157 testcase(
"testDownloadsAndFileSystem");
164 section.set(
"path", tempDir.
path());
165 section.set(
"max_historical_shards",
"20");
166 section.set(
"ledgers_per_shard",
"256");
167 section.set(
"earliest_seq",
"257");
171 section.set(
"ledgers_per_shard",
"256");
172 section.set(
"earliest_seq",
"257");
174 c->setupControl(
true,
true,
true);
184 (numberOfDownloads + 1);
191 BEAST_EXPECT(handler);
195 auto host = server->local_endpoint().address().to_string();
199 Downloads const dl = [count = numberOfDownloads, &host, &port] {
202 for (
int i = 1; i <= count; ++i)
206 (boost::format(
"https://%s:%d/%d.tar.lz4") % host % port %
214 for (
auto const& entry : dl)
218 handler->add(entry.first, {url, entry.second});
221 BEAST_EXPECT(handler->start());
229 boost::filesystem::exists(stateDir) || handler->archives_.empty());
231 using namespace std::chrono_literals;
234 while (!handler->archives_.empty())
239 if (waitMax -= 1s; waitMax <= 0s)
248 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
259 testcase(
"testDownloadsAndRestart");
267 section.set(
"path", tempDir.
path());
268 section.set(
"max_historical_shards",
"20");
269 section.set(
"ledgers_per_shard",
"256");
270 section.set(
"earliest_seq",
"257");
274 section.set(
"ledgers_per_shard",
"256");
275 section.set(
"earliest_seq",
"257");
277 c->setupControl(
true,
true,
true);
287 (numberOfDownloads + 1);
294 BEAST_EXPECT(handler);
299 auto host = server->local_endpoint().address().to_string();
303 Downloads const dl = [count = numberOfDownloads, &host, &port] {
306 for (
int i = 1; i <= count; ++i)
310 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
318 for (
auto const& entry : dl)
322 handler->add(entry.first, {url, entry.second});
328 boost::filesystem::copy_file(
332 BEAST_EXPECT(handler->start());
337 boost::filesystem::exists(stateDir) ||
338 handler->archives_.empty());
340 using namespace std::chrono_literals;
343 while (!handler->archives_.empty())
348 if (waitMax -= 1s; waitMax <= 0s)
357 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
359 boost::filesystem::create_directory(stateDir);
361 boost::filesystem::copy_file(
369 section.set(
"path", tempDir.
path());
370 section.set(
"max_historical_shards",
"20");
371 section.set(
"shard_verification_retry_interval",
"1");
372 section.set(
"shard_verification_max_attempts",
"10000");
373 section.set(
"ledgers_per_shard",
"256");
374 section.set(
"earliest_seq",
"257");
378 section.set(
"ledgers_per_shard",
"256");
379 section.set(
"earliest_seq",
"257");
381 c->setupControl(
true,
true,
true);
390 (numberOfDownloads + 1);
405 boost::filesystem::exists(stateDir) || handler->archives_.empty());
407 using namespace std::chrono_literals;
410 while (!handler->archives_.empty())
415 if (waitMax -= 1s; waitMax <= 0s)
424 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
432 testcase(
"testShardCountFailure");
441 section.set(
"path", tempDir.
path());
442 section.set(
"max_historical_shards",
"1");
443 section.set(
"ledgers_per_shard",
"256");
444 section.set(
"earliest_seq",
"257");
448 section.set(
"ledgers_per_shard",
"256");
449 section.set(
"earliest_seq",
"257");
451 c->setupControl(
true,
true,
true);
454 jtx::Env env(*
this, std::move(c), std::move(logs));
462 (numberOfDownloads + 1);
469 BEAST_EXPECT(handler);
474 auto host = server->local_endpoint().address().to_string();
478 Downloads const dl = [count = numberOfDownloads, &host, &port] {
481 for (
int i = 1; i <= count; ++i)
485 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
493 for (
auto const& entry : dl)
497 handler->add(entry.first, {url, entry.second});
500 BEAST_EXPECT(!handler->start());
505 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
508 auto const expectedErrorMessage =
509 "shards 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 maximum number of historical "
512 capturedLogs.
find(expectedErrorMessage) != std::string::npos);
520 section.set(
"path", tempDir.
path());
521 section.set(
"max_historical_shards",
"0");
522 section.set(
"ledgers_per_shard",
"256");
523 section.set(
"earliest_seq",
"257");
527 section.set(
"ledgers_per_shard",
"256");
528 section.set(
"earliest_seq",
"257");
530 c->setupControl(
true,
true,
true);
533 jtx::Env env(*
this, std::move(c), std::move(logs));
541 ((numberOfDownloads * 3) + 1);
548 BEAST_EXPECT(handler);
553 auto host = server->local_endpoint().address().to_string();
557 Downloads const dl = [count = numberOfDownloads, &host, &port] {
560 for (
int i = 1; i <= count; ++i)
564 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
572 for (
auto const& entry : dl)
576 handler->add(entry.first, {url, entry.second});
579 BEAST_EXPECT(!handler->start());
584 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
587 auto const expectedErrorMessage2 =
588 "shard 1 maximum number of historical shards reached";
590 capturedLogs.
find(expectedErrorMessage2) != std::string::npos);
599 testcase(
"testRedundantShardFailure");
608 section.set(
"path", tempDir.
path());
609 section.set(
"max_historical_shards",
"1");
610 section.set(
"ledgers_per_shard",
"256");
611 section.set(
"earliest_seq",
"257");
615 section.set(
"ledgers_per_shard",
"256");
616 section.set(
"earliest_seq",
"257");
618 c->setupControl(
true,
true,
true);
633 (numberOfDownloads + 1);
642 BEAST_EXPECT(handler);
647 auto host = server->local_endpoint().address().to_string();
651 Downloads const dl = [count = numberOfDownloads, &host, &port] {
654 for (
int i = 1; i <= count; ++i)
658 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
666 for (
auto const& entry : dl)
670 handler->add(entry.first, {url, entry.second});
673 BEAST_EXPECT(!handler->start());
678 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
681 auto const expectedErrorMessage =
682 "shard 1 is already queued for import";
684 capturedLogs.
find(expectedErrorMessage) != std::string::npos);