@Timestamp is not set to future when using SagaTestFixture.whenTimeElapses() for eventScheduler testing

Hi,

I have encountered an issue when testing saga with SagaTestFixture.
When using time shifts via whenTimeElapses() or andThenTimeElapses(), to test scheduled events, I noticed that the @Timestamp timestamps are not set to the future time.
To depict the issue above, please find below example saga with failing test.

Thanks a lot for help.
Best regards,
Przemek

Saga:

@Saga
public class TestSaga {

    @Setter(onMethod = @__(@Autowired))
    private transient EventScheduler eventScheduler;

    @Autowired
    private transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "id")
    public void startSaga(final Event event, @Timestamp Instant eventTimestamp) {
        Instant triggerTime = eventTimestamp.plus(Duration.ofMinutes(30));
        this.eventScheduler.schedule(triggerTime, new ScheduledEvent(event.getId()));
    }

    @SagaEventHandler(associationProperty = "id")
    public void handle(final ScheduledEvent event, @Timestamp Instant eventTimestamp) {
        commandGateway.send(new TestCommand(event.getId(), eventTimestamp));
    }

}

@Value
class TestCommand {
    String id;
    Instant timestamp;
}

@Value
class Event {
    String id;
}

@Value
class ScheduledEvent {
    String id;
}

Test:

@RunWith(SpringRunner.class)
public class TestSagaTest {

    private SagaTestFixture<TestSaga> fixture;

    @Before
    public void setup() {
        fixture = new SagaTestFixture<>(TestSaga.class);
    }

    @Test
    public void should() {

        String id = "id";

        Instant time = fixture.currentTime().plus(Duration.ofMinutes(60));

        fixture.givenAggregate(id)
                .published(new Event(id))
                .whenTimeElapses(Duration.ofMinutes(60))
                .expectDispatchedCommands(new TestCommand(id, time));
    }

}

Hi Przemek,

you haven’t set the initial time of the test. In that case, it will assume the timestamp at which the fixture is created. While it’s close, it’s not exactly the same moment as your “time” variable.
If you want to set the current time to your “time” variable, use:
fixture.givenCurrentTime(time).andThenAggregate(id).published(new Event(id)…

Hope this helps.
Cheers,

Allard

Hello Allard,

Thanks for point that thing out that time mismatch. Im sorry for not being clear enough. What Im trying to point out / ask about, is that the @Timestamp received on handling event published by EventScheduler is not either properly shifted in future nor it is taking into the consideration the fixture.givenCurrentTime. I have added explicit point in time so we can refer to the same times.
Given the snippet below, flow I would anticipate to see would be:

  1. Event is handled with @Timestamp 2018-01-01T00:00:00Z

  2. It is scheduling sending Scheduled**Event for 2018-01-01T00:30:00Z
    3) When we rewind the time with whenTimeElapses() with 60 minutes, the scheduler is publishing the Scheduled**Event, but it is handled with @Timestamp 2018-10-26T13:19:07.233664Z (My local current date :D),
    and I would suspect it would be set to the 2018-01-01T00:30:00Z.

Thanks again for such quick response.
Best regards,
Przemek

Test:

@Test
public void should() throws ParseException {
    String id = "id";

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Instant referenceTime = dateFormat.parse("2018-01-01T10:00:00").toInstant();

    Instant time = referenceTime.plus(Duration.ofMinutes(30));

    fixture.givenCurrentTime(referenceTime)
            .andThenAggregate(id)
            .published(new Event(id))
            .whenTimeElapses(Duration.ofMinutes(60))
            .expectDispatchedCommands(new TestCommand(id, time));
}

Saga:

@Saga
public class TestSaga {

    @Setter(onMethod = @__(@Autowired))
    private transient EventScheduler eventScheduler;

    @Autowired
    private transient CommandGateway commandGateway;

    @StartSaga
    @SagaEventHandler(associationProperty = "id")
    public void startSaga(final Event event, @Timestamp Instant eventTimestamp) {
        Instant triggerTime = eventTimestamp.plus(Duration.ofMinutes(30));
        this.eventScheduler.schedule(triggerTime, new ScheduledEvent(event.getId()));
    }

    @SagaEventHandler(associationProperty = "id")
    public void handle(final ScheduledEvent event, @Timestamp Instant eventTimestamp) {
        commandGateway.send(new TestCommand(event.getId(), eventTimestamp));
    }

}

@Value
class TestCommand {
    String id;
    Instant timestamp;
}

@Value
class Event {
    String id;
}

@Value
class ScheduledEvent {
    String id;
}

Thanks for the clarification! It looks like the stub scheduler isn’t modifying the timestamp correctly. We’ll look into it.

Cheers,
Allard

Hi Allard,

If possible, when you have time to look into it, and if an issue would to be created, please post it here, so that I can track the progress.

Thanks in advance,
Przemek

Hi,

I just created the issue: https://github.com/AxonFramework/AxonFramework/issues/882
It should be a fairly simple fix, so I expect it to be released as part of 4.0.1, which we expect to release this week.

Cheers,

Allard