

package org.apache.geode.redis.internal.services;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.services.locking.LockingStripedCoordinator;
import org.apache.geode.redis.internal.services.locking.StripedCoordinator;

public class LockingStripedCoordinatorTest {

  @Test
  public void handleMinNegativeHashCode() {
    Hashy hashy = new Hashy(Integer.MIN_VALUE);

    StripedCoordinator executor = new LockingStripedCoordinator();
    String result = executor.execute(hashy, () -> "OK");
    assertThat(result).isEqualTo("OK");
  }

  @Test
  public void handleMaxPositiveHashCode() {
    Hashy hashy = new Hashy(Integer.MAX_VALUE);

    StripedCoordinator executor = new LockingStripedCoordinator();
    String result = executor.execute(hashy, () -> "OK");
    assertThat(result).isEqualTo("OK");
  }

  @Test
  public void handleStripeCollisionsForSameExecution() {
    List<RedisKey> keys = new ArrayList<>();
    keys.add(new Hashy(1));
    keys.add(new Hashy(2));
    keys.add(new Hashy(3));

    StripedCoordinator coordinator = new LockingStripedCoordinator(1);

    assertThat(coordinator.execute(keys, () -> "OK"))
        .isEqualTo("OK");
  }

  private static class Hashy extends RedisKey {
    private final int hashcode;

    public Hashy(int hashcode) {
      this.hashcode = hashcode;
    }

    @Override
    public int hashCode() {
      return hashcode;
    }
  }
}
