]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/workunits/rgw/test_rgw_reshard.py
10 Rgw manual and dynamic resharding testing against a running instance
12 # The test cases in this file have been annotated for inventory.
13 # To extract the inventory (in csv format) use the command:
15 # grep '^ *# TESTCASE' | sed 's/^ *# TESTCASE //'
19 log
.basicConfig(level
=log
.DEBUG
)
20 log
.getLogger('botocore').setLevel(log
.CRITICAL
)
21 log
.getLogger('boto3').setLevel(log
.CRITICAL
)
22 log
.getLogger('urllib3').setLevel(log
.CRITICAL
)
26 DISPLAY_NAME
= 'Testing'
27 ACCESS_KEY
= 'NX5QOQKC6BH2IDN8HC7A'
28 SECRET_KEY
= 'LnEsqNNqZIpkzauboDcLXLcYaWwLQ3Kop0zAnKIn'
29 BUCKET_NAME1
= 'myfoo'
30 BUCKET_NAME2
= 'mybar'
31 VER_BUCKET_NAME
= 'myver'
36 proc
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
, shell
=True)
37 out
, err
= proc
.communicate()
38 if proc
.returncode
== 0:
39 log
.info('command succeeded')
40 if out
is not None: log
.info(out
)
43 raise Exception("error: %s \nreturncode: %s" % (err
, proc
.returncode
))
44 except Exception as e
:
45 log
.error('command failed')
50 def get_radosgw_port():
51 out
= exec_cmd('sudo netstat -nltp | grep radosgw')
52 log
.debug('output: %s' % out
)
53 x
= out
.decode('utf8').split(" ")
54 port
= [i
for i
in x
if ':' in i
][0].split(':')[1]
55 log
.info('radosgw port: %s' % port
)
60 def __init__(self
, bucket_name
, bucket_id
, num_objs
=0, size_kb
=0, num_shards
=0):
61 self
.bucket_name
= bucket_name
62 self
.bucket_id
= bucket_id
63 self
.num_objs
= num_objs
64 self
.size_kb
= size_kb
65 self
.num_shards
= num_shards
if num_shards
> 0 else 1
67 def get_num_shards(self
):
68 self
.num_shards
= get_bucket_num_shards(self
.bucket_name
, self
.bucket_id
)
71 def get_bucket_stats(bucket_name
):
73 function to get bucket stats
75 cmd
= exec_cmd("radosgw-admin bucket stats --bucket %s" % bucket_name
)
76 json_op
= json
.loads(cmd
)
77 bucket_id
= json_op
['id']
78 num_shards_op
= json_op
['num_shards']
79 if len(json_op
['usage']) > 0:
80 num_objects
= json_op
['usage']['rgw.main']['num_objects']
81 size_kb
= json_op
['usage']['rgw.main']['size_kb']
85 log
.debug("bucket %s id %s num_objects %d size_kb %d num_shards %d", bucket_name
, bucket_id
,
86 num_objects
, size_kb
, num_shards_op
)
87 return BucketStats(bucket_name
, bucket_id
, num_objects
, size_kb
, num_shards_op
)
90 def get_bucket_num_shards(bucket_name
, bucket_id
):
92 function to get bucket num shards
94 metadata
= 'bucket.instance:' + bucket_name
+ ':' + bucket_id
95 log
.debug("metadata %s", metadata
)
96 cmd
= exec_cmd('radosgw-admin metadata get %s' % metadata
)
97 json_op
= json
.loads(cmd
)
98 num_shards
= json_op
['data']['bucket_info']['num_shards']
99 log
.debug("bucket %s id %s num_shards %d", bucket_name
, bucket_id
, num_shards
)
105 execute manual and dynamic resharding commands
108 exec_cmd('radosgw-admin user create --uid %s --display-name %s --access-key %s --secret %s'
109 % (USER
, DISPLAY_NAME
, ACCESS_KEY
, SECRET_KEY
))
111 def boto_connect(portnum
, ssl
, proto
):
112 endpoint
= proto
+ '://localhost:' + portnum
113 conn
= boto3
.resource('s3',
114 aws_access_key_id
=ACCESS_KEY
,
115 aws_secret_access_key
=SECRET_KEY
,
117 endpoint_url
=endpoint
,
123 port
= get_radosgw_port()
126 connection
= boto_connect(port
, ssl
=False, proto
='http')
128 connection
= boto_connect(port
, ssl
=True, proto
='https')
131 bucket1
= connection
.create_bucket(Bucket
=BUCKET_NAME1
)
132 bucket2
= connection
.create_bucket(Bucket
=BUCKET_NAME2
)
133 ver_bucket
= connection
.create_bucket(Bucket
=VER_BUCKET_NAME
)
134 connection
.BucketVersioning('ver_bucket')
136 bucket_stats1
= get_bucket_stats(BUCKET_NAME1
)
137 bucket_stats2
= get_bucket_stats(BUCKET_NAME2
)
138 ver_bucket_stats
= get_bucket_stats(VER_BUCKET_NAME
)
140 bucket1_acl
= connection
.BucketAcl(BUCKET_NAME1
).load()
141 bucket2_acl
= connection
.BucketAcl(BUCKET_NAME2
).load()
142 ver_bucket_acl
= connection
.BucketAcl(VER_BUCKET_NAME
).load()
144 # TESTCASE 'reshard-add','reshard','add','add bucket to resharding queue','succeeds'
145 log
.debug(' test: reshard add')
146 num_shards_expected
= bucket_stats1
.num_shards
+ 1
147 cmd
= exec_cmd('radosgw-admin reshard add --bucket %s --num-shards %s' % (BUCKET_NAME1
, num_shards_expected
))
148 cmd
= exec_cmd('radosgw-admin reshard list')
149 json_op
= json
.loads(cmd
)
150 log
.debug('bucket name %s', json_op
[0]['bucket_name'])
151 assert json_op
[0]['bucket_name'] == BUCKET_NAME1
152 assert json_op
[0]['new_num_shards'] == num_shards_expected
154 # TESTCASE 'reshard-process','reshard','','process bucket resharding','succeeds'
155 log
.debug(' test: reshard process')
156 cmd
= exec_cmd('radosgw-admin reshard process')
158 # check bucket shards num
159 bucket_stats1
= get_bucket_stats(BUCKET_NAME1
)
160 bucket_stats1
.get_num_shards()
161 if bucket_stats1
.num_shards
!= num_shards_expected
:
162 log
.error("Resharding failed on bucket %s. Expected number of shards are not created" % BUCKET_NAME1
)
164 # TESTCASE 'reshard-add','reshard','add','add non empty bucket to resharding queue','succeeds'
165 log
.debug(' test: reshard add non empty bucket')
168 for i
in range(0, num_objs
):
169 connection
.Object(BUCKET_NAME1
, ('key'+str(i
))).put(Body
=b
"some_data")
171 num_shards_expected
= bucket_stats1
.num_shards
+ 1
172 cmd
= exec_cmd('radosgw-admin reshard add --bucket %s --num-shards %s' % (BUCKET_NAME1
, num_shards_expected
))
173 cmd
= exec_cmd('radosgw-admin reshard list')
174 json_op
= json
.loads(cmd
)
175 log
.debug('bucket name %s', json_op
[0]['bucket_name'])
176 assert json_op
[0]['bucket_name'] == BUCKET_NAME1
177 assert json_op
[0]['new_num_shards'] == num_shards_expected
179 # TESTCASE 'reshard process ,'reshard','process','reshard non empty bucket','succeeds'
180 log
.debug(' test: reshard process non empty bucket')
181 cmd
= exec_cmd('radosgw-admin reshard process')
182 # check bucket shards num
183 bucket_stats1
= get_bucket_stats(BUCKET_NAME1
)
184 bucket_stats1
.get_num_shards()
185 if bucket_stats1
.num_shards
!= num_shards_expected
:
186 log
.error("Resharding failed on bucket %s. Expected number of shards are not created" % BUCKET_NAME1
)
188 # TESTCASE 'manual resharding','bucket', 'reshard','','manual bucket resharding','succeeds'
189 log
.debug(' test: manual reshard bucket')
192 for i
in range(0, num_objs
):
193 connection
.Object(BUCKET_NAME2
, ('key' + str(i
))).put(Body
=b
"some_data")
196 num_shards_expected
= bucket_stats2
.num_shards
+ 1
197 cmd
= exec_cmd('radosgw-admin bucket reshard --bucket %s --num-shards %s' % (BUCKET_NAME2
,
198 num_shards_expected
))
199 # check bucket shards num
200 bucket_stats2
= get_bucket_stats(BUCKET_NAME2
)
201 bucket_stats2
.get_num_shards()
202 if bucket_stats2
.num_shards
!= num_shards_expected
:
203 log
.error("Resharding failed on bucket %s. Expected number of shards are not created" % BUCKET_NAME2
)
205 # TESTCASE 'versioning reshard-','bucket', reshard','versioning reshard','succeeds'
206 log
.debug(' test: reshard versioned bucket')
207 num_shards_expected
= ver_bucket_stats
.num_shards
+ 1
208 cmd
= exec_cmd('radosgw-admin bucket reshard --bucket %s --num-shards %s' % (VER_BUCKET_NAME
,
209 num_shards_expected
))
210 # check bucket shards num
211 ver_bucket_stats
= get_bucket_stats(VER_BUCKET_NAME
)
212 assert ver_bucket_stats
.num_shards
== num_shards_expected
214 # TESTCASE 'check acl'
215 new_bucket1_acl
= connection
.BucketAcl(BUCKET_NAME1
).load()
216 assert new_bucket1_acl
== bucket1_acl
217 new_bucket2_acl
= connection
.BucketAcl(BUCKET_NAME2
).load()
218 assert new_bucket2_acl
== bucket2_acl
219 new_ver_bucket_acl
= connection
.BucketAcl(VER_BUCKET_NAME
).load()
220 assert new_ver_bucket_acl
== ver_bucket_acl
223 log
.debug("Deleting bucket %s", BUCKET_NAME1
)
224 bucket1
.objects
.all().delete()
226 log
.debug("Deleting bucket %s", BUCKET_NAME2
)
227 bucket2
.objects
.all().delete()
229 log
.debug("Deleting bucket %s", VER_BUCKET_NAME
)
234 log
.info("Completed resharding tests")