### Question:
Sequence { public SequenceNumber nextSequenceNumber() { synchronized (lock) { final long tick = updateCounter(); return new SequenceNumber(tick, sequenceToByteArray()); } } Sequence(final SequenceConfig config); SequenceNumber nextSequenceNumber();  }### Answer:
@Test public void nextSequenceNumberShouldIncreaseSequenceNumberLinearly() { final Sequence provider = new Sequence(useDefaults(65536)); final Map<Long, List<SequenceNumber>> groupedByTick = Stream.iterate(0, i -> i + 1) .limit(100) .map(i -> provider.nextSequenceNumber()) .collect(Collectors.groupingBy(SequenceNumber::getTimestamp)); assertFalse(groupedByTick.isEmpty()); for (Long tick : groupedByTick.keySet()) { final List<SequenceNumber> numbers = groupedByTick.get(tick); assertFalse(numbers.isEmpty()); int expectedSequenceNumber = 0; for (SequenceNumber number : numbers) { assertThat(number.getSequenceNumber(), is(toByteArray(expectedSequenceNumber))); expectedSequenceNumber++; } } }
@Test(expected = OutOfSequenceNumbersException.class) public void nextSequenceNumberShouldThrowOutOfSequenceNumbersExceptionIfPoolIsExhausted() { final SequenceConfig config = create(1) .withMaxWaitTime(0, TimeUnit.MILLISECONDS) .build(); final Sequence provider = new Sequence(config); provider.nextSequenceNumber(); provider.nextSequenceNumber(); provider.nextSequenceNumber(); provider.nextSequenceNumber(); }
@Test(expected = BackwardsClockDriftException.class) public void nextSequenceNumberShouldThrowBackwardsClockDriftExceptionIfDriftIsDetected() { final SequenceConfig config = SequenceConfig.create(65536) .withTimeProvider(new DriftingTimeProvider()) .build(); final Sequence provider = new Sequence(config); provider.nextSequenceNumber(); provider.nextSequenceNumber(); }