Welcome to TimeMachine

TimeMachine is a library for simulation of the passage of time. It can be easily used in your unit and acceptance tests.

Why?

Often we are faced with a problem of how to test a passage of time in a system. We want to see what happens after a minute, a month or a year has elapsed.

The most common solution used is a Virtual Clock pattern, but there are a few fundamental problems connected with using it, namely:

  1. We have to modify the application code to use some kind of service which would be a single source of current time.
  2. Legacy code or the code, which we are not able to modify (external commercial libraries, etc.), is difficult (or sometimes impossible) to change so that it uses our Virtual Clock service.
  3. The code which uses Thread.sleep() or Object.wait() methods will not work properly.

Therefore TimeMachine has been created. It has none of the above-mentioned problems. And at the same time is easy to use.

How?

TimeMachine works as a Java agent which provides it's own implementation of the methods which are sensitive to the passage of time. Namely the following method implementations are provided:

  • java.lang.Object.wait (long)
  • java.lang.Object.wait (long, int)
  • java.lang.System.currentTimeMillis ()
  • java.lang.System.nanoTime ()
  • java.lang.Thread.sleep (long)
  • java.lang.Thread.sleep (long, int)

The TimeMachine Java agent modifies the bytecode of the classes as they are being loaded, replacing original method call with it's implementation. In your test code you can easily move forward in time by calling the TimeMachine.goToTheFuture (long) method. Below you can see some examples.

  • Example 1

    This example shows the usage of the Date class, which uses underneath the System.currentTimeMillis() method.

    import java.util.Date;
    
    import org.javart.timemachine.TimeMachine;
    
    ...
    
    Date startDate = new Date ();
    
    TimeMachine.gotoTheFuture (24*60*60*1000);
    
    Date currentDate = new Date ();
    System.out.println ("The difference is " + (currentDate.getTime () - startDate.getTime ())/(60*60*1000) + " hours"):
    // The above line will print "The difference is 24 hours" 
    
  • Example 2

    This example shows how the TimeMachine affects the Thread.sleep method.

    // Thread 1                                                      // Thread 2
    import org.javart.timemachine.TimeMachine;                       import org.javart.timemachine.TimeMachine;
    ...                                                              ...
                                                                                                                                      
    Thread.sleep (24*60*60*1000);                                    TimeMachine.goToTheFuture (24*60*60*1000);                       
    System.out.println ("I have slept enough");                                                                                        |
    TimeMachine.goToTheFuture (12*60*60*1000)                        Thread.sleep (10*60*80*1000);                                    
                                                                     System.out.println ("I have slept well too");
                                                                                         
    // The "I have slept enough" message should be printed first     
                                                                     // The "I have slept well too" message should be printed second
                                                                              
    // The whole test should not last longer than a few milliseconds                                                                  
    
  • Example 3

    This example shows the usage of java.util.Timer together with TimeMachine. If you looked deeply inside the java.util.Timer implementation you would see that it uses Object.wait methods underneath.

    import java.util.Timer;
    
    import org.javart.timemachine.TimeMachine;
    
    ...
    
    final long[] counter = new long[1];
    
    Timer timer = new Timer (true);
    timer.schedule (new TimerTask () {
            public void run ()
            {
                    counter[0]++;
            }
    }, 60 * 60 * 1000); // invoke in one hour
    
    TimeMachine.goToTheFuture (60 * 60 * 1000);
    
    Thread.sleep (1000); // allow some time to let the run() method run
    
    if (counter[0] == 1) {
            System.out.println ("An hour has passed!");
    }
    
    // The whole test should not last longer than two seconds and it should print "An hour has passed".
    

Where?

TimeMachine is available at this site. You can either read more about it, read a FAQ or go directly to the download page.