Skip to content

Commit 1f74438

Browse files
author
Duc Hieu Pham
committed
Fix Travis's ability to run concurrently
Summary: Allow `db_cloud_test` and `db_test` to run concurrently * In `db_cloud_test`, we use a different db name for every test. * In `db_test`, we fix the use of `rand()` when naming the db by seeding it with a random number first. This change will help to reduce the run time of the test. Test Plan: https://travis-ci.org/github/rockset/rocksdb-cloud/builds/661196659 Reviewers: igor, dhruba Reviewed By: dhruba Differential Revision: https://rockset.phacility.com/D5644
1 parent bbaae82 commit 1f74438

File tree

4 files changed

+62
-31
lines changed

4 files changed

+62
-31
lines changed

.travis.yml

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,14 @@ addons:
2727

2828
jobs:
2929
include:
30-
- stage: db_test_part_1
30+
- stage: Test
3131
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=-DBTest.MergeTestTime:DBTest.UnsupportedManualSync:DBTest.ApproximateSizes*:DBTest.HiddenValuesAreRemoved:DBTest.UnremovableSingleDelete:DBTest.OverlapInLevel0:MultiThreaded/MultiThreadedDBTest*:DBTest.SingleDeleteFlush:DBTest.GetLevel0Ordering:DBTest.GetPicksCorrectFile
32-
- stage: db_test_part_2
33-
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.SingleDeleteFlush:DBTest.GetLevel0Ordering:DBTest.GetPicksCorrectFile
34-
- stage: db_test_part_3
35-
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.HiddenValuesAreRemoved
36-
- stage: db_test_part_4
37-
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.UnremovableSingleDelete
38-
- stage: db_test_part_5
39-
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=MultiThreaded/MultiThreadedDBTest*
40-
- stage: db_test2
41-
script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test2 db_basic_test env_basic_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test2 && LD_LIBRARY_PATH=/usr/local/lib ./db_basic_test --gtest_filter=-DBBasicTest.CompactBetweenSnapshots && LD_LIBRARY_PATH=/usr/local/lib ./env_basic_test
42-
- stage: cloud_test
43-
script: build_tools/spinup_kafka.sh && sleep 10 && OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_cloud_test cloud_manifest_test && LD_LIBRARY_PATH=/usr/local/lib ./db_cloud_test && LD_LIBRARY_PATH=/usr/local/lib ./cloud_manifest_test
32+
- script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.SingleDeleteFlush:DBTest.GetLevel0Ordering:DBTest.GetPicksCorrectFile
33+
- script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.HiddenValuesAreRemoved
34+
- script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=DBTest.UnremovableSingleDelete
35+
- script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test --gtest_filter=MultiThreaded/MultiThreadedDBTest*
36+
- script: OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_test2 db_basic_test env_basic_test && LD_LIBRARY_PATH=/usr/local/lib ./db_test2 && LD_LIBRARY_PATH=/usr/local/lib ./db_basic_test --gtest_filter=-DBBasicTest.CompactBetweenSnapshots && LD_LIBRARY_PATH=/usr/local/lib ./env_basic_test
37+
- script: build_tools/spinup_kafka.sh && sleep 10 && OPT=-DTRAVIS V=1 USE_AWS=1 USE_KAFKA=1 make -j4 db_cloud_test cloud_manifest_test && LD_LIBRARY_PATH=/usr/local/lib ./db_cloud_test && LD_LIBRARY_PATH=/usr/local/lib ./cloud_manifest_test
4438

4539
before_script:
4640
# Increase the maximum number of open file descriptors, since some tests use

