def test_set_uri(cartridge_cmd, conf_type, tmpdir, clusterwide_conf_simple,
                 clusterwide_conf_srv_disabled, clusterwide_conf_one_file):
    data_dir = os.path.join(tmpdir, 'tmp', 'data')
    os.makedirs(data_dir)

    NEW_URI = 'new-uri:666'

    configs = {
        'simple': clusterwide_conf_simple,
        'srv-disabled': clusterwide_conf_srv_disabled,
        'one-file-config': clusterwide_conf_one_file,
    }

    config = configs[conf_type]
    old_conf = config.conf

    # create app configs
    instances = ['instance-1', 'instance-2']
    conf_paths = write_instances_topology_conf(data_dir, APPNAME, old_conf,
                                               instances, config.one_file)

    # create other app configs
    other_instances = ['other-instance-1', 'other-instance-2']
    other_app_conf_paths = write_instances_topology_conf(
        data_dir,
        OTHER_APP_NAME,
        old_conf,
        other_instances,
        config.one_file,
    )

    cmd = [
        cartridge_cmd,
        'repair',
        'set-advertise-uri',
        '--name',
        APPNAME,
        '--data-dir',
        data_dir,
        config.instance_uuid,
        NEW_URI,
    ]

    rc, output = run_command_and_get_output(cmd, cwd=tmpdir)
    assert rc == 0

    # check logs
    logs = get_logs(output)
    assert logs[0] == "Set %s advertise URI to %s" % (config.instance_uuid,
                                                      NEW_URI)

    instances_logs = logs[-len(instances):]
    assert_ok_for_all_instances(instances_logs, instances)

    # check app config changes
    new_conf = get_conf_with_new_uri(old_conf, config.instance_uuid, NEW_URI)
    assert_conf_changed(conf_paths, other_app_conf_paths, old_conf, new_conf)
def test_remove(
        cartridge_cmd, conf_type, tmpdir, clusterwide_conf_simple,
        clusterwide_conf_srv_disabled, clusterwide_conf_srv_expelled,
        clusterwide_conf_srv_not_in_leaders, clusterwide_conf_non_existent_rpl,
        clusterwide_conf_srv_last_in_rpl, clusterwide_conf_srv_last_in_leaders,
        clusterwide_conf_current_leader_is_string, clusterwide_conf_one_file):
    data_dir = os.path.join(tmpdir, 'tmp', 'data')
    os.makedirs(data_dir)

    configs = {
        'simple': clusterwide_conf_simple,
        'disabled': clusterwide_conf_srv_disabled,
        'expelled': clusterwide_conf_srv_expelled,
        'not-in-leaders': clusterwide_conf_srv_not_in_leaders,
        'non-existent-rpl': clusterwide_conf_non_existent_rpl,
        'srv-last-in-rpl': clusterwide_conf_srv_last_in_rpl,
        'srv-last-in-leaders': clusterwide_conf_srv_last_in_leaders,
        'leader-is-string': clusterwide_conf_current_leader_is_string,
        'one-file-config': clusterwide_conf_one_file,
    }

    config = configs[conf_type]
    old_conf = copy.deepcopy(config.conf)
    instance_uuid = config.instance_uuid

    # create app configs
    instances = ['instance-1', 'instance-2']
    conf_paths = write_instances_topology_conf(data_dir, APPNAME, old_conf,
                                               instances, config.one_file)

    # create other app configs
    other_instances = ['other-instance-1', 'other-instance-2']
    other_app_conf_paths = write_instances_topology_conf(
        data_dir,
        OTHER_APP_NAME,
        old_conf,
        other_instances,
        config.one_file,
    )

    cmd = [
        cartridge_cmd,
        'repair',
        'remove-instance',
        '--name',
        APPNAME,
        '--data-dir',
        data_dir,
        instance_uuid,
    ]

    rc, output = run_command_and_get_output(cmd, cwd=tmpdir)
    assert rc == 0

    # check logs
    logs = get_logs(output)
    assert logs[0] == "Remove instance with UUID %s" % config.instance_uuid

    instances_logs = logs[-len(instances):]
    assert_ok_for_all_instances(instances_logs, instances)

    # check config changes
    new_conf = get_conf_with_removed_instance(old_conf, config.instance_uuid)
    assert_conf_changed(conf_paths, other_app_conf_paths, old_conf, new_conf)
