]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_multi.py
11 import ConfigParser
as configparser
15 from rgw_multi
import multisite
16 from rgw_multi
.zone_rados
import RadosZone
as RadosZone
17 from rgw_multi
.zone_es
import ESZone
as ESZone
19 # make tests from rgw_multi.tests available to nose
20 from rgw_multi
.tests
import *
21 from rgw_multi
.tests_es
import *
23 mstart_path
= os
.getenv('MSTART_PATH')
24 if mstart_path
is None:
25 mstart_path
= os
.path
.normpath(os
.path
.dirname(os
.path
.realpath(__file__
)) + '/../..') + '/'
27 test_path
= os
.path
.normpath(os
.path
.dirname(os
.path
.realpath(__file__
))) + '/'
29 # configure logging for the tests module
30 log
= logging
.getLogger('rgw_multi.tests')
32 def bash(cmd
, **kwargs
):
33 log
.debug('running cmd: %s', ' '.join(cmd
))
34 check_retcode
= kwargs
.pop('check_retcode', True)
35 kwargs
['stdout'] = subprocess
.PIPE
36 process
= subprocess
.Popen(cmd
, **kwargs
)
37 s
= process
.communicate()[0]
38 log
.debug('command returned status=%d stdout=%s', process
.returncode
, s
.decode('utf-8'))
40 assert(process
.returncode
== 0)
41 return (s
, process
.returncode
)
43 class Cluster(multisite
.Cluster
):
44 """ cluster implementation based on mstart/mrun scripts """
45 def __init__(self
, cluster_id
):
46 super(Cluster
, self
).__init
__()
47 self
.cluster_id
= cluster_id
48 self
.needs_reset
= True
50 def admin(self
, args
= None, **kwargs
):
51 """ radosgw-admin command """
52 cmd
= [test_path
+ 'test-rgw-call.sh', 'call_rgw_admin', self
.cluster_id
]
55 if kwargs
.pop('read_only', False):
56 cmd
+= ['--rgw-cache-enabled', 'false']
57 return bash(cmd
, **kwargs
)
60 cmd
= [mstart_path
+ 'mstart.sh', self
.cluster_id
]
62 cmd
+= ['-n', '--mds_num', '0']
64 self
.needs_reset
= False
67 cmd
= [mstart_path
+ 'mstop.sh', self
.cluster_id
]
70 class Gateway(multisite
.Gateway
):
71 """ gateway implementation based on mrgw/mstop scripts """
72 def __init__(self
, client_id
= None, *args
, **kwargs
):
73 super(Gateway
, self
).__init
__(*args
, **kwargs
)
76 def start(self
, args
= None):
77 """ start the gateway """
79 cmd
= [mstart_path
+ 'mrgw.sh', self
.cluster
.cluster_id
, str(self
.port
)]
81 cmd
+= ['-i', self
.id]
82 cmd
+= ['--debug-rgw=20', '--debug-ms=1']
88 """ stop the gateway """
90 cmd
= [mstart_path
+ 'mstop.sh', self
.cluster
.cluster_id
, 'radosgw', self
.id]
94 return ''.join(random
.choice(string
.ascii_uppercase
+ string
.digits
) for _
in range(16))
97 return ''.join(random
.choice(string
.ascii_uppercase
+ string
.ascii_lowercase
+ string
.digits
) for _
in range(32))
99 def gen_credentials():
100 return multisite
.Credentials(gen_access_key(), gen_secret())
102 def cluster_name(cluster_num
):
103 return 'c' + str(cluster_num
)
105 def zonegroup_name(zonegroup_num
):
106 return string
.ascii_lowercase
[zonegroup_num
]
108 def zone_name(zonegroup_num
, zone_num
):
109 return zonegroup_name(zonegroup_num
) + str(zone_num
+ 1)
111 def gateway_port(zonegroup_num
, gateway_num
):
112 return 8000 + 100 * zonegroup_num
+ gateway_num
114 def gateway_name(zonegroup_num
, zone_num
, gateway_num
):
115 return zone_name(zonegroup_num
, zone_num
) + '-' + str(gateway_num
+ 1)
117 def zone_endpoints(zonegroup_num
, zone_num
, gateways_per_zone
):
119 base
= gateway_port(zonegroup_num
, zone_num
* gateways_per_zone
)
120 for i
in range(0, gateways_per_zone
):
121 endpoints
.append('http://localhost:' + str(base
+ i
))
124 def get_log_level(log_level
):
133 return logging
.CRITICAL
135 def setup_logging(log_level_console
, log_file
, log_level_file
):
137 formatter
= logging
.Formatter('%(asctime)s %(levelname)s %(message)s')
138 fh
= logging
.FileHandler(log_file
)
139 fh
.setFormatter(formatter
)
140 fh
.setLevel(get_log_level(log_level_file
))
143 formatter
= logging
.Formatter('%(levelname)s %(message)s')
144 ch
= logging
.StreamHandler()
145 ch
.setFormatter(formatter
)
146 ch
.setLevel(get_log_level(log_level_console
))
149 def init(parse_args
):
150 cfg
= configparser
.RawConfigParser({
154 'gateways_per_zone': 2,
155 'no_bootstrap': 'false',
158 'file_log_level': 20,
160 'checkpoint_retries': 60,
161 'checkpoint_delay': 5,
162 'reconfigure_delay': 5,
166 path
= os
.environ
['RGW_MULTI_TEST_CONF']
168 path
= test_path
+ 'test_multi.conf'
171 with
open(path
) as f
:
174 print('WARNING: error reading test config. Path can be set through the RGW_MULTI_TEST_CONF env variable')
177 parser
= argparse
.ArgumentParser(
178 description
='Run rgw multi-site tests',
179 usage
='test_multi [--num-zonegroups <num>] [--num-zones <num>] [--no-bootstrap]')
182 parser
.add_argument('--num-zonegroups', type=int, default
=cfg
.getint(section
, 'num_zonegroups'))
183 parser
.add_argument('--num-zones', type=int, default
=cfg
.getint(section
, 'num_zones'))
184 parser
.add_argument('--num-es-zones', type=int, default
=cfg
.getint(section
, 'num_es_zones'))
185 parser
.add_argument('--gateways-per-zone', type=int, default
=cfg
.getint(section
, 'gateways_per_zone'))
186 parser
.add_argument('--no-bootstrap', action
='store_true', default
=cfg
.getboolean(section
, 'no_bootstrap'))
187 parser
.add_argument('--log-level', type=int, default
=cfg
.getint(section
, 'log_level'))
188 parser
.add_argument('--log-file', type=str, default
=cfg
.get(section
, 'log_file'))
189 parser
.add_argument('--file-log-level', type=int, default
=cfg
.getint(section
, 'file_log_level'))
190 parser
.add_argument('--tenant', type=str, default
=cfg
.get(section
, 'tenant'))
191 parser
.add_argument('--checkpoint-retries', type=int, default
=cfg
.getint(section
, 'checkpoint_retries'))
192 parser
.add_argument('--checkpoint-delay', type=int, default
=cfg
.getint(section
, 'checkpoint_delay'))
193 parser
.add_argument('--reconfigure-delay', type=int, default
=cfg
.getint(section
, 'reconfigure_delay'))
194 parser
.add_argument('--es-endpoint', type=str, default
=cfg
.get(section
, 'es_endpoint'))
201 args
= parser
.parse_args(argv
)
202 bootstrap
= not args
.no_bootstrap
204 # if num_es_zones is defined, need to have es_endpoint defined too
205 assert(args
.num_es_zones
== 0 or args
.es_endpoint
)
207 setup_logging(args
.log_level
, args
.log_file
, args
.file_log_level
)
209 # start first cluster
210 c1
= Cluster(cluster_name(1))
216 admin_creds
= gen_credentials()
217 admin_user
= multisite
.User('zone.user')
219 user_creds
= gen_credentials()
220 user
= multisite
.User('tester')
222 realm
= multisite
.Realm('r')
224 # create the realm on c1
228 period
= multisite
.Period(realm
=realm
)
229 realm
.current_period
= period
231 num_zones
= args
.num_zones
+ args
.num_es_zones
233 for zg
in range(0, args
.num_zonegroups
):
234 zonegroup
= multisite
.ZoneGroup(zonegroup_name(zg
), period
)
235 period
.zonegroups
.append(zonegroup
)
237 is_master_zg
= zg
== 0
239 period
.master_zonegroup
= zonegroup
241 for z
in range(0, num_zones
):
243 # start a cluster, or use c1 for first zone
245 if is_master_zg
and is_master
:
248 cluster
= Cluster(cluster_name(len(clusters
) + 1))
249 clusters
.append(cluster
)
252 # pull realm configuration from the master's gateway
253 gateway
= realm
.meta_master_zone().gateways
[0]
254 realm
.pull(cluster
, gateway
, admin_creds
)
256 endpoints
= zone_endpoints(zg
, z
, args
.gateways_per_zone
)
259 # create the zonegroup on its first zone's cluster
263 if len(endpoints
): # use master zone's endpoints
264 arg
+= ['--endpoints', ','.join(endpoints
)]
265 zonegroup
.create(cluster
, arg
)
267 zonegroup
.get(cluster
)
269 es_zone
= (z
>= args
.num_zones
)
271 # create the zone in its zonegroup
272 zone
= multisite
.Zone(zone_name(zg
, z
), zonegroup
, cluster
)
274 zone
= ESZone(zone_name(zg
, z
), args
.es_endpoint
, zonegroup
, cluster
)
276 zone
= RadosZone(zone_name(zg
, z
), zonegroup
, cluster
)
279 arg
= admin_creds
.credential_args()
283 arg
+= ['--endpoints', ','.join(endpoints
)]
284 zone
.create(cluster
, arg
)
287 zonegroup
.zones
.append(zone
)
289 zonegroup
.master_zone
= zone
291 zonegroup
.zones_by_type
.setdefault(zone
.tier_type(), []).append(zone
)
293 if zone
.is_read_only():
294 zonegroup
.ro_zones
.append(zone
)
296 zonegroup
.rw_zones
.append(zone
)
298 # update/commit the period
300 period
.update(zone
, commit
=True)
303 for g
in range(0, args
.gateways_per_zone
):
304 port
= gateway_port(zg
, g
+ z
* args
.gateways_per_zone
)
305 client_id
= gateway_name(zg
, z
, g
)
306 gateway
= Gateway(client_id
, 'localhost', port
, cluster
, zone
)
309 zone
.gateways
.append(gateway
)
311 if is_master_zg
and is_master
:
314 arg
= ['--display-name', '"Zone User"', '--system']
315 arg
+= admin_creds
.credential_args()
316 admin_user
.create(zone
, arg
)
318 arg
= ['--display-name', '"Test User"']
319 arg
+= user_creds
.credential_args()
321 cmd
+= ['--tenant', args
.tenant
]
322 user
.create(zone
, arg
)
324 # read users and update keys
325 admin_user
.info(zone
)
326 admin_creds
= admin_user
.credentials
[0]
328 user_creds
= user
.credentials
[0]
333 config
= Config(checkpoint_retries
=args
.checkpoint_retries
,
334 checkpoint_delay
=args
.checkpoint_delay
,
335 reconfigure_delay
=args
.reconfigure_delay
)
336 init_multi(realm
, user
, config
)
341 if __name__
== "__main__":