# Path: aredis/commands/cluster.py
# def parse_cluster_slots(response):
#     res = dict()
#     for slot_info in response:
#         min_slot, max_slot = slot_info[:2]
#         nodes = slot_info[2:]
#         parse_node = lambda node: {
#             'host': node[0],
#             'port': node[1],
#             'node_id': node[2] if len(node) > 2 else '',
#             'server_type': 'slave'
#         }
#         res[(min_slot, max_slot)] = [parse_node(node) for node in nodes]
#         res[(min_slot, max_slot)][0]['server_type'] = 'master'
#     return res
# 
# Path: aredis/exceptions.py
# class RedisClusterException(Exception):
#     pass
# 
# class ClusterDownError(ClusterError, ResponseError):
# 
#     def __init__(self, resp):
#         self.args = (resp,)
#         self.message = resp
# 
# Path: aredis/utils.py
# def list_keys_to_dict(key_list, callback):
#     return dict.fromkeys(key_list, callback)
# 
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# def dict_merge(*dicts):
#     merged = {}
#     for d in dicts:
#         merged.update(d)
#     return merged
# 
# def blocked_command(self, command):
#     """
#     Raises a `RedisClusterException` mentioning the command is blocked.
#     """
#     raise RedisClusterException("Command: {0} is blocked in redis cluster mode".format(command))
# 
# def merge_result(res):
#     """
#     Merges all items in `res` into a list.
# 
#     This command is used when sending a command to multiple nodes
#     and they result from each node should be merged into a single list.
#     """
#     if not isinstance(res, dict):
#         raise ValueError('Value should be of dict type')
# 
#     result = set([])
# 
#     for _, v in res.items():
#         for value in v:
#             result.add(value)
# 
#     return list(result)
# 
# def first_key(res):
#     """
#     Returns the first result for the given command.
# 
#     If more then 1 result is returned then a `RedisClusterException` is raised.
#     """
#     if not isinstance(res, dict):
#         raise ValueError('Value should be of dict type')
# 
#     if len(res.keys()) != 1:
#         raise RedisClusterException("More then 1 result from command")
# 
#     return list(res.values())[0]
# 
# def clusterdown_wrapper(func):
#     """
#     Wrapper for CLUSTERDOWN error handling.
# 
#     If the cluster reports it is down it is assumed that:
#      - connection_pool was disconnected
#      - connection_pool was reseted
#      - refereh_table_asap set to True
# 
#     It will try 3 times to rerun the command and raises ClusterDownException if it continues to fail.
#     """
# 
#     @wraps(func)
#     async def inner(*args, **kwargs):
#         for _ in range(0, 3):
#             try:
#                 return await func(*args, **kwargs)
#             except ClusterDownError:
#                 # Try again with the new cluster setup. All other errors
#                 # should be raised.
#                 pass
# 
#         # If it fails 3 times then raise exception back to caller
#         raise ClusterDownError("CLUSTERDOWN error. Unable to rebuild the cluster")
# 
#     return inner


from aredis.commands.cluster import parse_cluster_slots
from aredis.exceptions import (
    RedisClusterException, ClusterDownError
)
from aredis.utils import (
    list_keys_to_dict,
    b, dict_merge,
    blocked_command,
    merge_result,
    first_key,
    clusterdown_wrapper,
)
import pytest
             'port': 7004,
             'server_type': 'slave'}],
        (10923, 16383): [
            {'host': b'172.17.0.2',
             'node_id': b'3588b4cf9fc72d57bb262a024747797ead0cf7ea',
             'port': 7002,
             'server_type': 'master'},
            {'host': b'172.17.0.2',
             'node_id': b'a72c02c7d85f4ec3145ab2c411eefc0812aa96b0',
             'port': 7005,
             'server_type': 'slave'}]
    }

    assert parse_cluster_slots(extended_mock_binary_response) == extended_mock_parsed


def test_list_keys_to_dict():
    def mock_true():
        return True
    assert list_keys_to_dict(["FOO", "BAR"], mock_true) == {"FOO": mock_true, "BAR": mock_true}


def test_dict_merge():
    a = {"a": 1}
    b = {"b": 2}
    c = {"c": 3}
    assert dict_merge(a, b, c) == {"a": 1, "b": 2, "c": 3}


def test_dict_merge_empty_list():

