Mykhaylo Adamovych
Mykhaylo Adamovych

Reputation: 20966

Suspend test execution until application becomes idle

Is it feasible to implement some util method to suspend test (current thread) execution until application becomes idle?
Idle means:
1. there were no GUI events added to event queue for some period of time
2. there were no worker threads running any tasks for the same period of time.
Could you please provide implementation/code snippets to track previous conditions of idleness?

Upvotes: 1

Views: 620

Answers (2)

trashgod
trashgod

Reputation: 205805

You can replace the EventQueue with your own implementation, as shown here. The variation below adds an idle() method that relies on an arbitrary THRESHOLD of 1000 ms.

import java.awt.AWTEvent;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JTree;

/**
 * @see https://stackoverflow.com/questions/7976967
 * @see https://stackoverflow.com/questions/3158254
 */
public class EventQueueTest {

    public static void main(String[] args) throws
            InterruptedException, InvocationTargetException {
        EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
        final MyEventQueue q = new MyEventQueue();
        eventQueue.push(q);

        EventQueue.invokeAndWait(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("Test");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new JTree());
                f.pack();
                f.setVisible(true);
            }
        });
        // Test idle() on initial thread
        for (int i = 0; i < 10; i++) {
            Thread.sleep(2 * MyEventQueue.THRESHOLD);
            System.out.println("Idle: " + q.idle());
        }
    }

    private static class MyEventQueue extends EventQueue {

        private static final int THRESHOLD = 1 * 1000;
        private long last;

        @Override
        public void postEvent(AWTEvent e) {
            super.postEvent(e);
            last = System.currentTimeMillis();
        }

        public boolean idle() {
            return System.currentTimeMillis() - last > THRESHOLD;
        }
    }
}

Upvotes: 2

AlexR
AlexR

Reputation: 115358

You can use Toolkit.getDefaultToolkit().addAWTEventListener(listener, eventMask) to subscribe to AWT event queue, so you can detect whether events are not added for some period of time.

I think that you need your custom code to monitor working threads, i.e. something in the beginning and end of run() method.

The problem is to "suspend the test execution". If your test is running in thread theoretically you can invoke the thread's suspend() method. But it is deprecated and should not be used. To perform clear implementation you should make your custom code that asks status during execution of the thread and calls wait() once it detects that the test must be suspended. When your code that monitors AWT event queue and working threads decides that test may be resumed it should call appropriate notify().

Probably better solution from design point of view is Actors model. There are several java framework that provide this functionality.

Upvotes: 1

Related Questions