def test_repair_reload_set_uri(cartridge_cmd, start_stop_cli, project_with_cartridge, tmpdir): project = project_with_cartridge cli = start_stop_cli cmd = [ cartridge_cmd, "build", project.path ] process = subprocess.run(cmd, cwd=tmpdir) assert process.returncode == 0, "Error during building the project" # patch cartridge.cfg to don't change process title patch_cartridge_proc_titile(project) # start instances INSTANCE1 = 'instance-1' INSTANCE2 = 'instance-2' ID1 = get_instance_id(project.name, INSTANCE1) ID2 = get_instance_id(project.name, INSTANCE2) ADMIN_HTTP_PORT = 8081 ADVERTISE_URI_TO_CHANGE = 'localhost:3302' NEW_ADVERTISE_URI = 'localhost:3322' INSTANCE_TO_SET_URI = INSTANCE2 cfg = { ID1: { 'advertise_uri': 'localhost:3301', 'http_port': ADMIN_HTTP_PORT, 'replication_connect_quorum': 0, 'custom_proc_title': '', }, ID2: { 'advertise_uri': ADVERTISE_URI_TO_CHANGE, 'http_port': 8082, 'replication_connect_quorum': 0, 'custom_proc_title': '', }, } write_conf(os.path.join(project.path, DEFAULT_CFG), cfg) # start instance-1 and instance-2 cli.start(project, daemonized=True) check_instances_running(cli, project, [INSTANCE1, INSTANCE2], daemonized=True) advertise_uris = [cfg[id]['advertise_uri'] for id in cfg] admin_api_url = 'http://localhost:%s/admin/api' % ADMIN_HTTP_PORT # join instances to replicaset replicaset_uuid = create_replicaset(admin_api_url, advertise_uris, ['vshard-storage']) replicaset = get_replicaset(admin_api_url, replicaset_uuid) instance_to_set_uri_uuid = None for instance in replicaset['servers']: if instance['uri'] == ADVERTISE_URI_TO_CHANGE: instance_to_set_uri_uuid = instance['uuid'] break assert instance_to_set_uri_uuid is not None # first, change URI in config and restart instance INSTANCE_ID = get_instance_id(project.name, INSTANCE_TO_SET_URI) cfg[INSTANCE_ID]['advertise_uri'] = NEW_ADVERTISE_URI write_conf(os.path.join(project.path, DEFAULT_CFG), cfg) cli.stop(project, [INSTANCE_TO_SET_URI]) check_instances_stopped(cli, project, [INSTANCE_TO_SET_URI]) cli.start(project, [INSTANCE_TO_SET_URI], daemonized=True) check_instances_running(cli, project, [INSTANCE1, INSTANCE2], daemonized=True, skip_env_checks=True) # then, update cluster-wide configs data_dir = os.path.join(project.path, DEFAULT_DATA_DIR) run_dir = os.path.join(project.path, DEFAULT_RUN_DIR) cmd = [ cartridge_cmd, 'repair', 'set-advertise-uri', '--name', project.name, '--data-dir', data_dir, '--run-dir', run_dir, '--reload', '--verbose', instance_to_set_uri_uuid, NEW_ADVERTISE_URI, ] rc, output = run_command_and_get_output(cmd, cwd=tmpdir) assert rc == 0 wait_for_replicaset_is_healthy(admin_api_url, replicaset_uuid) new_replicaset = get_replicaset(admin_api_url, replicaset_uuid) new_replicaset_instance_advertise_uri = None for instance in new_replicaset['servers']: if instance['uuid'] == instance_to_set_uri_uuid: new_replicaset_instance_advertise_uri = instance['uri'] break assert new_replicaset_instance_advertise_uri == NEW_ADVERTISE_URI
def test_repair_reload_set_leader(cartridge_cmd, start_stop_cli, project_with_cartridge, tmpdir): project = project_with_cartridge cli = start_stop_cli cmd = [ cartridge_cmd, "build", project.path ] process = subprocess.run(cmd, cwd=tmpdir) assert process.returncode == 0, "Error during building the project" # patch cartridge.cfg to don't change process title patch_cartridge_proc_titile(project) # start instances INSTANCE1 = 'instance-1' INSTANCE2 = 'instance-2' ID1 = get_instance_id(project.name, INSTANCE1) ID2 = get_instance_id(project.name, INSTANCE2) ADMIN_HTTP_PORT = 8081 cfg = { ID1: { 'advertise_uri': 'localhost:3301', 'http_port': ADMIN_HTTP_PORT, }, ID2: { 'advertise_uri': 'localhost:3302', 'http_port': 8082, }, } write_conf(os.path.join(project.path, DEFAULT_CFG), cfg) # start instance-1 and instance-2 cli.start(project, daemonized=True) check_instances_running(cli, project, [INSTANCE1, INSTANCE2], daemonized=True) advertise_uris = [cfg[id]['advertise_uri'] for id in cfg] # join instances to replicaset admin_api_url = 'http://localhost:%s/admin/api' % ADMIN_HTTP_PORT replicaset_uuid = create_replicaset(admin_api_url, advertise_uris, ['vshard-storage']) replicaset = get_replicaset(admin_api_url, replicaset_uuid) cluster_instances = replicaset['servers'] # change leader instances_by_priority = sorted(cluster_instances, key=lambda i: i['priority']) new_leader_uuid = instances_by_priority[-1]['uuid'] data_dir = os.path.join(project.path, DEFAULT_DATA_DIR) run_dir = os.path.join(project.path, DEFAULT_RUN_DIR) cmd = [ cartridge_cmd, 'repair', 'set-leader', '--name', project.name, '--data-dir', data_dir, '--run-dir', run_dir, '--reload', '--verbose', replicaset_uuid, new_leader_uuid, ] rc, output = run_command_and_get_output(cmd, cwd=tmpdir) assert rc == 0 wait_for_replicaset_is_healthy(admin_api_url, replicaset_uuid) new_replicaset = get_replicaset(admin_api_url, replicaset_uuid) new_replicaset_leader_uuid = new_replicaset['master']['uuid'] assert new_replicaset_leader_uuid == new_leader_uuid
def test_repair_reload_remove_instance(cartridge_cmd, start_stop_cli, project_with_cartridge, tmpdir): project = project_with_cartridge cli = start_stop_cli cmd = [ cartridge_cmd, "build", project.path ] process = subprocess.run(cmd, cwd=tmpdir) assert process.returncode == 0, "Error during building the project" # patch cartridge.cfg to don't change process title patch_cartridge_proc_titile(project) # start instances INSTANCE1 = 'instance-1' INSTANCE2 = 'instance-2' ID1 = get_instance_id(project.name, INSTANCE1) ID2 = get_instance_id(project.name, INSTANCE2) ADVERTISE_URI_TO_REMOVE = 'localhost:3302' ADMIN_HTTP_PORT = 8081 cfg = { # this instance shouldn't be removed since we use it's http port ID1: { 'advertise_uri': 'localhost:3301', 'http_port': ADMIN_HTTP_PORT, }, ID2: { 'advertise_uri': ADVERTISE_URI_TO_REMOVE, 'http_port': 8082, }, } write_conf(os.path.join(project.path, DEFAULT_CFG), cfg) # start instance-1 and instance-2 cli.start(project, daemonized=True) check_instances_running(cli, project, [INSTANCE1, INSTANCE2], daemonized=True) advertise_uris = [cfg[id]['advertise_uri'] for id in cfg] admin_api_url = 'http://localhost:%s/admin/api' % ADMIN_HTTP_PORT # join instances to replicaset replicaset_uuid = create_replicaset(admin_api_url, advertise_uris, ['vshard-storage']) replicaset = get_replicaset(admin_api_url, replicaset_uuid) cluster_instances = replicaset['servers'] # change leader instance_to_remove_uuid = None for instance in cluster_instances: if instance['uri'] == ADVERTISE_URI_TO_REMOVE: instance_to_remove_uuid = instance['uuid'] break assert instance_to_remove_uuid is not None data_dir = os.path.join(project.path, DEFAULT_DATA_DIR) run_dir = os.path.join(project.path, DEFAULT_RUN_DIR) cmd = [ cartridge_cmd, 'repair', 'remove-instance', '--name', project.name, '--data-dir', data_dir, '--run-dir', run_dir, '--reload', '--verbose', instance_to_remove_uuid, ] rc, output = run_command_and_get_output(cmd, cwd=tmpdir) assert rc == 0 wait_for_replicaset_is_healthy(admin_api_url, replicaset_uuid) new_replicaset = get_replicaset(admin_api_url, replicaset_uuid) new_replicaset_instances_uuids = [ instance['uuid'] for instance in new_replicaset['servers'] ] assert instance_to_remove_uuid not in new_replicaset_instances_uuids
def test_api(start_stop_cli, cartridge_cmd, project_getting_started): project = project_getting_started cli = start_stop_cli APP_INSTANCES = [project.get_instance_id('router')] S1_INSTANCES = [ project.get_instance_id('s1-master'), project.get_instance_id('s1-replica') ] S2_INSTANCES = [ project.get_instance_id('s2-master'), project.get_instance_id('s2-replica') ] # build app process = subprocess.run([cartridge_cmd, 'build'], cwd=project.path) assert process.returncode == 0 patch_cartridge_proc_titile(project) # check config and get instances instances_conf = get_instances_from_conf(project) instance_ids = list(instances_conf.keys()) instances = [instance_id.split(".")[1] for instance_id in instance_ids] assert all([ instance_id in instance_ids for instance_id in APP_INSTANCES + S1_INSTANCES + S2_INSTANCES ]) router_http_port = instances_conf[APP_INSTANCES[0]]['http_port'] admin_api_url = 'http://localhost:{}/admin/api'.format(router_http_port) # start application in interactive mode (to easily check logs on debug) cli.start(project) check_instances_running(cli, project, instances) # create app replicaset uris = [ instances_conf[instance_id]['advertise_uri'] for instance_id in APP_INSTANCES ] roles = ['api'] app_replicaset_uuid = create_replicaset(admin_api_url, uris, roles) wait_for_replicaset_is_healthy(admin_api_url, app_replicaset_uuid) replicaset_roles = get_replicaset_roles(admin_api_url, app_replicaset_uuid) # api role should contain vshard-router dependency assert set(replicaset_roles) == set(['api', 'vshard-router']) # create s1 replicaset uris = [ instances_conf[instance_id]['advertise_uri'] for instance_id in S1_INSTANCES ] roles = ['storage'] s1_replicaset_uuid = create_replicaset(admin_api_url, uris, roles) wait_for_replicaset_is_healthy(admin_api_url, s1_replicaset_uuid) replicaset_roles = get_replicaset_roles(admin_api_url, s1_replicaset_uuid) # storage role should contain vshard-storage dependency assert set(replicaset_roles) == set(['storage', 'vshard-storage']) # create s2 replicaset uris = [ instances_conf[instance_id]['advertise_uri'] for instance_id in S2_INSTANCES ] roles = ['storage'] s2_replicaset_uuid = create_replicaset(admin_api_url, uris, roles) wait_for_replicaset_is_healthy(admin_api_url, s2_replicaset_uuid) replicaset_roles = get_replicaset_roles(admin_api_url, s2_replicaset_uuid) # storage role should contain vshard-storage dependency assert set(replicaset_roles) == set(['storage', 'vshard-storage']) # bootstrap vshard bootstrap_vshard(admin_api_url) # test HTTP API CUSTOMER_ID = 10 CUSTOMER_NAME = 'Elizabeth' customer = {'customer_id': CUSTOMER_ID, 'name': CUSTOMER_NAME} # create new customer url = 'http://localhost:{}/storage/customers/create'.format( router_http_port) r = requests.post(url, json=customer) assert r.status_code == requests.status_codes.codes.CREATED resp = r.json() assert 'info' in resp assert resp['info'] == 'Successfully created' # # create the same customer again # r = requests.post(url, json=customer) # # XXX: r.status_code is 500 now # get customer url = 'http://localhost:{}/storage/customers/{}'.format( router_http_port, CUSTOMER_ID) r = requests.get(url, json=customer) assert r.status_code == requests.status_codes.codes.OK resp = r.json() assert resp == { 'customer_id': CUSTOMER_ID, 'name': CUSTOMER_NAME, 'accounts': [], } # get customer by wrong id url = 'http://localhost:{}/storage/customers/{}'.format( router_http_port, CUSTOMER_ID + 1) r = requests.get(url, json=customer) assert r.status_code == requests.status_codes.codes.NOT_FOUND resp = r.json() assert 'info' in resp assert resp['info'] == 'Customer not found'