TSReadParamsTest.java
package redis.clients.jedis.timeseries;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static redis.clients.jedis.timeseries.TimeSeriesProtocol.DOLLAR;
import static redis.clients.jedis.timeseries.TimeSeriesProtocol.MINUS;
import static redis.clients.jedis.timeseries.TimeSeriesProtocol.PLUS;
import static redis.clients.jedis.timeseries.TimeSeriesProtocol.TimeSeriesKeyword.BLOCK;
import static redis.clients.jedis.timeseries.TimeSeriesProtocol.TimeSeriesKeyword.MAX_COUNT;
import static redis.clients.jedis.util.CommandArgumentsMatchers.hasArgumentCount;
import static redis.clients.jedis.util.CommandArgumentsMatchers.hasArguments;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.CommandArguments;
import redis.clients.jedis.args.RawableFactory;
import redis.clients.jedis.timeseries.TimeSeriesProtocol.TimeSeriesCommand;
public class TSReadParamsTest {
private static CommandArguments args() {
return new CommandArguments(TimeSeriesCommand.READ);
}
@Nested
class ValidationTests {
@Test
public void negativeBlockMillisecondsThrowsException() {
assertThrows(IllegalArgumentException.class, () -> TSReadParams.readParams().block(-1L, 1));
}
@Test
public void zeroBlockMillisecondsIsAllowed() {
// BLOCK 0 means "wait indefinitely" and must be supported.
assertTrue(TSReadParams.readParams().block(0L, 1).isBlocking());
}
@Test
public void nonPositiveBlockMinCountThrowsException() {
assertThrows(IllegalArgumentException.class, () -> TSReadParams.readParams().block(1000L, 0));
assertThrows(IllegalArgumentException.class,
() -> TSReadParams.readParams().block(1000L, -3));
}
@Test
public void nonPositiveMaxCountThrowsException() {
assertThrows(IllegalArgumentException.class, () -> TSReadParams.readParams().maxCount(0));
assertThrows(IllegalArgumentException.class, () -> TSReadParams.readParams().maxCount(-2));
}
@Test
public void minCountGreaterThanMaxCountThrowsAtSerialization() {
TSReadParams params = TSReadParams.readParams().block(1000L, 5).maxCount(2);
assertThrows(IllegalArgumentException.class, () -> params.addParams(args()));
}
}
@Nested
class BlockingClassificationTests {
@Test
public void notBlockingByDefault() {
assertFalse(TSReadParams.readParams().isBlocking());
assertFalse(TSReadParams.readParams().timestamp(100L).maxCount(10).isBlocking());
}
@Test
public void blockingWhenBlockGroupPresent() {
assertTrue(TSReadParams.readParams().block(1000L, 1).isBlocking());
}
}
@Nested
class AddParamsTests {
@Test
public void defaultsToEarliestCursor() {
TSReadParams params = TSReadParams.readParams();
CommandArguments args = args();
params.addParams(args);
// Expected: TS.READ -
assertThat(args, hasArgumentCount(2));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(MINUS)));
}
@Test
public void literalCursorZeroIsEmitted() {
TSReadParams params = TSReadParams.readParams().timestamp(0L);
CommandArguments args = args();
params.addParams(args);
// Expected: TS.READ 0
assertThat(args, hasArgumentCount(2));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(0L)));
}
@Test
public void latestSentinel() {
CommandArguments args = args();
TSReadParams.readParams().latest().addParams(args);
// Expected: TS.READ +
assertThat(args, hasArgumentCount(2));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(PLUS)));
}
@Test
public void newSamplesSentinel() {
CommandArguments args = args();
TSReadParams.readParams().newSamples().addParams(args);
// Expected: TS.READ $
assertThat(args, hasArgumentCount(2));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(DOLLAR)));
}
@Test
public void blockGroupEmitsKeywordAndBothValues() {
CommandArguments args = args();
TSReadParams.readParams().timestamp(101L).block(1000L, 10).addParams(args);
// Expected: TS.READ 101 BLOCK 1000 10
assertThat(args, hasArgumentCount(5));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(101L), BLOCK,
RawableFactory.from(1000L), RawableFactory.from(10L)));
}
@Test
public void maxCountEmitsKeywordAndValue() {
CommandArguments args = args();
TSReadParams.readParams().timestamp(200L).maxCount(2).addParams(args);
// Expected: TS.READ 200 MAX_COUNT 2
assertThat(args, hasArgumentCount(4));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(200L), MAX_COUNT,
RawableFactory.from(2L)));
}
@Test
public void canonicalOrderBlockBeforeMaxCount() {
CommandArguments args = args();
TSReadParams.readParams().newSamples().block(5000L, 1).maxCount(100).addParams(args);
// Expected: TS.READ $ BLOCK 5000 1 MAX_COUNT 100
assertThat(args, hasArgumentCount(7));
assertThat(args, hasArguments(TimeSeriesCommand.READ, RawableFactory.from(DOLLAR), BLOCK,
RawableFactory.from(5000L), RawableFactory.from(1L), MAX_COUNT, RawableFactory.from(100L)));
}
}
@Nested
class EqualsHashCodeTests {
@Test
public void equalWhenSameConfiguration() {
TSReadParams a = TSReadParams.readParams().timestamp(100L).block(1000L, 5).maxCount(10);
TSReadParams b = TSReadParams.readParams().timestamp(100L).block(1000L, 5).maxCount(10);
assertEquals(a, b);
assertEquals(a.hashCode(), b.hashCode());
}
@Test
public void notEqualWhenCursorDiffers() {
assertNotEquals(TSReadParams.readParams().timestamp(100L),
TSReadParams.readParams().timestamp(200L));
assertNotEquals(TSReadParams.readParams().earliest(), TSReadParams.readParams().latest());
}
@Test
public void notEqualWhenBlockDiffers() {
assertNotEquals(TSReadParams.readParams().block(1000L, 1),
TSReadParams.readParams().block(2000L, 1));
}
}
}