Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulating "faster time" in linux

I have a Java app that runs on linux that has a lots of events and business logic that revolve around times and dates.

For testing, is it possible to tweak something into time going faster. Let's say, make a whole computer-year finish in one hour wall time?

like image 920
flybywire Avatar asked Mar 08 '09 19:03

flybywire


3 Answers

You can write a wrapper interface for your time/date calls. Have one real implementation that does real system calls, and a test implementation that can do whatever you want (run faster, slower, fake dates, etc).

like image 178
patros Avatar answered Oct 21 '22 13:10

patros


One approach that works best for unit testing is to abstract the way the current time is accessed in your code.

Instead of calling System.currentTimeMillis() directly you can provide your own implementation.

Something like this (pseudo-code):

class MyTime {
   private static TimeInterface CurrentTimeInterface = new DefaultTimeImpl();

   public setTimeInterface(TimeInterface timeInterface) {
      CurrentTimeInterface = timeInterface;
   }

   public int getTime() { CurrentTimeInterface.getTime(); }

}

class DefaultTimeImpl implements TimeInterface {
   public int getTime() { return System.currentTimeMillis(); }
}

class TestTimeImpl implements TimeInterface {
   private int CurrentTimeMillis = 0;
   public int getTime() { return CurrentTimeMillis; }
   public void setTime(int timeMillis) { CurrentTimeMillis = timeMillis}
   public void sleep(int millis) { CurrentTimeMillis += millis; }
}

Then, everywhere you would have called System.getTimeMillis() instead call MyTime.getTime(). When you're testing your code simply create a TestTimeImpl and call MyTime.setTimeInterface(testTimeImpl). Then when you want time to advance call testTimeImpl.sleep() or testTimeImpl.setTime().

This allows you to simulate any time down to the millisecond.

like image 39
Tom Hennen Avatar answered Oct 21 '22 14:10

Tom Hennen


If you are system calls to get the system time (i.e. System.currentTimeMillis()), presumably, you can speed up time by changing the system time. This should reflect on the time you see in your application.

If you are using other ways to calculate time (elapsed time from JVM start (i.e. System.nanoTime()), net time servers, etc...) then the answer is that it is not possible.


I can't stress enough that I am just explaining how to do what you asked, and this is good only for integration testing, when you take into considerations anything else you are affecting on said machine.

This should not come as a replacement whatsoever for proper and extensive unit-testing.

like image 2
Yuval Adam Avatar answered Oct 21 '22 15:10

Yuval Adam