20 #include <ripple/app/rdb/ShardArchive.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);
185 (numberOfDownloads + 1);
192 BEAST_EXPECT(handler);
196 auto host = server->local_endpoint().address().to_string();
200 Downloads const dl = [count = numberOfDownloads, &host, &port] {
203 for (
int i = 1; i <= count; ++i)
207 (boost::format(
"https://%s:%d/%d.tar.lz4") % host % port %
215 for (
auto const& entry : dl)
219 handler->add(entry.first, {url, entry.second});
222 BEAST_EXPECT(handler->start());
230 boost::filesystem::exists(stateDir) || handler->archives_.empty());
232 using namespace std::chrono_literals;
235 while (!handler->archives_.empty())
240 if (waitMax -= 1s; waitMax <= 0s)
249 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
260 testcase(
"testDownloadsAndRestart");
268 section.set(
"path", tempDir.
path());
269 section.set(
"max_historical_shards",
"20");
270 section.set(
"ledgers_per_shard",
"256");
271 section.set(
"earliest_seq",
"257");
275 section.set(
"ledgers_per_shard",
"256");
276 section.set(
"earliest_seq",
"257");
278 c->setupControl(
true,
true,
true);
289 (numberOfDownloads + 1);
296 BEAST_EXPECT(handler);
301 auto host = server->local_endpoint().address().to_string();
305 Downloads const dl = [count = numberOfDownloads, &host, &port] {
308 for (
int i = 1; i <= count; ++i)
312 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
320 for (
auto const& entry : dl)
324 handler->add(entry.first, {url, entry.second});
330 boost::filesystem::copy_file(
334 BEAST_EXPECT(handler->start());
339 boost::filesystem::exists(stateDir) ||
340 handler->archives_.empty());
342 using namespace std::chrono_literals;
345 while (!handler->archives_.empty())
350 if (waitMax -= 1s; waitMax <= 0s)
359 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
361 boost::filesystem::create_directory(stateDir);
363 boost::filesystem::copy_file(
371 section.set(
"path", tempDir.
path());
372 section.set(
"max_historical_shards",
"20");
373 section.set(
"shard_verification_retry_interval",
"1");
374 section.set(
"shard_verification_max_attempts",
"10000");
375 section.set(
"ledgers_per_shard",
"256");
376 section.set(
"earliest_seq",
"257");
380 section.set(
"ledgers_per_shard",
"256");
381 section.set(
"earliest_seq",
"257");
383 c->setupControl(
true,
true,
true);
393 (numberOfDownloads + 1);
408 boost::filesystem::exists(stateDir) || handler->archives_.empty());
410 using namespace std::chrono_literals;
413 while (!handler->archives_.empty())
418 if (waitMax -= 1s; waitMax <= 0s)
427 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
435 testcase(
"testShardCountFailure");
444 section.set(
"path", tempDir.
path());
445 section.set(
"max_historical_shards",
"1");
446 section.set(
"ledgers_per_shard",
"256");
447 section.set(
"earliest_seq",
"257");
451 section.set(
"ledgers_per_shard",
"256");
452 section.set(
"earliest_seq",
"257");
454 c->setupControl(
true,
true,
true);
457 jtx::Env env(*
this, std::move(c), std::move(logs));
465 (numberOfDownloads + 1);
472 BEAST_EXPECT(handler);
477 auto host = server->local_endpoint().address().to_string();
481 Downloads const dl = [count = numberOfDownloads, &host, &port] {
484 for (
int i = 1; i <= count; ++i)
488 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
496 for (
auto const& entry : dl)
500 handler->add(entry.first, {url, entry.second});
503 BEAST_EXPECT(!handler->start());
508 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
511 auto const expectedErrorMessage =
512 "shards 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 maximum number of historical "
515 capturedLogs.
find(expectedErrorMessage) != std::string::npos);
523 section.set(
"path", tempDir.
path());
524 section.set(
"max_historical_shards",
"0");
525 section.set(
"ledgers_per_shard",
"256");
526 section.set(
"earliest_seq",
"257");
530 section.set(
"ledgers_per_shard",
"256");
531 section.set(
"earliest_seq",
"257");
533 c->setupControl(
true,
true,
true);
536 jtx::Env env(*
this, std::move(c), std::move(logs));
544 ((numberOfDownloads * 3) + 1);
551 BEAST_EXPECT(handler);
556 auto host = server->local_endpoint().address().to_string();
560 Downloads const dl = [count = numberOfDownloads, &host, &port] {
563 for (
int i = 1; i <= count; ++i)
567 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
575 for (
auto const& entry : dl)
579 handler->add(entry.first, {url, entry.second});
582 BEAST_EXPECT(!handler->start());
587 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
590 auto const expectedErrorMessage2 =
591 "shard 1 maximum number of historical shards reached";
593 capturedLogs.
find(expectedErrorMessage2) != std::string::npos);
602 testcase(
"testRedundantShardFailure");
611 section.set(
"path", tempDir.
path());
612 section.set(
"max_historical_shards",
"1");
613 section.set(
"ledgers_per_shard",
"256");
614 section.set(
"earliest_seq",
"257");
618 section.set(
"ledgers_per_shard",
"256");
619 section.set(
"earliest_seq",
"257");
621 c->setupControl(
true,
true,
true);
636 (numberOfDownloads + 1);
645 BEAST_EXPECT(handler);
650 auto host = server->local_endpoint().address().to_string();
654 Downloads const dl = [count = numberOfDownloads, &host, &port] {
657 for (
int i = 1; i <= count; ++i)
661 (boost::format(
"https://%s:%d/%d.tar.lz4") % host %
669 for (
auto const& entry : dl)
673 handler->add(entry.first, {url, entry.second});
676 BEAST_EXPECT(!handler->start());
681 BEAST_EXPECT(!boost::filesystem::exists(stateDir));
684 auto const expectedErrorMessage =
685 "shard 1 is already queued for import";
687 capturedLogs.
find(expectedErrorMessage) != std::string::npos);