// Path: src/main/java/com/behase/relumin/exception/ApiException.java
// public class ApiException extends RuntimeException {
//     private static final long serialVersionUID = 3285456520279227122L;
// 
//     @Getter
//     @Setter
//     private ErrorResponse errorResponse;
// 
//     @Getter
//     @Setter
//     private HttpStatus httpStatus;
// 
//     public ApiException(ErrorResponse errorResponse, HttpStatus httpStatus) {
//         super(errorResponse.getError().getMessage());
//         this.errorResponse = errorResponse;
//         this.httpStatus = httpStatus;
//     }
// 
//     public ApiException(String code, String message, HttpStatus httpStatus) {
//         super(message);
//         this.errorResponse = new ErrorResponse(code, message);
//         this.httpStatus = httpStatus;
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/exception/InvalidParameterException.java
// public class InvalidParameterException extends ApiException {
//     private static final long serialVersionUID = -6416726302671334601L;
// 
//     public InvalidParameterException(String message) {
//         super(Constants.ERR_CODE_INVALID_PARAMETER, String.format("Invalid parameter. %s", message), HttpStatus.BAD_REQUEST);
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/model/ClusterNode.java
// @Data
// @Builder
// @NoArgsConstructor
// @AllArgsConstructor
// public class ClusterNode {
//     private String nodeId;
//     private String hostAndPort;
//     private Set<String> flags = Sets.newLinkedHashSet();
//     private String masterNodeId;
//     private long pingSent;
//     private long pongReceived;
//     private long configEpoch;
//     private boolean connect;
//     private Map<Integer, String> migrating = Maps.newLinkedHashMap();
//     private Map<Integer, String> importing = Maps.newLinkedHashMap();
// 
//     @JsonIgnore
//     private Set<Integer> servedSlotsSet = Sets.newTreeSet();
// 
//     public boolean hasFlag(String flag) {
//         if (flags == null || flags.isEmpty()) {
//             return false;
//         }
//         return flags.contains(flag);
//     }
// 
//     public String getServedSlots() {
//         return new JedisSupport().slotsDisplay(servedSlotsSet);
//     }
// 
//     public int getSlotCount() {
//         if (servedSlotsSet == null) {
//             return 0;
//         }
//         return servedSlotsSet.size();
//     }
// 
//     @JsonIgnore
//     public String getHost() {
//         return StringUtils.split(hostAndPort, ":")[0];
//     }
// 
//     @JsonIgnore
//     public int getPort() {
//         return Integer.valueOf(StringUtils.split(hostAndPort, ":")[1]);
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
// 
//         ClusterNode other = (ClusterNode) obj;
//         return StringUtils.equalsIgnoreCase(nodeId, other.nodeId);
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/model/param/CreateClusterParam.java
// @Data
// @Builder
// @NoArgsConstructor
// @AllArgsConstructor
// public class CreateClusterParam {
//     private String startSlotNumber;
//     private String endSlotNumber;
//     private String master;
//     private List<String> replicas = Lists.newArrayList();
// 
//     @JsonIgnore
//     private String masterNodeId;
// }