def test_set_leader(cartridge_cmd, conf_type, tmpdir,
                    clusterwide_conf_simple,
                    clusterwide_conf_srv_not_in_leaders,
                    clusterwide_conf_other_leader_is_string,
                    clusterwide_conf_one_file):
    data_dir = os.path.join(tmpdir, 'tmp', 'data')
    os.makedirs(data_dir)

    configs = {
        'simple': clusterwide_conf_simple,
        'not-in-leaders': clusterwide_conf_srv_not_in_leaders,
        'leader-is-string': clusterwide_conf_other_leader_is_string,
        'one-file-config': clusterwide_conf_one_file,
    }

    config = configs[conf_type]
    old_conf = copy.deepcopy(config.conf)

    # create app configs
    instances = ['instance-1', 'instance-2']
    conf_paths = write_instances_topology_conf(data_dir, APPNAME, old_conf, instances, config.one_file)

    # create other app configs
    other_instances = ['other-instance-1', 'other-instance-2']
    other_app_conf_paths = write_instances_topology_conf(
        data_dir, OTHER_APP_NAME, old_conf, other_instances, config.one_file,
    )

    cmd = [
        cartridge_cmd, 'repair', 'set-leader',
        '--name', APPNAME,
        '--data-dir', data_dir,
        config.replicaset_uuid, config.instance_uuid,
    ]

    rc, output = run_command_and_get_output(cmd, cwd=tmpdir)
    assert rc == 0

    # check logs
    logs = get_logs(output)
    assert logs[0] == "Set %s leader to %s" % (config.replicaset_uuid, config.instance_uuid)

    instances_logs = logs[-len(instances):]
    assert_ok_for_all_instances(instances_logs, instances)

    # check app config changes
    new_conf = copy.deepcopy(old_conf)

    # apply expected changes to topology conf
    new_topology_conf = new_conf
    if config.one_file:
        new_topology_conf = new_conf['topology']

    new_leaders = new_topology_conf['replicasets'][config.replicaset_uuid]['master']
    if type(new_leaders) == list:
        if config.instance_uuid in new_leaders:
            new_leaders.remove(config.instance_uuid)

        new_leaders.insert(0, config.instance_uuid)
    else:
        new_topology_conf['replicasets'][config.replicaset_uuid]['master'] = config.instance_uuid

    assert_conf_changed(conf_paths, other_app_conf_paths, old_conf, new_conf)
def test_force_patch(cartridge_cmd, repair_cmd, tmpdir,
                     clusterwide_conf_simple_v1, clusterwide_conf_simple_v2):
    data_dir = os.path.join(tmpdir, 'tmp', 'data')
    os.makedirs(data_dir)

    config1 = clusterwide_conf_simple_v1
    config2 = clusterwide_conf_simple_v2

    # create app configs
    conf1_instances = ['instance-1', 'instance-2']
    conf1_paths = write_instances_topology_conf(data_dir, APPNAME,
                                                config1.conf, conf1_instances)

    conf2_instances = ['instance-3', 'instance-4']
    conf2_paths = write_instances_topology_conf(data_dir, APPNAME,
                                                config2.conf, conf2_instances)

    instances = conf1_instances + conf2_instances

    args = simple_args.get(repair_cmd, [])
    cmd = [
        cartridge_cmd,
        'repair',
        repair_cmd,
        '--name',
        APPNAME,
        '--data-dir',
        data_dir,
        '--force',
    ]
    cmd.extend(args)

    rc, output = run_command_and_get_output(cmd, cwd=tmpdir)
    assert rc == 0

    if repair_cmd == 'set-advertise-uri':
        first_log_line = "Set %s advertise URI to %s" % (args[0], args[1])
    elif repair_cmd == 'remove-instance':
        first_log_line = "Remove instance with UUID %s" % args[0]
    elif repair_cmd == 'set-leader':
        first_log_line = "Set %s leader to %s" % (args[0], args[1])

    logs = get_logs(output)
    assert logs[0] == first_log_line
    assert "Clusterwide config is diverged between instances" in logs[1]
    assert logs[2] == "Process application cluster-wide configurations..."

    process_conf_logs = logs[3:5]
    assert_ok_for_instances_group(process_conf_logs, conf1_instances)
    assert_ok_for_instances_group(process_conf_logs, conf2_instances)

    assert logs[5] == "Write application cluster-wide configurations..."

    write_conf_logs = logs[6:]
    assert_ok_for_all_instances(write_conf_logs, instances)

    # check config changes independently
    if repair_cmd == 'set-advertise-uri':
        new_conf1 = get_conf_with_new_uri(config1.conf, config1.instance_uuid,
                                          args[1])
        new_conf2 = get_conf_with_new_uri(config2.conf, config2.instance_uuid,
                                          args[1])
    elif repair_cmd == 'remove-instance':
        new_conf1 = get_conf_with_removed_instance(config1.conf, args[0])
        new_conf2 = get_conf_with_removed_instance(config2.conf, args[0])
    elif repair_cmd == 'set-leader':
        new_conf1 = get_conf_with_new_leader(config1.conf, args[0], args[1])
        new_conf2 = get_conf_with_new_leader(config2.conf, args[0], args[1])

    assert_conf_changed(conf1_paths, None, config1.conf, new_conf1)
    assert_conf_changed(conf2_paths, None, config2.conf, new_conf2)