@@ -1479,3 +1479,94 @@ TEST_F(cls_rgw, reshardlog_num)
14791479 index_complete (ioctx, bucket_oid, CLS_RGW_OP_DEL, tag, 2 , obj1, meta);
14801480 reshardlog_entries (ioctx, bucket_oid, 2u );
14811481}
1482+
1483+ TEST_F (cls_rgw, bi_put_entries)
1484+ {
1485+ const string src_bucket = str_int (" bi_put_entries" , 0 );
1486+ const string dst_bucket = str_int (" bi_put_entries" , 1 );
1487+
1488+ const cls_rgw_obj_key obj1 = str_int (" obj" , 1 );
1489+ const cls_rgw_obj_key obj2 = str_int (" obj" , 2 );
1490+ const cls_rgw_obj_key obj3 = str_int (" obj" , 3 );
1491+ const cls_rgw_obj_key obj4 = str_int (" obj" , 4 );
1492+ const string tag = str_int (" tag" , 0 );
1493+ const string loc = str_int (" loc" , 0 );
1494+ auto meta = rgw_bucket_dir_entry_meta{
1495+ .category = RGWObjCategory::Main, .size = 8192 };
1496+
1497+ // prepare src_bucket and add two objects
1498+ {
1499+ ObjectWriteOperation op;
1500+ cls_rgw_bucket_init_index2 (op);
1501+ ASSERT_EQ (0 , ioctx.operate (src_bucket, &op));
1502+
1503+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, obj1, loc);
1504+ index_complete (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, 1 , obj1, meta);
1505+
1506+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, obj2, loc);
1507+ index_complete (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, 2 , obj2, meta);
1508+
1509+ test_stats (ioctx, src_bucket, RGWObjCategory::Main, 2 , 16384 );
1510+ }
1511+
1512+ // prepare dst_bucket and copy the bi entries
1513+ {
1514+ ObjectWriteOperation op;
1515+ cls_rgw_bucket_init_index2 (op);
1516+ ASSERT_EQ (0 , ioctx.operate (dst_bucket, &op));
1517+ }
1518+ {
1519+ list<rgw_cls_bi_entry> src_entries;
1520+ bool truncated{false };
1521+ ASSERT_EQ (0 , cls_rgw_bi_list (ioctx, src_bucket, " " , " " , 128 ,
1522+ &src_entries, &truncated));
1523+ ASSERT_EQ (2u , src_entries.size ());
1524+
1525+ ObjectWriteOperation op;
1526+ cls_rgw_bi_put_entries (op, {src_entries.begin (), src_entries.end ()}, true );
1527+ ASSERT_EQ (0 , ioctx.operate (dst_bucket, &op));
1528+
1529+ test_stats (ioctx, dst_bucket, RGWObjCategory::Main, 2 , 16384 );
1530+ }
1531+
1532+ {
1533+ // start reshard on src_bucket
1534+ set_reshard_status (ioctx, src_bucket, cls_rgw_reshard_status::IN_LOGRECORD);
1535+
1536+ // delete obj1 and log a ReshardDeleted entry
1537+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_DEL, tag, obj1, loc);
1538+ index_complete (ioctx, src_bucket, CLS_RGW_OP_DEL, tag, 3 , obj1, meta);
1539+
1540+ // overwrite obj2 and record its reshardlog entry
1541+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, obj2, loc);
1542+ index_complete (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, 4 , obj2, meta);
1543+
1544+ // add two more objects
1545+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, obj3, loc);
1546+ index_complete (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, 5 , obj3, meta);
1547+
1548+ index_prepare (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, obj4, loc);
1549+ index_complete (ioctx, src_bucket, CLS_RGW_OP_ADD, tag, 6 , obj4, meta);
1550+
1551+ test_stats (ioctx, src_bucket, RGWObjCategory::Main, 3 , 24576 );
1552+ }
1553+
1554+ // copy the reshardlog entries from src_bucket to dst_bucket
1555+ {
1556+ list<rgw_cls_bi_entry> src_entries;
1557+ bool truncated{false };
1558+ const bool reshardlog = true ;
1559+ ASSERT_EQ (0 , cls_rgw_bi_list (ioctx, src_bucket, " " , " " , 128 ,
1560+ &src_entries, &truncated, reshardlog));
1561+ ASSERT_EQ (4u , src_entries.size ());
1562+
1563+ const auto & entry = src_entries.front ();
1564+ EXPECT_EQ (BIIndexType::ReshardDeleted, entry.type );
1565+
1566+ ObjectWriteOperation op;
1567+ cls_rgw_bi_put_entries (op, {src_entries.begin (), src_entries.end ()}, true );
1568+ ASSERT_EQ (0 , ioctx.operate (dst_bucket, &op));
1569+
1570+ test_stats (ioctx, dst_bucket, RGWObjCategory::Main, 3 , 24576 );
1571+ }
1572+ }
0 commit comments