cloud/aws/aws_env.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ Status AwsEnv::EmptyBucket(const std::string& bucket,
10591059

10601060
// Delete all objects from bucket
10611061
for (auto path : results) {
1062+
path = s3_object_prefix + "/" + path;
10621063
st = DeletePathInS3(bucket, path);
10631064
if (!st.ok()) {
10641065
Log(InfoLogLevel::ERROR_LEVEL, info_log_,

cloud/db_cloud_test.cc

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "rocksdb/status.h"
2222
#include "rocksdb/table.h"
2323
#include "test_util/testharness.h"
24+
#include "util/random.h"
2425
#include "util/string_util.h"
2526
#ifndef OS_WIN
2627
#include <unistd.h>
@@ -32,9 +33,13 @@ namespace rocksdb {
3233
class CloudTest : public testing::Test {
3334
public:
3435
CloudTest() {
36+
Random64 rng(time(nullptr));
37+
test_id_ = std::to_string(rng.Next());
38+
fprintf(stderr, "Test ID: %s\n", test_id_.c_str());
39+
3540
base_env_ = Env::Default();
36-
dbname_ = test::TmpDir() + "/db_cloud";
37-
clone_dir_ = test::TmpDir() + "/ctest";
41+
dbname_ = test::TmpDir() + "/db_cloud-" + test_id_;
42+
clone_dir_ = test::TmpDir() + "/ctest-" + test_id_;
3843
cloud_env_options_.TEST_Initialize("dbcloudtest.", dbname_);
3944

4045
options_.create_if_missing = true;
@@ -59,15 +64,14 @@ class CloudTest : public testing::Test {
5964

6065
CloudEnv* aenv;
6166
// create a dummy aws env
62-
ASSERT_OK(CloudEnv::NewAwsEnv(base_env_, cloud_env_options_,
63-
options_.info_log, &aenv));
67+
CloudEnv::NewAwsEnv(base_env_, cloud_env_options_,
68+
options_.info_log, &aenv);
6469
aenv_.reset(aenv);
6570
// delete all pre-existing contents from the bucket
66-
Status st = aenv_->EmptyBucket(aenv_->GetSrcBucketName(), "");
71+
Status st = aenv_->EmptyBucket(aenv_->GetSrcBucketName(), dbname_);
6772
ASSERT_TRUE(st.ok() || st.IsNotFound());
6873
aenv_.reset();
6974

70-
// delete and create directory where clones reside
7175
DestroyDir(clone_dir_);
7276
ASSERT_OK(base_env_->CreateDir(clone_dir_));
7377
}
@@ -97,12 +101,14 @@ class CloudTest : public testing::Test {
97101

98102
virtual ~CloudTest() {
99103
// Cleanup the cloud bucket
100-
CloudEnv* aenv;
101-
Status st = CloudEnv::NewAwsEnv(base_env_, cloud_env_options_,
102-
options_.info_log, &aenv);
103-
if (st.ok()) {
104-
aenv->EmptyBucket(aenv->GetSrcBucketName(), "");
105-
delete aenv;
104+
if (!cloud_env_options_.src_bucket.GetBucketName().empty()) {
105+
CloudEnv* aenv;
106+
Status st = CloudEnv::NewAwsEnv(base_env_, cloud_env_options_,
107+
options_.info_log, &aenv);
108+
if (st.ok()) {
109+
aenv->EmptyBucket(aenv->GetSrcBucketName(), dbname_);
110+
delete aenv;
111+
}
106112
}
107113

108114
CloseDB();
@@ -126,6 +132,9 @@ class CloudTest : public testing::Test {
126132
CreateAwsEnv();
127133
options_.env = aenv_.get();
128134

135+
// Sleep for a second because S3 is eventual consistency.
136+
std::this_thread::sleep_for(std::chrono::seconds(1));
137+
129138
// default column family
130139
ColumnFamilyOptions cfopt = options_;
131140
std::vector<ColumnFamilyDescriptor> column_families;
@@ -259,6 +268,7 @@ class CloudTest : public testing::Test {
259268
}
260269

261270
protected:
271+
std::string test_id_;
262272
Env* base_env_;
263273
Options options_;
264274
std::string dbname_;
@@ -423,13 +433,14 @@ TEST_F(CloudTest, TrueClone) {
423433
ASSERT_OK(db_->Flush(FlushOptions()));
424434
CloseDB();
425435
value.clear();
436+
auto clone_path1 = "clone1_path-" + test_id_;
426437
{
427438
// Create a new instance with different src and destination paths.
428439
// This is true clone and should have all the contents of the masterdb
429440
std::unique_ptr<CloudEnv> cloud_env;
430441
std::unique_ptr<DBCloud> cloud_db;
431442
CloneDB("localpath1", cloud_env_options_.src_bucket.GetBucketName(),
432-
"clone1_path", &cloud_db, &cloud_env);
443+
clone_path1, &cloud_db, &cloud_env);
433444

434445
// Retrieve the id of the clone db
435446
ASSERT_OK(cloud_db->GetDbIdentity(newdb1_dbid));
@@ -455,7 +466,7 @@ TEST_F(CloudTest, TrueClone) {
455466
std::unique_ptr<CloudEnv> cloud_env;
456467
std::unique_ptr<DBCloud> cloud_db;
457468
CloneDB("localpath2", cloud_env_options_.src_bucket.GetBucketName(),
458-
"clone1_path", &cloud_db, &cloud_env);
469+
clone_path1, &cloud_db, &cloud_env);
459470

460471
// Retrieve the id of the clone db
461472
ASSERT_OK(cloud_db->GetDbIdentity(newdb2_dbid));
@@ -470,7 +481,7 @@ TEST_F(CloudTest, TrueClone) {
470481
std::unique_ptr<CloudEnv> cloud_env;
471482
std::unique_ptr<DBCloud> cloud_db;
472483
CloneDB("localpath2", cloud_env_options_.src_bucket.GetBucketName(),
473-
"clone1_path", &cloud_db, &cloud_env);
484+
clone_path1, &cloud_db, &cloud_env);
474485

475486
// Retrieve the id of the clone db
476487
ASSERT_OK(cloud_db->GetDbIdentity(newdb2_dbid));
@@ -480,13 +491,14 @@ TEST_F(CloudTest, TrueClone) {
480491
ASSERT_TRUE(value.compare("Clone1") == 0);
481492
ASSERT_OK(cloud_db->Flush(FlushOptions()));
482493
}
494+
auto clone_path2 = "clone2_path-" + test_id_;
483495
{
484496
// Create clone2
485497
std::unique_ptr<CloudEnv> cloud_env;
486498
std::unique_ptr<DBCloud> cloud_db;
487499
CloneDB("localpath3", // xxx try with localpath2
488500
cloud_env_options_.src_bucket.GetBucketName(),
489-
"clone2_path", &cloud_db, &cloud_env);
501+
clone_path2, &cloud_db, &cloud_env);
490502

491503
// Retrieve the id of the clone db
492504
ASSERT_OK(cloud_db->GetDbIdentity(newdb3_dbid));
@@ -509,6 +521,9 @@ TEST_F(CloudTest, TrueClone) {
509521
// TODO(igor): Re-enable once purger code is fixed
510522
// ASSERT_EQ(to_be_deleted.size(), 0);
511523
}
524+
525+
aenv_->EmptyBucket(aenv_->GetSrcBucketName(), clone_path1);
526+
aenv_->EmptyBucket(aenv_->GetSrcBucketName(), clone_path2);
512527
}
513528

514529
//
@@ -525,7 +540,7 @@ TEST_F(CloudTest, DbidRegistry) {
525540
// Assert that there is one db in the registry
526541
DbidList dbs;
527542
ASSERT_OK(aenv_->GetDbidList(aenv_->GetSrcBucketName(), &dbs));
528-
ASSERT_EQ(dbs.size(), 1);
543+
ASSERT_GE(dbs.size(), 1);
529544

530545
CloseDB();
531546
}
@@ -705,7 +720,8 @@ TEST_F(CloudTest, Savepoint) {
705720
// Reopen the clone
706721
std::unique_ptr<CloudEnv> cloud_env;
707722
std::unique_ptr<DBCloud> cloud_db;
708-
CloneDB("localpath2", cloud_env_options_.src_bucket.GetBucketName(), dest_path, &cloud_db, &cloud_env);
723+
CloneDB("localpath2", cloud_env_options_.src_bucket.GetBucketName(),
724+
dest_path, &cloud_db, &cloud_env);
709725

710726
// check that the both kvs appears in the clone
711727
value.clear();
@@ -1346,6 +1362,13 @@ TEST_F(CloudTest, CheckpointToCloud) {
13461362
cloud_env_options_.keep_local_sst_files = true;
13471363
options_.level0_file_num_compaction_trigger = 100; // never compact
13481364

1365+
// Pre-create the bucket.
1366+
CreateAwsEnv();
1367+
aenv_.reset();
1368+
1369+
// S3 is eventual consistency.
1370+
std::this_thread::sleep_for(std::chrono::seconds(1));
1371+
13491372
auto checkpoint_bucket = cloud_env_options_.dest_bucket;
13501373

13511374
cloud_env_options_.src_bucket = BucketOptions();
@@ -1375,6 +1398,9 @@ TEST_F(CloudTest, CheckpointToCloud) {
13751398
ASSERT_OK(db_->Get(ReadOptions(), "c", &value));
13761399
ASSERT_EQ(value, "d");
13771400
CloseDB();
1401+
1402+
aenv_->EmptyBucket(checkpoint_bucket.GetBucketName(),
1403+
checkpoint_bucket.GetObjectPath());
13781404
}
13791405

13801406
TEST_F(CloudTest, ConstantSstFileManager) {

db/db_test_util.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ DBTestBase::DBTestBase(const std::string path)
8181
: (mem_env_ ? mem_env_ : base_env));
8282
#ifdef USE_AWS
8383
// Randomize the test path so that multiple tests can run in parallel
84+
srand(time(nullptr));
8485
std::string mypath = path + "_" + std::to_string(rand());
8586
option_env_ = kDefaultEnv;
8687
env_->NewLogger(test::TmpDir(env_) + "/rocksdb-cloud.log", &info_log_);
@@ -122,6 +123,11 @@ DBTestBase::~DBTestBase() {
122123
EXPECT_OK(DestroyDB(dbname_, options));
123124
}
124125
delete env_;
126+
127+
#ifdef USE_AWS
128+
auto aenv = dynamic_cast<CloudEnv*>(s3_env_);
129+
aenv->EmptyBucket(aenv->GetSrcBucketName(), aenv->GetSrcObjectPath());
130+
#endif
125131
delete s3_env_;
126132
}
127133

@@ -635,6 +641,10 @@ Options DBTestBase::GetOptions(
635641

636642
#ifdef USE_AWS
637643
Env* DBTestBase::CreateNewAwsEnv(const std::string& prefix) {
644+
if (!prefix.empty()) {
645+
fprintf(stderr, "Creating new AWS env with prefix %s\n", prefix.c_str());
646+
}
647+
638648
// get AWS credentials
639649
rocksdb::CloudEnvOptions coptions;
640650
CloudEnv* cenv = nullptr;

0 commit comments

Comments
 (0)