# Path: aredis/commands/cluster.py
# def parse_cluster_slots(response):
#     res = dict()
#     for slot_info in response:
#         min_slot, max_slot = slot_info[:2]
#         nodes = slot_info[2:]
#         parse_node = lambda node: {
#             'host': node[0],
#             'port': node[1],
#             'node_id': node[2] if len(node) > 2 else '',
#             'server_type': 'slave'
#         }
#         res[(min_slot, max_slot)] = [parse_node(node) for node in nodes]
#         res[(min_slot, max_slot)][0]['server_type'] = 'master'
#     return res
# 
# Path: aredis/exceptions.py
# class RedisClusterException(Exception):
#     pass
# 
# class ClusterDownError(ClusterError, ResponseError):
# 
#     def __init__(self, resp):
#         self.args = (resp,)
#         self.message = resp
# 
# Path: aredis/utils.py
# def list_keys_to_dict(key_list, callback):
#     return dict.fromkeys(key_list, callback)
# 
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# def dict_merge(*dicts):
#     merged = {}
#     for d in dicts:
#         merged.update(d)
#     return merged
# 
# def blocked_command(self, command):
#     """
#     Raises a `RedisClusterException` mentioning the command is blocked.
#     """
#     raise RedisClusterException("Command: {0} is blocked in redis cluster mode".format(command))
# 
# def merge_result(res):
#     """
#     Merges all items in `res` into a list.
# 
#     This command is used when sending a command to multiple nodes
#     and they result from each node should be merged into a single list.
#     """
#     if not isinstance(res, dict):
#         raise ValueError('Value should be of dict type')
# 
#     result = set([])
# 
#     for _, v in res.items():
#         for value in v:
#             result.add(value)
# 
#     return list(result)
# 
# def first_key(res):
#     """
#     Returns the first result for the given command.
# 
#     If more then 1 result is returned then a `RedisClusterException` is raised.
#     """
#     if not isinstance(res, dict):
#         raise ValueError('Value should be of dict type')
# 
#     if len(res.keys()) != 1:
#         raise RedisClusterException("More then 1 result from command")
# 
#     return list(res.values())[0]
# 
# def clusterdown_wrapper(func):
#     """
#     Wrapper for CLUSTERDOWN error handling.
# 
#     If the cluster reports it is down it is assumed that:
#      - connection_pool was disconnected
#      - connection_pool was reseted
#      - refereh_table_asap set to True
# 
#     It will try 3 times to rerun the command and raises ClusterDownException if it continues to fail.
#     """
# 
#     @wraps(func)
#     async def inner(*args, **kwargs):
#         for _ in range(0, 3):
#             try:
#                 return await func(*args, **kwargs)
#             except ClusterDownError:
#                 # Try again with the new cluster setup. All other errors
#                 # should be raised.
#                 pass
# 
#         # If it fails 3 times then raise exception back to caller
#         raise ClusterDownError("CLUSTERDOWN error. Unable to rebuild the cluster")
# 
#     return inner


# Path: tests/cluster/test_utils.py
from aredis.commands.cluster import parse_cluster_slots
from aredis.exceptions import (
    RedisClusterException, ClusterDownError
)
from aredis.utils import (
    list_keys_to_dict,
    b, dict_merge,
    blocked_command,
    merge_result,
    first_key,
    clusterdown_wrapper,
)
import pytest

             'port': 7004,
             'server_type': 'slave'}],
        (10923, 16383): [
            {'host': b'172.17.0.2',
             'node_id': b'3588b4cf9fc72d57bb262a024747797ead0cf7ea',
             'port': 7002,
             'server_type': 'master'},
            {'host': b'172.17.0.2',
             'node_id': b'a72c02c7d85f4ec3145ab2c411eefc0812aa96b0',
             'port': 7005,
             'server_type': 'slave'}]
    }

    assert parse_cluster_slots(extended_mock_binary_response) == extended_mock_parsed


def test_list_keys_to_dict():
    def mock_true():
        return True
    assert list_keys_to_dict(["FOO", "BAR"], mock_true) == {"FOO": mock_true, "BAR": mock_true}


def test_dict_merge():
    a = {"a": 1}
    b = {"b": 2}
    c = {"c": 3}
    assert dict_merge(a, b, c) == {"a": 1, "b": 2, "c": 3}


def test_dict_merge_empty_list():

    assert dict_merge([]) == {}