import com.behase.relumin.exception.ApiException;
import com.behase.relumin.exception.InvalidParameterException;
import com.behase.relumin.model.ClusterNode;
import com.behase.relumin.model.param.CreateClusterParam;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.internal.util.reflection.Whitebox;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.boot.test.OutputCapture;
import redis.clients.jedis.Jedis;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anySet;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyList;
import static org.mockito.Mockito.*;

        doReturn(jedis).when(mock2).getJedis();
        doReturn(jedis).when(mock3).getJedis();

        doReturn(true).when(mock1).hasFlag("slave");
        doReturn(jedis).when(mock2).getJedis();
        doReturn(jedis).when(mock3).getJedis();
        doReturn(1l).doReturn(2l).when(jedis).clusterCountKeysInSlot(anyInt());

        // when
        TribClusterNode result = tested.getNodeWithMostKeysInSlot(Lists.newArrayList(mock1, mock2, mock3), 0);

        // then
        assertThat(result, is(mock3));
    }

    @Test
    public void fixOpenSlot_owner_node_is_null_then_throw() {
        expectedEx.expect(ApiException.class);
        expectedEx.expectMessage(containsString("Fix me, some work to do here"));

        // given
        doReturn(null).when(tested).getSlotOwner(anyInt());

        // then
        tested.fixOpenSlot(0);
    }

    @Test
    public void fixOpenSlot_else_case() {
// Path: src/main/java/com/behase/relumin/exception/ApiException.java
// public class ApiException extends RuntimeException {
//     private static final long serialVersionUID = 3285456520279227122L;
// 
//     @Getter
//     @Setter
//     private ErrorResponse errorResponse;
// 
//     @Getter
//     @Setter
//     private HttpStatus httpStatus;
// 
//     public ApiException(ErrorResponse errorResponse, HttpStatus httpStatus) {
//         super(errorResponse.getError().getMessage());
//         this.errorResponse = errorResponse;
//         this.httpStatus = httpStatus;
//     }
// 
//     public ApiException(String code, String message, HttpStatus httpStatus) {
//         super(message);
//         this.errorResponse = new ErrorResponse(code, message);
//         this.httpStatus = httpStatus;
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/exception/InvalidParameterException.java
// public class InvalidParameterException extends ApiException {
//     private static final long serialVersionUID = -6416726302671334601L;
// 
//     public InvalidParameterException(String message) {
//         super(Constants.ERR_CODE_INVALID_PARAMETER, String.format("Invalid parameter. %s", message), HttpStatus.BAD_REQUEST);
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/model/ClusterNode.java
// @Data
// @Builder
// @NoArgsConstructor
// @AllArgsConstructor
// public class ClusterNode {
//     private String nodeId;
//     private String hostAndPort;
//     private Set<String> flags = Sets.newLinkedHashSet();
//     private String masterNodeId;
//     private long pingSent;
//     private long pongReceived;
//     private long configEpoch;
//     private boolean connect;
//     private Map<Integer, String> migrating = Maps.newLinkedHashMap();
//     private Map<Integer, String> importing = Maps.newLinkedHashMap();
// 
//     @JsonIgnore
//     private Set<Integer> servedSlotsSet = Sets.newTreeSet();
// 
//     public boolean hasFlag(String flag) {
//         if (flags == null || flags.isEmpty()) {
//             return false;
//         }
//         return flags.contains(flag);
//     }
// 
//     public String getServedSlots() {
//         return new JedisSupport().slotsDisplay(servedSlotsSet);
//     }
// 
//     public int getSlotCount() {
//         if (servedSlotsSet == null) {
//             return 0;
//         }
//         return servedSlotsSet.size();
//     }
// 
//     @JsonIgnore
//     public String getHost() {
//         return StringUtils.split(hostAndPort, ":")[0];
//     }
// 
//     @JsonIgnore
//     public int getPort() {
//         return Integer.valueOf(StringUtils.split(hostAndPort, ":")[1]);
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
// 
//         ClusterNode other = (ClusterNode) obj;
//         return StringUtils.equalsIgnoreCase(nodeId, other.nodeId);
//     }
// }
// 
// Path: src/main/java/com/behase/relumin/model/param/CreateClusterParam.java
// @Data
// @Builder
// @NoArgsConstructor
// @AllArgsConstructor
// public class CreateClusterParam {
//     private String startSlotNumber;
//     private String endSlotNumber;
//     private String master;
//     private List<String> replicas = Lists.newArrayList();
// 
//     @JsonIgnore
//     private String masterNodeId;
// }


// Path: src/test/java/com/behase/relumin/support/RedisTribTest.java
import com.behase.relumin.exception.ApiException;
import com.behase.relumin.exception.InvalidParameterException;
import com.behase.relumin.model.ClusterNode;
import com.behase.relumin.model.param.CreateClusterParam;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.internal.util.reflection.Whitebox;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.boot.test.OutputCapture;
import redis.clients.jedis.Jedis;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anySet;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyList;
import static org.mockito.Mockito.*;


        doReturn(jedis).when(mock2).getJedis();
        doReturn(jedis).when(mock3).getJedis();

        doReturn(true).when(mock1).hasFlag("slave");
        doReturn(jedis).when(mock2).getJedis();
        doReturn(jedis).when(mock3).getJedis();
        doReturn(1l).doReturn(2l).when(jedis).clusterCountKeysInSlot(anyInt());

        // when
        TribClusterNode result = tested.getNodeWithMostKeysInSlot(Lists.newArrayList(mock1, mock2, mock3), 0);

        // then
        assertThat(result, is(mock3));
    }

    @Test
    public void fixOpenSlot_owner_node_is_null_then_throw() {
        expectedEx.expect(ApiException.class);
        expectedEx.expectMessage(containsString("Fix me, some work to do here"));

        // given
        doReturn(null).when(tested).getSlotOwner(anyInt());

        // then
        tested.fixOpenSlot(0);
    }

    @Test
    public void fixOpenSlot_else_case() {
        expectedEx.expect(ApiException.class);