You can have the communication channels between components under the control of the simulation environment rather than have them happen in their 'normal' manner. This allows you to inject latency between components, 'fiddle' with the inputs/outputs as suggested as well as record messaging (assuming you're working with systems that exchange messages/events) with appropriate event times.
Another important point around clocks is that you'll want to include a scheduling API in your clock components to be able to schedule events for themselves in the future. If you start moving to event-time then being able to fast-forward in time is another advantage.
Overall it's worth considering the class of issue you're trying to detect with this approach. It's great to be able to run things in event time, debug ad-nauseam but you're not going to catch race conditions without the smarts mentioned around native scheduling.
There are some parallels as well between this style of testing and production replication, so that's good to have at the back of your mind if you're looking to collect production telemetry/ingress + egress data. If you build a good system for this type of testing producing reproduceable code will be part of your development process and you're more likely to be able to produce tooling for investigation/reproduction of production issues.
(The context in which I do work that's kind of in this area is robust backtesting of trading systems)