import_column_family_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. #ifndef ROCKSDB_LITE
  2. #include <functional>
  3. #include "db/db_test_util.h"
  4. #include "port/port.h"
  5. #include "port/stack_trace.h"
  6. #include "rocksdb/sst_file_writer.h"
  7. #include "test_util/testutil.h"
  8. namespace ROCKSDB_NAMESPACE {
  9. class ImportColumnFamilyTest : public DBTestBase {
  10. public:
  11. ImportColumnFamilyTest() : DBTestBase("/import_column_family_test") {
  12. sst_files_dir_ = dbname_ + "/sst_files/";
  13. DestroyAndRecreateExternalSSTFilesDir();
  14. export_files_dir_ = test::TmpDir(env_) + "/export";
  15. import_cfh_ = nullptr;
  16. import_cfh2_ = nullptr;
  17. metadata_ptr_ = nullptr;
  18. }
  19. ~ImportColumnFamilyTest() {
  20. if (import_cfh_) {
  21. db_->DropColumnFamily(import_cfh_);
  22. db_->DestroyColumnFamilyHandle(import_cfh_);
  23. import_cfh_ = nullptr;
  24. }
  25. if (import_cfh2_) {
  26. db_->DropColumnFamily(import_cfh2_);
  27. db_->DestroyColumnFamilyHandle(import_cfh2_);
  28. import_cfh2_ = nullptr;
  29. }
  30. if (metadata_ptr_) {
  31. delete metadata_ptr_;
  32. metadata_ptr_ = nullptr;
  33. }
  34. test::DestroyDir(env_, sst_files_dir_);
  35. test::DestroyDir(env_, export_files_dir_);
  36. }
  37. void DestroyAndRecreateExternalSSTFilesDir() {
  38. test::DestroyDir(env_, sst_files_dir_);
  39. env_->CreateDir(sst_files_dir_);
  40. test::DestroyDir(env_, export_files_dir_);
  41. }
  42. LiveFileMetaData LiveFileMetaDataInit(std::string name, std::string path,
  43. int level,
  44. SequenceNumber smallest_seqno,
  45. SequenceNumber largest_seqno) {
  46. LiveFileMetaData metadata;
  47. metadata.name = name;
  48. metadata.db_path = path;
  49. metadata.smallest_seqno = smallest_seqno;
  50. metadata.largest_seqno = largest_seqno;
  51. metadata.level = level;
  52. return metadata;
  53. }
  54. protected:
  55. std::string sst_files_dir_;
  56. std::string export_files_dir_;
  57. ColumnFamilyHandle* import_cfh_;
  58. ColumnFamilyHandle* import_cfh2_;
  59. ExportImportFilesMetaData* metadata_ptr_;
  60. };
  61. TEST_F(ImportColumnFamilyTest, ImportSSTFileWriterFiles) {
  62. Options options = CurrentOptions();
  63. CreateAndReopenWithCF({"koko"}, options);
  64. SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
  65. SstFileWriter sfw_unknown(EnvOptions(), options);
  66. // cf1.sst
  67. const std::string cf1_sst_name = "cf1.sst";
  68. const std::string cf1_sst = sst_files_dir_ + cf1_sst_name;
  69. ASSERT_OK(sfw_cf1.Open(cf1_sst));
  70. ASSERT_OK(sfw_cf1.Put("K1", "V1"));
  71. ASSERT_OK(sfw_cf1.Put("K2", "V2"));
  72. ASSERT_OK(sfw_cf1.Finish());
  73. // cf_unknown.sst
  74. const std::string unknown_sst_name = "cf_unknown.sst";
  75. const std::string unknown_sst = sst_files_dir_ + unknown_sst_name;
  76. ASSERT_OK(sfw_unknown.Open(unknown_sst));
  77. ASSERT_OK(sfw_unknown.Put("K3", "V1"));
  78. ASSERT_OK(sfw_unknown.Put("K4", "V2"));
  79. ASSERT_OK(sfw_unknown.Finish());
  80. {
  81. // Import sst file corresponding to cf1 onto a new cf and verify
  82. ExportImportFilesMetaData metadata;
  83. metadata.files.push_back(
  84. LiveFileMetaDataInit(cf1_sst_name, sst_files_dir_, 0, 10, 19));
  85. metadata.db_comparator_name = options.comparator->Name();
  86. ASSERT_OK(db_->CreateColumnFamilyWithImport(
  87. options, "toto", ImportColumnFamilyOptions(), metadata, &import_cfh_));
  88. ASSERT_NE(import_cfh_, nullptr);
  89. std::string value;
  90. db_->Get(ReadOptions(), import_cfh_, "K1", &value);
  91. ASSERT_EQ(value, "V1");
  92. db_->Get(ReadOptions(), import_cfh_, "K2", &value);
  93. ASSERT_EQ(value, "V2");
  94. ASSERT_OK(db_->DropColumnFamily(import_cfh_));
  95. ASSERT_OK(db_->DestroyColumnFamilyHandle(import_cfh_));
  96. import_cfh_ = nullptr;
  97. }
  98. {
  99. // Import sst file corresponding to unknown cf onto a new cf and verify
  100. ExportImportFilesMetaData metadata;
  101. metadata.files.push_back(
  102. LiveFileMetaDataInit(unknown_sst_name, sst_files_dir_, 0, 20, 29));
  103. metadata.db_comparator_name = options.comparator->Name();
  104. ASSERT_OK(db_->CreateColumnFamilyWithImport(
  105. options, "yoyo", ImportColumnFamilyOptions(), metadata, &import_cfh_));
  106. ASSERT_NE(import_cfh_, nullptr);
  107. std::string value;
  108. db_->Get(ReadOptions(), import_cfh_, "K3", &value);
  109. ASSERT_EQ(value, "V1");
  110. db_->Get(ReadOptions(), import_cfh_, "K4", &value);
  111. ASSERT_EQ(value, "V2");
  112. }
  113. }
  114. TEST_F(ImportColumnFamilyTest, ImportSSTFileWriterFilesWithOverlap) {
  115. Options options = CurrentOptions();
  116. CreateAndReopenWithCF({"koko"}, options);
  117. SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
  118. // file3.sst
  119. const std::string file3_sst_name = "file3.sst";
  120. const std::string file3_sst = sst_files_dir_ + file3_sst_name;
  121. ASSERT_OK(sfw_cf1.Open(file3_sst));
  122. for (int i = 0; i < 100; ++i) {
  123. sfw_cf1.Put(Key(i), Key(i) + "_val");
  124. }
  125. ASSERT_OK(sfw_cf1.Finish());
  126. // file2.sst
  127. const std::string file2_sst_name = "file2.sst";
  128. const std::string file2_sst = sst_files_dir_ + file2_sst_name;
  129. ASSERT_OK(sfw_cf1.Open(file2_sst));
  130. for (int i = 0; i < 100; i += 2) {
  131. sfw_cf1.Put(Key(i), Key(i) + "_overwrite1");
  132. }
  133. ASSERT_OK(sfw_cf1.Finish());
  134. // file1a.sst
  135. const std::string file1a_sst_name = "file1a.sst";
  136. const std::string file1a_sst = sst_files_dir_ + file1a_sst_name;
  137. ASSERT_OK(sfw_cf1.Open(file1a_sst));
  138. for (int i = 0; i < 52; i += 4) {
  139. sfw_cf1.Put(Key(i), Key(i) + "_overwrite2");
  140. }
  141. ASSERT_OK(sfw_cf1.Finish());
  142. // file1b.sst
  143. const std::string file1b_sst_name = "file1b.sst";
  144. const std::string file1b_sst = sst_files_dir_ + file1b_sst_name;
  145. ASSERT_OK(sfw_cf1.Open(file1b_sst));
  146. for (int i = 52; i < 100; i += 4) {
  147. sfw_cf1.Put(Key(i), Key(i) + "_overwrite2");
  148. }
  149. ASSERT_OK(sfw_cf1.Finish());
  150. // file0a.sst
  151. const std::string file0a_sst_name = "file0a.sst";
  152. const std::string file0a_sst = sst_files_dir_ + file0a_sst_name;
  153. ASSERT_OK(sfw_cf1.Open(file0a_sst));
  154. for (int i = 0; i < 100; i += 16) {
  155. sfw_cf1.Put(Key(i), Key(i) + "_overwrite3");
  156. }
  157. ASSERT_OK(sfw_cf1.Finish());
  158. // file0b.sst
  159. const std::string file0b_sst_name = "file0b.sst";
  160. const std::string file0b_sst = sst_files_dir_ + file0b_sst_name;
  161. ASSERT_OK(sfw_cf1.Open(file0b_sst));
  162. for (int i = 0; i < 100; i += 16) {
  163. sfw_cf1.Put(Key(i), Key(i) + "_overwrite4");
  164. }
  165. ASSERT_OK(sfw_cf1.Finish());
  166. // Import sst files and verify
  167. ExportImportFilesMetaData metadata;
  168. metadata.files.push_back(
  169. LiveFileMetaDataInit(file3_sst_name, sst_files_dir_, 3, 10, 19));
  170. metadata.files.push_back(
  171. LiveFileMetaDataInit(file2_sst_name, sst_files_dir_, 2, 20, 29));
  172. metadata.files.push_back(
  173. LiveFileMetaDataInit(file1a_sst_name, sst_files_dir_, 1, 30, 34));
  174. metadata.files.push_back(
  175. LiveFileMetaDataInit(file1b_sst_name, sst_files_dir_, 1, 35, 39));
  176. metadata.files.push_back(
  177. LiveFileMetaDataInit(file0a_sst_name, sst_files_dir_, 0, 40, 49));
  178. metadata.files.push_back(
  179. LiveFileMetaDataInit(file0b_sst_name, sst_files_dir_, 0, 50, 59));
  180. metadata.db_comparator_name = options.comparator->Name();
  181. ASSERT_OK(db_->CreateColumnFamilyWithImport(
  182. options, "toto", ImportColumnFamilyOptions(), metadata, &import_cfh_));
  183. ASSERT_NE(import_cfh_, nullptr);
  184. for (int i = 0; i < 100; i++) {
  185. std::string value;
  186. db_->Get(ReadOptions(), import_cfh_, Key(i), &value);
  187. if (i % 16 == 0) {
  188. ASSERT_EQ(value, Key(i) + "_overwrite4");
  189. } else if (i % 4 == 0) {
  190. ASSERT_EQ(value, Key(i) + "_overwrite2");
  191. } else if (i % 2 == 0) {
  192. ASSERT_EQ(value, Key(i) + "_overwrite1");
  193. } else {
  194. ASSERT_EQ(value, Key(i) + "_val");
  195. }
  196. }
  197. for (int i = 0; i < 100; i += 5) {
  198. ASSERT_OK(
  199. db_->Put(WriteOptions(), import_cfh_, Key(i), Key(i) + "_overwrite5"));
  200. }
  201. // Flush and check again
  202. ASSERT_OK(db_->Flush(FlushOptions(), import_cfh_));
  203. for (int i = 0; i < 100; i++) {
  204. std::string value;
  205. db_->Get(ReadOptions(), import_cfh_, Key(i), &value);
  206. if (i % 5 == 0) {
  207. ASSERT_EQ(value, Key(i) + "_overwrite5");
  208. } else if (i % 16 == 0) {
  209. ASSERT_EQ(value, Key(i) + "_overwrite4");
  210. } else if (i % 4 == 0) {
  211. ASSERT_EQ(value, Key(i) + "_overwrite2");
  212. } else if (i % 2 == 0) {
  213. ASSERT_EQ(value, Key(i) + "_overwrite1");
  214. } else {
  215. ASSERT_EQ(value, Key(i) + "_val");
  216. }
  217. }
  218. // Compact and check again.
  219. ASSERT_OK(
  220. db_->CompactRange(CompactRangeOptions(), import_cfh_, nullptr, nullptr));
  221. for (int i = 0; i < 100; i++) {
  222. std::string value;
  223. db_->Get(ReadOptions(), import_cfh_, Key(i), &value);
  224. if (i % 5 == 0) {
  225. ASSERT_EQ(value, Key(i) + "_overwrite5");
  226. } else if (i % 16 == 0) {
  227. ASSERT_EQ(value, Key(i) + "_overwrite4");
  228. } else if (i % 4 == 0) {
  229. ASSERT_EQ(value, Key(i) + "_overwrite2");
  230. } else if (i % 2 == 0) {
  231. ASSERT_EQ(value, Key(i) + "_overwrite1");
  232. } else {
  233. ASSERT_EQ(value, Key(i) + "_val");
  234. }
  235. }
  236. }
  237. TEST_F(ImportColumnFamilyTest, ImportExportedSSTFromAnotherCF) {
  238. Options options = CurrentOptions();
  239. CreateAndReopenWithCF({"koko"}, options);
  240. for (int i = 0; i < 100; ++i) {
  241. Put(1, Key(i), Key(i) + "_val");
  242. }
  243. ASSERT_OK(Flush(1));
  244. ASSERT_OK(
  245. db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
  246. // Overwrite the value in the same set of keys.
  247. for (int i = 0; i < 100; ++i) {
  248. Put(1, Key(i), Key(i) + "_overwrite");
  249. }
  250. // Flush to create L0 file.
  251. ASSERT_OK(Flush(1));
  252. for (int i = 0; i < 100; ++i) {
  253. Put(1, Key(i), Key(i) + "_overwrite2");
  254. }
  255. // Flush again to create another L0 file. It should have higher sequencer.
  256. ASSERT_OK(Flush(1));
  257. Checkpoint* checkpoint;
  258. ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
  259. ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
  260. &metadata_ptr_));
  261. ASSERT_NE(metadata_ptr_, nullptr);
  262. delete checkpoint;
  263. ImportColumnFamilyOptions import_options;
  264. import_options.move_files = false;
  265. ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "toto", import_options,
  266. *metadata_ptr_, &import_cfh_));
  267. ASSERT_NE(import_cfh_, nullptr);
  268. import_options.move_files = true;
  269. ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "yoyo", import_options,
  270. *metadata_ptr_, &import_cfh2_));
  271. ASSERT_NE(import_cfh2_, nullptr);
  272. delete metadata_ptr_;
  273. metadata_ptr_ = NULL;
  274. std::string value1, value2;
  275. for (int i = 0; i < 100; ++i) {
  276. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1);
  277. ASSERT_EQ(Get(1, Key(i)), value1);
  278. }
  279. for (int i = 0; i < 100; ++i) {
  280. db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2);
  281. ASSERT_EQ(Get(1, Key(i)), value2);
  282. }
  283. // Modify keys in cf1 and verify.
  284. for (int i = 0; i < 25; i++) {
  285. ASSERT_OK(db_->Delete(WriteOptions(), import_cfh_, Key(i)));
  286. }
  287. for (int i = 25; i < 50; i++) {
  288. ASSERT_OK(
  289. db_->Put(WriteOptions(), import_cfh_, Key(i), Key(i) + "_overwrite3"));
  290. }
  291. for (int i = 0; i < 25; ++i) {
  292. ASSERT_TRUE(
  293. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1).IsNotFound());
  294. }
  295. for (int i = 25; i < 50; ++i) {
  296. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1);
  297. ASSERT_EQ(Key(i) + "_overwrite3", value1);
  298. }
  299. for (int i = 50; i < 100; ++i) {
  300. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1);
  301. ASSERT_EQ(Key(i) + "_overwrite2", value1);
  302. }
  303. for (int i = 0; i < 100; ++i) {
  304. db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2);
  305. ASSERT_EQ(Get(1, Key(i)), value2);
  306. }
  307. // Compact and check again.
  308. ASSERT_OK(db_->Flush(FlushOptions(), import_cfh_));
  309. ASSERT_OK(
  310. db_->CompactRange(CompactRangeOptions(), import_cfh_, nullptr, nullptr));
  311. for (int i = 0; i < 25; ++i) {
  312. ASSERT_TRUE(
  313. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1).IsNotFound());
  314. }
  315. for (int i = 25; i < 50; ++i) {
  316. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1);
  317. ASSERT_EQ(Key(i) + "_overwrite3", value1);
  318. }
  319. for (int i = 50; i < 100; ++i) {
  320. db_->Get(ReadOptions(), import_cfh_, Key(i), &value1);
  321. ASSERT_EQ(Key(i) + "_overwrite2", value1);
  322. }
  323. for (int i = 0; i < 100; ++i) {
  324. db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2);
  325. ASSERT_EQ(Get(1, Key(i)), value2);
  326. }
  327. }
  328. TEST_F(ImportColumnFamilyTest, ImportExportedSSTFromAnotherDB) {
  329. Options options = CurrentOptions();
  330. CreateAndReopenWithCF({"koko"}, options);
  331. for (int i = 0; i < 100; ++i) {
  332. Put(1, Key(i), Key(i) + "_val");
  333. }
  334. ASSERT_OK(Flush(1));
  335. // Compact to create a L1 file.
  336. ASSERT_OK(
  337. db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
  338. // Overwrite the value in the same set of keys.
  339. for (int i = 0; i < 50; ++i) {
  340. Put(1, Key(i), Key(i) + "_overwrite");
  341. }
  342. // Flush to create L0 file.
  343. ASSERT_OK(Flush(1));
  344. for (int i = 0; i < 25; ++i) {
  345. Put(1, Key(i), Key(i) + "_overwrite2");
  346. }
  347. // Flush again to create another L0 file. It should have higher sequencer.
  348. ASSERT_OK(Flush(1));
  349. Checkpoint* checkpoint;
  350. ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
  351. ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
  352. &metadata_ptr_));
  353. ASSERT_NE(metadata_ptr_, nullptr);
  354. delete checkpoint;
  355. // Create a new db and import the files.
  356. DB* db_copy;
  357. test::DestroyDir(env_, dbname_ + "/db_copy");
  358. ASSERT_OK(DB::Open(options, dbname_ + "/db_copy", &db_copy));
  359. ColumnFamilyHandle* cfh = nullptr;
  360. ASSERT_OK(db_copy->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
  361. ImportColumnFamilyOptions(),
  362. *metadata_ptr_, &cfh));
  363. ASSERT_NE(cfh, nullptr);
  364. for (int i = 0; i < 100; ++i) {
  365. std::string value;
  366. db_copy->Get(ReadOptions(), cfh, Key(i), &value);
  367. ASSERT_EQ(Get(1, Key(i)), value);
  368. }
  369. db_copy->DropColumnFamily(cfh);
  370. db_copy->DestroyColumnFamilyHandle(cfh);
  371. delete db_copy;
  372. test::DestroyDir(env_, dbname_ + "/db_copy");
  373. }
  374. TEST_F(ImportColumnFamilyTest, ImportColumnFamilyNegativeTest) {
  375. Options options = CurrentOptions();
  376. CreateAndReopenWithCF({"koko"}, options);
  377. {
  378. // Create column family with existing cf name.
  379. ExportImportFilesMetaData metadata;
  380. ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "koko",
  381. ImportColumnFamilyOptions(),
  382. metadata, &import_cfh_),
  383. Status::InvalidArgument("Column family already exists"));
  384. ASSERT_EQ(import_cfh_, nullptr);
  385. }
  386. {
  387. // Import with no files specified.
  388. ExportImportFilesMetaData metadata;
  389. ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
  390. ImportColumnFamilyOptions(),
  391. metadata, &import_cfh_),
  392. Status::InvalidArgument("The list of files is empty"));
  393. ASSERT_EQ(import_cfh_, nullptr);
  394. }
  395. {
  396. // Import with overlapping keys in sst files.
  397. ExportImportFilesMetaData metadata;
  398. SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
  399. const std::string file1_sst_name = "file1.sst";
  400. const std::string file1_sst = sst_files_dir_ + file1_sst_name;
  401. ASSERT_OK(sfw_cf1.Open(file1_sst));
  402. ASSERT_OK(sfw_cf1.Put("K1", "V1"));
  403. ASSERT_OK(sfw_cf1.Put("K2", "V2"));
  404. ASSERT_OK(sfw_cf1.Finish());
  405. const std::string file2_sst_name = "file2.sst";
  406. const std::string file2_sst = sst_files_dir_ + file2_sst_name;
  407. ASSERT_OK(sfw_cf1.Open(file2_sst));
  408. ASSERT_OK(sfw_cf1.Put("K2", "V2"));
  409. ASSERT_OK(sfw_cf1.Put("K3", "V3"));
  410. ASSERT_OK(sfw_cf1.Finish());
  411. metadata.files.push_back(
  412. LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
  413. metadata.files.push_back(
  414. LiveFileMetaDataInit(file2_sst_name, sst_files_dir_, 1, 10, 19));
  415. metadata.db_comparator_name = options.comparator->Name();
  416. ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
  417. ImportColumnFamilyOptions(),
  418. metadata, &import_cfh_),
  419. Status::InvalidArgument("Files have overlapping ranges"));
  420. ASSERT_EQ(import_cfh_, nullptr);
  421. }
  422. {
  423. // Import with a mismatching comparator, should fail with appropriate error.
  424. ExportImportFilesMetaData metadata;
  425. Options mismatch_options = CurrentOptions();
  426. mismatch_options.comparator = ReverseBytewiseComparator();
  427. SstFileWriter sfw_cf1(EnvOptions(), mismatch_options, handles_[1]);
  428. const std::string file1_sst_name = "file1.sst";
  429. const std::string file1_sst = sst_files_dir_ + file1_sst_name;
  430. ASSERT_OK(sfw_cf1.Open(file1_sst));
  431. ASSERT_OK(sfw_cf1.Put("K2", "V2"));
  432. ASSERT_OK(sfw_cf1.Put("K1", "V1"));
  433. ASSERT_OK(sfw_cf1.Finish());
  434. metadata.files.push_back(
  435. LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
  436. metadata.db_comparator_name = mismatch_options.comparator->Name();
  437. ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "coco",
  438. ImportColumnFamilyOptions(),
  439. metadata, &import_cfh_),
  440. Status::InvalidArgument("Comparator name mismatch"));
  441. ASSERT_EQ(import_cfh_, nullptr);
  442. }
  443. {
  444. // Import with non existent sst file should fail with appropriate error
  445. ExportImportFilesMetaData metadata;
  446. SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
  447. const std::string file1_sst_name = "file1.sst";
  448. const std::string file1_sst = sst_files_dir_ + file1_sst_name;
  449. ASSERT_OK(sfw_cf1.Open(file1_sst));
  450. ASSERT_OK(sfw_cf1.Put("K1", "V1"));
  451. ASSERT_OK(sfw_cf1.Put("K2", "V2"));
  452. ASSERT_OK(sfw_cf1.Finish());
  453. const std::string file3_sst_name = "file3.sst";
  454. metadata.files.push_back(
  455. LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
  456. metadata.files.push_back(
  457. LiveFileMetaDataInit(file3_sst_name, sst_files_dir_, 1, 10, 19));
  458. metadata.db_comparator_name = options.comparator->Name();
  459. ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
  460. ImportColumnFamilyOptions(),
  461. metadata, &import_cfh_),
  462. Status::IOError("No such file or directory"));
  463. ASSERT_EQ(import_cfh_, nullptr);
  464. // Test successful import after a failure with the same CF name. Ensures
  465. // there is no side effect with CF when there is a failed import
  466. metadata.files.pop_back();
  467. metadata.db_comparator_name = options.comparator->Name();
  468. ASSERT_OK(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
  469. ImportColumnFamilyOptions(),
  470. metadata, &import_cfh_));
  471. ASSERT_NE(import_cfh_, nullptr);
  472. }
  473. }
  474. } // namespace ROCKSDB_NAMESPACE
  475. int main(int argc, char** argv) {
  476. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  477. ::testing::InitGoogleTest(&argc, argv);
  478. return RUN_ALL_TESTS();
  479. }
  480. #else
  481. #include <stdio.h>
  482. int main(int /*argc*/, char** /*argv*/) {
  483. fprintf(stderr,
  484. "SKIPPED as External SST File Writer and Import are not supported "
  485. "in ROCKSDB_LITE\n");
  486. return 0;
  487. }
  488. #endif // !ROCKSDB_LITE