Skip to content

Commit cec5e83

Browse files
test/rgw: add test for logrecord reshard
Signed-off-by: Mingyuan Liang <[email protected]>
1 parent 7299783 commit cec5e83

File tree

5 files changed

+100
-1
lines changed

5 files changed

+100
-1
lines changed

qa/suites/rgw/verify/overrides.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ overrides:
1414
rgw bucket counters cache: true
1515
rgw sts key: abcdefghijklmnop
1616
rgw s3 auth use sts: true
17+
rgw reshard progress judge interval: 10
1718
rgw:
1819
compression type: random
1920
storage classes: LUKEWARM, FROZEN

qa/workunits/rgw/test_rgw_reshard.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ def get_bucket_num_shards(bucket_name, bucket_id):
7676
num_shards = json_op['data']['bucket_info']['num_shards']
7777
return num_shards
7878

79+
def get_bucket_reshard_status(bucket_name):
80+
"""
81+
function to get bucket reshard status
82+
"""
83+
cmd = exec_cmd("radosgw-admin bucket stats --bucket {}".format(bucket_name))
84+
json_op = json.loads(cmd)
85+
#print(json.dumps(json_op, indent = 4, sort_keys=True))
86+
reshard_status = json_op['reshard_status']
87+
return reshard_status
88+
7989
def run_bucket_reshard_cmd(bucket_name, num_shards, **kwargs):
8090
cmd = 'radosgw-admin bucket reshard --bucket {} --num-shards {}'.format(bucket_name, num_shards)
8191
cmd += ' --rgw-reshard-bucket-lock-duration 30' # reduce to minimum
@@ -139,6 +149,11 @@ def test_bucket_reshard(conn, name, **fault):
139149
bucket.delete_objects(Delete={'Objects':[{'Key':o.key} for o in objs]})
140150
bucket.delete()
141151

152+
def calc_reshardlog_count(json_op):
153+
cnt = 0
154+
for shard in json_op:
155+
cnt += len(shard['shard_entries'])
156+
return cnt
142157

