Path: blob/master/test/jdk/java/awt/EventQueue/6980209/bug6980209.java
41154 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @key headful26* @bug 698020927* @summary Make tracking SecondaryLoop.enter/exit methods easier28* @author Semyon Sadetsky29*/3031import javax.swing.*;32import java.awt.*;33import java.awt.event.*;34import java.awt.event.ActionEvent;35import java.awt.event.ActionListener;36import java.awt.event.KeyEvent;37import java.awt.event.KeyListener;38import java.util.logging.Logger;3940public class bug6980209 implements ActionListener {41private final static Logger log =42Logger.getLogger("java.awt.event.WaitDispatchSupport");43public static final int ATTEMPTS = 100;44public static final int EVENTS = 5;4546private static boolean runInEDT;47private static JFrame frame;48private static int disorderCounter = 0;49private static Boolean enterReturn;50private static Boolean exitReturn;51private static int dispatchedEvents;52private static JButton button;53private static Point point;5455public static void main(String[] args) throws Exception {56System.out.println(57"PLEASE DO NOT TOUCH KEYBOARD AND MOUSE DURING THE TEST RUN!");58// log.setLevel(java.util.logging.Level.FINE);59// log.setLevel(java.util.logging.Level.FINEST);60try {61SwingUtilities.invokeAndWait(new Runnable() {62public void run() {63frame = new JFrame();64frame.setUndecorated(true);65setup(frame);66}67});68final Robot robot = new Robot();69robot.delay(100);70robot.waitForIdle();71robot.setAutoDelay(10);72robot.setAutoWaitForIdle(true);73SwingUtilities.invokeAndWait(new Runnable() {74@Override75public void run() {76point = button.getLocationOnScreen();77}78});79robot.mouseMove( point.x + 5, point.y + 5 );80robot.mousePress(InputEvent.BUTTON1_MASK);81robot.mouseRelease(InputEvent.BUTTON1_MASK);82robot.delay(100);83robot.waitForIdle();8485testExitBeforeEnter();86System.out.println("Run random test in EDT");87runInEDT = true;88testRandomly();89System.out.println("Run random test in another thread");90runInEDT = false;91testRandomly();92System.out.println("ok");9394} finally {95SwingUtilities.invokeAndWait(new Runnable() {96@Override97public void run() {98frame.dispose();99}100});101}102}103104private static void testExitBeforeEnter() throws Exception {105final SecondaryLoop loop =106Toolkit.getDefaultToolkit().getSystemEventQueue()107.createSecondaryLoop();108loop.exit();109Robot robot = new Robot();110robot.mouseWheel(1);111robot.waitForIdle();112SwingUtilities.invokeAndWait(new Runnable() {113@Override114public void run() {115if(loop.enter()) {116throw new RuntimeException("Wrong enter() return value");117}118}119});120}121122private static void testRandomly() throws AWTException {123disorderCounter = 0;124final Robot robot = new Robot();125robot.setAutoDelay(1);126for (int i = 0; i < ATTEMPTS; i++) {127enterReturn = null;128exitReturn = null;129dispatchedEvents = 0;130synchronized (bug6980209.class) {131try {132for (int j = 0; j < EVENTS; j++) {133robot.keyPress(KeyEvent.VK_1);134robot.keyRelease(KeyEvent.VK_1);135}136137// trigger the button action that starts secondary loop138robot.keyPress(KeyEvent.VK_SPACE);139robot.keyRelease(KeyEvent.VK_SPACE);140141for (int j = 0; j < EVENTS; j++) {142robot.keyPress(KeyEvent.VK_1);143robot.keyRelease(KeyEvent.VK_1);144}145long time = System.nanoTime();146// wait for enter() returns147bug6980209.class.wait(1000);148if (enterReturn == null) {149System.out.println("wait time=" +150((System.nanoTime() - time) / 1E9) +151" seconds");152throw new RuntimeException(153"It seems the secondary loop will never end");154}155if (!enterReturn) disorderCounter++;156157robot.waitForIdle();158if (dispatchedEvents <1592 * EVENTS) { //check that all events are dispatched160throw new RuntimeException(161"KeyEvent.VK_1 has been lost!");162}163164} catch (InterruptedException e) {165throw new RuntimeException("Interrupted!");166}167}168}169if (disorderCounter == 0) {170System.out.println(171"Zero disordered enter/exit caught. It is recommended to run scenario again");172} else {173System.out.println(174"Disordered calls is " + disorderCounter + " from " +175ATTEMPTS);176}177}178179private static void setup(final JFrame frame) {180button = new JButton("Button");181frame.getContentPane().add(button);182button.addActionListener(new bug6980209());183frame.pack();184frame.setVisible(true);185button.setFocusable(true);186button.requestFocus();187button.addKeyListener(new KeyListener() {188@Override189public void keyTyped(KeyEvent e) {190}191192@Override193public void keyPressed(KeyEvent e) {194if (e.getKeyChar() == '1') dispatchedEvents++;195}196197@Override198public void keyReleased(KeyEvent e) {199if (e.getKeyChar() == '1') dispatchedEvents++;200}201});202}203204205@Override206public void actionPerformed(ActionEvent e) {207if (runInEDT) {208runSecondaryLoop();209return;210}211new Thread("Secondary loop run thread") {212@Override213public void run() {214runSecondaryLoop();215}216}.start();217}218219private static void runSecondaryLoop() {220log.fine("\n---TEST START---");221222final SecondaryLoop loop =223Toolkit.getDefaultToolkit().getSystemEventQueue()224.createSecondaryLoop();225226final Object LOCK = new Object(); //lock to start simultaneously227Thread exitThread = new Thread("Exit thread") {228@Override229public void run() {230synchronized (LOCK) {231LOCK.notify();232}233Thread.yield();234exitReturn = loop.exit();235log.fine("exit() returns " + exitReturn);236}237};238239synchronized (LOCK) {240try {241exitThread.start();242LOCK.wait();243} catch (InterruptedException e1) {244throw new RuntimeException("What?");245}246}247248enterReturn = loop.enter();249log.fine("enter() returns " + enterReturn);250251try {252exitThread.join();253} catch (InterruptedException e) {254throw new RuntimeException("What?");255}256synchronized (bug6980209.class) {257bug6980209.class.notifyAll();258}259log.fine("\n---TEST END---");260}261}262263264