]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_multi.py
57791448914595d76efe575609de9606781ddf5f
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 cmd
+= ['--debug-rgw', str(kwargs
.pop('debug_rgw', 0))]
56 cmd
+= ['--debug-ms', str(kwargs
.pop('debug_ms', 0))]
57 if kwargs
.pop('read_only', False):
58 cmd
+= ['--rgw-cache-enabled', 'false']
59 return bash(cmd
, **kwargs
)
62 cmd
= [mstart_path
+ 'mstart.sh', self
.cluster_id
]
64 cmd
+= ['-n', '--mds_num', '0']
66 self
.needs_reset
= False
69 cmd
= [mstart_path
+ 'mstop.sh', self
.cluster_id
]
72 class Gateway(multisite
.Gateway
):
73 """ gateway implementation based on mrgw/mstop scripts """
74 def __init__(self
, client_id
= None, *args
, **kwargs
):
75 super(Gateway
, self
).__init
__(*args
, **kwargs
)
78 def start(self
, args
= None):
79 """ start the gateway """
81 cmd
= [mstart_path
+ 'mrgw.sh', self
.cluster
.cluster_id
, str(self
.port
)]
83 cmd
+= ['-i', self
.id]
84 cmd
+= ['--debug-rgw=20', '--debug-ms=1']
90 """ stop the gateway """
92 cmd
= [mstart_path
+ 'mstop.sh', self
.cluster
.cluster_id
, 'radosgw', self
.id]
96 return ''.join(random
.choice(string
.ascii_uppercase
+ string
.digits
) for _
in range(16))
99 return ''.join(random
.choice(string
.ascii_uppercase
+ string
.ascii_lowercase
+ string
.digits
) for _
in range(32))
101 def gen_credentials():
102 return multisite
.Credentials(gen_access_key(), gen_secret())
104 def cluster_name(cluster_num
):
105 return 'c' + str(cluster_num
)
107 def zonegroup_name(zonegroup_num
):
108 return string
.ascii_lowercase
[zonegroup_num
]
110 def zone_name(zonegroup_num
, zone_num
):
111 return zonegroup_name(zonegroup_num
) + str(zone_num
+ 1)
113 def gateway_port(zonegroup_num
, gateway_num
):
114 return 8000 + 100 * zonegroup_num
+ gateway_num
116 def gateway_name(zonegroup_num
, zone_num
, gateway_num
):
117 return zone_name(zonegroup_num
, zone_num
) + '-' + str(gateway_num
+ 1)
119 def zone_endpoints(zonegroup_num
, zone_num
, gateways_per_zone
):
121 base
= gateway_port(zonegroup_num
, zone_num
* gateways_per_zone
)
122 for i
in range(0, gateways_per_zone
):
123 endpoints
.append('http://localhost:' + str(base
+ i
))
126 def get_log_level(log_level
):
135 return logging
.CRITICAL
137 def setup_logging(log_level_console
, log_file
, log_level_file
):
139 formatter
= logging
.Formatter('%(asctime)s %(levelname)s %(message)s')
140 fh
= logging
.FileHandler(log_file
)
141 fh
.setFormatter(formatter
)
142 fh
.setLevel(get_log_level(log_level_file
))
145 formatter
= logging
.Formatter('%(levelname)s %(message)s')
146 ch
= logging
.StreamHandler()
147 ch
.setFormatter(formatter
)
148 ch
.setLevel(get_log_level(log_level_console
))
151 def init(parse_args
):
152 cfg
= configparser
.RawConfigParser({
156 'gateways_per_zone': 2,
157 'no_bootstrap': 'false',
160 'file_log_level': 20,
162 'checkpoint_retries': 60,
163 'checkpoint_delay': 5,
164 'reconfigure_delay': 5,
168 path
= os
.environ
['RGW_MULTI_TEST_CONF']
170 path
= test_path
+ 'test_multi.conf'
173 with
open(path
) as f
:
176 print('WARNING: error reading test config. Path can be set through the RGW_MULTI_TEST_CONF env variable')
179 parser
= argparse
.ArgumentParser(
180 description
='Run rgw multi-site tests',
181 usage
='test_multi [--num-zonegroups <num>] [--num-zones <num>] [--no-bootstrap]')
184 parser
.add_argument('--num-zonegroups', type=int, default
=cfg
.getint(section
, 'num_zonegroups'))
185 parser
.add_argument('--num-zones', type=int, default
=cfg
.getint(section
, 'num_zones'))
186 parser
.add_argument('--num-es-zones', type=int, default
=cfg
.getint(section
, 'num_es_zones'))
187 parser
.add_argument('--gateways-per-zone', type=int, default
=cfg
.getint(section
, 'gateways_per_zone'))
188 parser
.add_argument('--no-bootstrap', action
='store_true', default
=cfg
.getboolean(section
, 'no_bootstrap'))
189 parser
.add_argument('--log-level', type=int, default
=cfg
.getint(section
, 'log_level'))
190 parser
.add_argument('--log-file', type=str, default
=cfg
.get(section
, 'log_file'))
191 parser
.add_argument('--file-log-level', type=int, default
=cfg
.getint(section
, 'file_log_level'))
192 parser
.add_argument('--tenant', type=str, default
=cfg
.get(section
, 'tenant'))
193 parser
.add_argument('--checkpoint-retries', type=int, default
=cfg
.getint(section
, 'checkpoint_retries'))
194 parser
.add_argument('--checkpoint-delay', type=int, default
=cfg
.getint(section
, 'checkpoint_delay'))
195 parser
.add_argument('--reconfigure-delay', type=int, default
=cfg
.getint(section
, 'reconfigure_delay'))
196 parser
.add_argument('--es-endpoint', type=str, default
=cfg
.get(section
, 'es_endpoint'))
203 args
= parser
.parse_args(argv
)
204 bootstrap
= not args
.no_bootstrap
206 # if num_es_zones is defined, need to have es_endpoint defined too
207 assert(args
.num_es_zones
== 0 or args
.es_endpoint
)
209 setup_logging(args
.log_level
, args
.log_file
, args
.file_log_level
)
211 # start first cluster
212 c1
= Cluster(cluster_name(1))
218 admin_creds
= gen_credentials()
219 admin_user
= multisite
.User('zone.user')
221 user_creds
= gen_credentials()
222 user
= multisite
.User('tester')
224 realm
= multisite
.Realm('r')
226 # create the realm on c1
230 period
= multisite
.Period(realm
=realm
)
231 realm
.current_period
= period
233 num_zones
= args
.num_zones
+ args
.num_es_zones
235 for zg
in range(0, args
.num_zonegroups
):
236 zonegroup
= multisite
.ZoneGroup(zonegroup_name(zg
), period
)
237 period
.zonegroups
.append(zonegroup
)
239 is_master_zg
= zg
== 0
241 period
.master_zonegroup
= zonegroup
243 for z
in range(0, num_zones
):
245 # start a cluster, or use c1 for first zone
247 if is_master_zg
and is_master
:
250 cluster
= Cluster(cluster_name(len(clusters
) + 1))
251 clusters
.append(cluster
)
254 # pull realm configuration from the master's gateway
255 gateway
= realm
.meta_master_zone().gateways
[0]
256 realm
.pull(cluster
, gateway
, admin_creds
)
258 endpoints
= zone_endpoints(zg
, z
, args
.gateways_per_zone
)
261 # create the zonegroup on its first zone's cluster
265 if len(endpoints
): # use master zone's endpoints
266 arg
+= ['--endpoints', ','.join(endpoints
)]
267 zonegroup
.create(cluster
, arg
)
269 zonegroup
.get(cluster
)
271 es_zone
= (z
>= args
.num_zones
)
273 # create the zone in its zonegroup
274 zone
= multisite
.Zone(zone_name(zg
, z
), zonegroup
, cluster
)
276 zone
= ESZone(zone_name(zg
, z
), args
.es_endpoint
, zonegroup
, cluster
)
278 zone
= RadosZone(zone_name(zg
, z
), zonegroup
, cluster
)
281 arg
= admin_creds
.credential_args()
285 arg
+= ['--endpoints', ','.join(endpoints
)]
286 zone
.create(cluster
, arg
)
289 zonegroup
.zones
.append(zone
)
291 zonegroup
.master_zone
= zone
293 zonegroup
.zones_by_type
.setdefault(zone
.tier_type(), []).append(zone
)
295 if zone
.is_read_only():
296 zonegroup
.ro_zones
.append(zone
)
298 zonegroup
.rw_zones
.append(zone
)
300 # update/commit the period
302 period
.update(zone
, commit
=True)
305 for g
in range(0, args
.gateways_per_zone
):
306 port
= gateway_port(zg
, g
+ z
* args
.gateways_per_zone
)
307 client_id
= gateway_name(zg
, z
, g
)
308 gateway
= Gateway(client_id
, 'localhost', port
, cluster
, zone
)
311 zone
.gateways
.append(gateway
)
313 if is_master_zg
and is_master
:
316 arg
= ['--display-name', '"Zone User"', '--system']
317 arg
+= admin_creds
.credential_args()
318 admin_user
.create(zone
, arg
)
320 arg
= ['--display-name', '"Test User"']
321 arg
+= user_creds
.credential_args()
323 cmd
+= ['--tenant', args
.tenant
]
324 user
.create(zone
, arg
)
326 # read users and update keys
327 admin_user
.info(zone
)
328 admin_creds
= admin_user
.credentials
[0]
330 user_creds
= user
.credentials
[0]
335 config
= Config(checkpoint_retries
=args
.checkpoint_retries
,
336 checkpoint_delay
=args
.checkpoint_delay
,
337 reconfigure_delay
=args
.reconfigure_delay
)
338 init_multi(realm
, user
, config
)
343 if __name__
== "__main__":