143158
def main():
144159
"""
@@ -235,6 +250,68 @@ def main():
235250
log.debug('TEST: reshard bucket with abort at change_reshard_state\n')
236251
test_bucket_reshard(connection, 'abort-at-change-reshard-state', abort_at='change_reshard_state')
237252

253+
# TESTCASE 'logrecord could be stopped after reshard failed'
254+
log.debug(' test: logrecord could be stopped after reshard failed')
255+
num_shards = get_bucket_stats(BUCKET_NAME).num_shards
256+
assert "None" == get_bucket_reshard_status(BUCKET_NAME)
257+
_, ret = run_bucket_reshard_cmd(BUCKET_NAME, num_shards + 1, check_retcode=False, abort_at='change_reshard_state')
258+
assert(ret != 0 and ret != errno.EBUSY)
259+
assert "InLogrecord" == get_bucket_reshard_status(BUCKET_NAME)
260+
261+
bucket.put_object(Key='put_during_logrecord', Body=b"some_data")
262+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
263+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
264+
assert calc_reshardlog_count(json_op) == 1
265+
266+
# end up with logrecord status, the logrecord will be purged
267+
time.sleep(30)
268+
assert "InLogrecord" == get_bucket_reshard_status(BUCKET_NAME)
269+
bucket.put_object(Key='put_during_logrecord1', Body=b"some_data1")
270+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
271+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
272+
assert calc_reshardlog_count(json_op) == 0
273+
assert "None" == get_bucket_reshard_status(BUCKET_NAME)
274+
275+
# TESTCASE 'duplicated entries should be purged before reshard'
276+
log.debug(' test: duplicated entries should be purged before reshard')
277+
num_shards = get_bucket_stats(BUCKET_NAME).num_shards
278+
_, ret = run_bucket_reshard_cmd(BUCKET_NAME, num_shards + 1, check_retcode=False, abort_at='do_reshard')
279+
assert(ret != 0 and ret != errno.EBUSY)
280+
assert "InLogrecord" == get_bucket_reshard_status(BUCKET_NAME)
281+
282+
bucket.put_object(Key='put_during_logrecord2', Body=b"some_data2")
283+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
284+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
285+
assert calc_reshardlog_count(json_op) == 1
286+
287+
# begin to reshard again, the duplicated entries will be purged
288+
time.sleep(30)
289+
_, ret = run_bucket_reshard_cmd(BUCKET_NAME, num_shards + 1, check_retcode=False, abort_at='logrecord_writes')
290+
assert(ret != 0 and ret != errno.EBUSY)
291+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
292+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
293+
assert calc_reshardlog_count(json_op) == 0
294+
295+
# TESTCASE 'duplicated entries can be purged manually'
296+
log.debug(' test: duplicated entries can be purged manually')
297+
time.sleep(30)
298+
num_shards = get_bucket_stats(BUCKET_NAME).num_shards
299+
_, ret = run_bucket_reshard_cmd(BUCKET_NAME, num_shards + 1, check_retcode=False, abort_at='do_reshard')
300+
assert(ret != 0 and ret != errno.EBUSY)
301+
assert "InLogrecord" == get_bucket_reshard_status(BUCKET_NAME)
302+
303+
bucket.put_object(Key='put_during_logrecord3', Body=b"some_data3")
304+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
305+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
306+
assert calc_reshardlog_count(json_op) == 1
307+
308+
time.sleep(30)
309+
exec_cmd('radosgw-admin reshardlog purge --bucket %s' % BUCKET_NAME)
310+
cmd = exec_cmd('radosgw-admin reshardlog list --bucket %s' % BUCKET_NAME)
311+
json_op = json.loads(cmd.decode('utf-8', 'ignore')) # ignore utf-8 can't decode 0x80
312+
assert calc_reshardlog_count(json_op) == 0
313+
log.debug('check reshard logrecord successfully')
314+
238315
# TESTCASE 'versioning reshard-','bucket', reshard','versioning reshard','succeeds'
239316
log.debug(' test: reshard versioned bucket')
240317
num_shards_expected = get_bucket_stats(VER_BUCKET_NAME).num_shards + 1
@@ -288,6 +365,8 @@ def main():
288365
time.sleep(1)
289366
ver_bucket.put_object(Key='put_during_reshard', Body=b"some_data")
290367
log.debug('put object successful')
368+
# waiter for delay reshard to finish
369+
time.sleep(5)
291370

292371
# TESTCASE 'check that bucket stats are correct after reshard with unlinked entries'
293372
log.debug('TEST: check that bucket stats are correct after reshard with unlinked entries\n')

src/rgw/rgw_admin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11074,7 +11074,7 @@ int main(int argc, const char **argv)
1107411074
for (; i < max_shards; i++) {
1107511075
formatter->open_object_section("shard");
1107611076
encode_json("shard_id", i, formatter.get());
11077-
formatter->open_array_section("single shard entries");
11077+
formatter->open_array_section("shard_entries");
1107811078
RGWRados::BucketShard bs(static_cast<rgw::sal::RadosStore*>(driver)->getRados());
1107911079
int ret = bs.init(dpp(), bucket->get_info(), index, i, null_yield);
1108011080
if (ret < 0) {

src/test/cli/radosgw-admin/help.t

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@
182182
reshard cancel cancel resharding a bucket
183183
reshard stale-instances list list stale-instances from bucket resharding
184184
reshard stale-instances delete cleanup stale-instances from bucket resharding
185+
reshardlog list list bucket reshard newest generation log
186+
reshardlog purge trim all bucket resharding log
185187
sync error list list sync error
186188
sync error trim trim sync error
187189
mfa create create a new MFA TOTP token

src/test/cls_rgw/test_cls_rgw.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,7 @@ TEST_F(cls_rgw, reshardlog_list)
13891389

13901390
// record a log in prepare
13911391
cls_rgw_obj_key obj2 = str_int("obj2", 0);
1392+
entries.clear();
13921393
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_ADD, tag, obj2, loc);
13931394
ASSERT_EQ(0, reshardlog_list(ioctx, bucket_oid, &entries, &is_truncated));
13941395
ASSERT_FALSE(is_truncated);
@@ -1400,4 +1401,20 @@ TEST_F(cls_rgw, reshardlog_list)
14001401
ASSERT_EQ(0, reshardlog_list(ioctx, bucket_oid, &entries, &is_truncated));
14011402
ASSERT_FALSE(is_truncated);
14021403
ASSERT_EQ(1u, entries.size());
1404+
1405+
// record a log in deleting obj
1406+
entries.clear();
1407+
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag, obj1, loc);
1408+
index_complete(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag, 1, obj1, meta);
1409+
ASSERT_EQ(0, reshardlog_list(ioctx, bucket_oid, &entries, &is_truncated));
1410+
ASSERT_FALSE(is_truncated);
1411+
ASSERT_EQ(2u, entries.size());
1412+
1413+
// overwrite the log writen
1414+
entries.clear();
1415+
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag, obj2, loc);
1416+
index_complete(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag, 1, obj2, meta);
1417+
ASSERT_EQ(0, reshardlog_list(ioctx, bucket_oid, &entries, &is_truncated));
1418+
ASSERT_FALSE(is_truncated);
1419+
ASSERT_EQ(2u, entries.size());
14031420
}

0 commit comments

Comments
 (0)