From 9c86ac27236a67ff7d84447821d89772b993f7e1 Mon Sep 17 00:00:00 2001
From: Tejesh R
Date: Sun, 27 Apr 2025 11:44:40 +0000
Subject: [PATCH] 8354495: Open source several AWT DataTransfer tests
Reviewed-by: azvegint
---
test/jdk/ProblemList.txt | 3 +
.../ClipboardPerformanceTest.java | 133 +++++++++++++
.../HTMLTransferConsoleOutputTest.java | 182 ++++++++++++++++++
.../datatransfer/ImageTransferCrashTest.java | 147 ++++++++++++++
4 files changed, 465 insertions(+)
create mode 100644 test/jdk/java/awt/datatransfer/ClipboardPerformanceTest.java
create mode 100644 test/jdk/java/awt/datatransfer/HTMLTransferConsoleOutputTest.java
create mode 100644 test/jdk/java/awt/datatransfer/ImageTransferCrashTest.java
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index b6307d1ed00..c17d8dbe559 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -189,6 +189,9 @@ java/awt/Mouse/EnterExitEvents/DragWindowTest.java 8298823 macosx-all
java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all
java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all
java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all
+java/awt/datatransfer/ClipboardPerformanceTest.java 8029022 windows-all
+java/awt/datatransfer/HTMLTransferConsoleOutputTest.java 8237254 macosx-all
+java/awt/datatransfer/ImageTransferCrashTest.java 8237253 macosx-all
java/awt/Toolkit/RealSync/Test.java 6849383 linux-all
java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all
java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8072110 macosx-all
diff --git a/test/jdk/java/awt/datatransfer/ClipboardPerformanceTest.java b/test/jdk/java/awt/datatransfer/ClipboardPerformanceTest.java
new file mode 100644
index 00000000000..3bad044b949
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/ClipboardPerformanceTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4463560
+ * @requires (os.family == "windows")
+ * @summary Tests that datatransfer doesn't take too much time to complete
+ * @key headful
+ * @library /test/lib
+ * @run main/timeout=300 ClipboardPerformanceTest
+ */
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class ClipboardPerformanceTest {
+ public static final int CODE_FAILURE = 1;
+ public static final int CODE_OTHER_FAILURE = 2;
+ static String eoln;
+ static char[] text;
+ public static final int ARRAY_SIZE = 100000;
+ public static final int RATIO_THRESHOLD = 10;
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ ClipboardPerformanceTest clipboardPerformanceTest = new ClipboardPerformanceTest();
+ clipboardPerformanceTest.initialize();
+ return;
+ }
+
+ long before, after, oldTime, newTime;
+ float ratio;
+
+ try {
+ Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
+ before = System.currentTimeMillis();
+ String ss = (String) t.getTransferData(new DataFlavor("text/plain; class=java.lang.String"));
+ after = System.currentTimeMillis();
+
+ System.err.println("Size: " + ss.length());
+ newTime = after - before;
+ System.err.println("Time consumed: " + newTime);
+
+ initArray();
+
+ StringBuffer buf = new StringBuffer(new String(text));
+ int eoln_len = eoln.length();
+ before = System.currentTimeMillis();
+
+ for (int i = 0; i + eoln_len <= buf.length(); i++) {
+ if (eoln.equals(buf.substring(i, i + eoln_len))) {
+ buf.replace(i, i + eoln_len, "\n");
+ }
+ }
+
+ after = System.currentTimeMillis();
+ oldTime = after - before;
+ System.err.println("Old algorithm: " + oldTime);
+ ratio = oldTime / newTime;
+ System.err.println("Ratio: " + ratio);
+
+ if (ratio < RATIO_THRESHOLD) {
+ System.out.println("Time ratio failure!!");
+ System.exit(CODE_FAILURE);
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ System.exit(CODE_OTHER_FAILURE);
+ }
+ System.out.println("Test Pass!");
+ }
+
+ public static void initArray() {
+ text = new char[ARRAY_SIZE + 2];
+
+ for (int i = 0; i < ARRAY_SIZE; i += 3) {
+ text[i] = '\r';
+ text[i + 1] = '\n';
+ text[i + 2] = 'a';
+ }
+ eoln = "\r\n";
+ }
+
+ public void initialize() throws Exception {
+ initArray();
+ Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+ cb.setContents(new StringSelection(new String(text)), null);
+
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ ClipboardPerformanceTest.class.getName(),
+ "child"
+ );
+
+ Process process = ProcessTools.startProcess("Child", pb);
+ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process);
+
+ if (!process.waitFor(15, TimeUnit.SECONDS)) {
+ process.destroyForcibly();
+ throw new TimeoutException("Timed out waiting for Child");
+ }
+
+ outputAnalyzer.shouldHaveExitValue(0);
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/HTMLTransferConsoleOutputTest.java b/test/jdk/java/awt/datatransfer/HTMLTransferConsoleOutputTest.java
new file mode 100644
index 00000000000..6a18a11270f
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/HTMLTransferConsoleOutputTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4638351
+ * @summary tests that HTML transfer doesn't cause console output
+ * @key headful
+ * @library /test/lib
+ * @run main HTMLTransferConsoleOutputTest
+ */
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class HTMLTransferConsoleOutputTest implements ClipboardOwner {
+ static final Clipboard clipboard =
+ Toolkit.getDefaultToolkit().getSystemClipboard();
+ static final DataFlavor dataFlavor =
+ new DataFlavor("text/html; class=java.lang.String", null);
+ static final String magic = "TESTMAGICSTRING";
+ static final Transferable transferable = new Transferable() {
+ final DataFlavor[] flavors = new DataFlavor[]{dataFlavor};
+ final String data = "" + magic + "";
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return flavors;
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor df) {
+ return dataFlavor.equals(df);
+ }
+
+ public Object getTransferData(DataFlavor df)
+ throws UnsupportedFlavorException {
+ if (!isDataFlavorSupported(df)) {
+ throw new UnsupportedFlavorException(df);
+ }
+ return data;
+ }
+ };
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ public static final int CLIPBOARD_DELAY = 1000;
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ HTMLTransferConsoleOutputTest htmlTransferConsoleOutputTest = new HTMLTransferConsoleOutputTest();
+ htmlTransferConsoleOutputTest.initialize();
+ return;
+ }
+ final ClipboardOwner clipboardOwner = new ClipboardOwner() {
+ public void lostOwnership(Clipboard clip,
+ Transferable contents) {
+ System.exit(0);
+ }
+ };
+ clipboard.setContents(transferable, clipboardOwner);
+ final Object o = new Object();
+ synchronized (o) {
+ try {
+ o.wait();
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ }
+ System.out.println("Test Pass!");
+ }
+
+ public void initialize() throws Exception {
+ clipboard.setContents(transferable, this);
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ HTMLTransferConsoleOutputTest.class.getName(),
+ "child"
+ );
+
+ Process process = ProcessTools.startProcess("Child", pb);
+ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process);
+
+ if (!process.waitFor(15, TimeUnit.SECONDS)) {
+ process.destroyForcibly();
+ throw new TimeoutException("Timed out waiting for Child");
+ }
+
+ byte[] bytes = baos.toByteArray();
+ String string = null;
+ try {
+ string = new String(bytes, "ASCII");
+ } catch (UnsupportedEncodingException uee) {
+ uee.printStackTrace();
+ }
+ if (string.lastIndexOf(magic) != -1) {
+ throw new RuntimeException("Test failed. Output contains:" +
+ string);
+ }
+
+ outputAnalyzer.shouldHaveExitValue(0);
+ }
+
+
+ static class ForkOutputStream extends OutputStream {
+ final OutputStream outputStream1;
+ final OutputStream outputStream2;
+
+ public ForkOutputStream(OutputStream os1, OutputStream os2) {
+ outputStream1 = os1;
+ outputStream2 = os2;
+ }
+
+ public void write(int b) throws IOException {
+ outputStream1.write(b);
+ outputStream2.write(b);
+ }
+
+ public void flush() throws IOException {
+ outputStream1.flush();
+ outputStream2.flush();
+ }
+
+ public void close() throws IOException {
+ outputStream1.close();
+ outputStream2.close();
+ }
+ }
+
+ public void lostOwnership(Clipboard clip, Transferable contents) {
+ final Runnable r = () -> {
+ try {
+ Thread.sleep(CLIPBOARD_DELAY);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ final PrintStream oldOut = System.out;
+ final PrintStream newOut =
+ new PrintStream(new ForkOutputStream(oldOut, baos));
+ Transferable t = clipboard.getContents(null);
+ try {
+ System.setOut(newOut);
+ t.getTransferData(dataFlavor);
+ System.setOut(oldOut);
+ } catch (IOException | UnsupportedFlavorException ioe) {
+ ioe.printStackTrace();
+ }
+ clipboard.setContents(transferable, null);
+ };
+ final Thread t = new Thread(r);
+ t.start();
+ }
+}
diff --git a/test/jdk/java/awt/datatransfer/ImageTransferCrashTest.java b/test/jdk/java/awt/datatransfer/ImageTransferCrashTest.java
new file mode 100644
index 00000000000..76e484b3ce2
--- /dev/null
+++ b/test/jdk/java/awt/datatransfer/ImageTransferCrashTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4513976
+ * @summary tests that inter-JVM image transfer doesn't cause crash
+ * @key headful
+ * @library /test/lib
+ * @run main ImageTransferCrashTest
+ */
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class ImageTransferCrashTest implements ClipboardOwner {
+ static final Clipboard clipboard =
+ Toolkit.getDefaultToolkit().getSystemClipboard();
+ final Transferable textTransferable = new StringSelection("TEXT");
+ public static final int CLIPBOARD_DELAY = 10;
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ ImageTransferCrashTest imageTransferCrashTest = new ImageTransferCrashTest();
+ imageTransferCrashTest.initialize();
+ return;
+ }
+ final ClipboardOwner clipboardOwner = (clip, contents) -> System.exit(0);
+ final int width = 100;
+ final int height = 100;
+ final BufferedImage bufferedImage =
+ new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ final WritableRaster writableRaster =
+ bufferedImage.getWritableTile(0, 0);
+ final int[] color = new int[]{0x80, 0x80, 0x80};
+ for (int i = 0; i < width; i++) {
+ for (int j = 0; j < height; j++) {
+ writableRaster.setPixel(i, j, color);
+ }
+ }
+ bufferedImage.releaseWritableTile(0, 0);
+
+ final Transferable imageTransferable = new Transferable() {
+ final DataFlavor[] flavors = new DataFlavor[]{
+ DataFlavor.imageFlavor};
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return flavors;
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor df) {
+ return DataFlavor.imageFlavor.equals(df);
+ }
+
+ public Object getTransferData(DataFlavor df)
+ throws UnsupportedFlavorException {
+ if (!isDataFlavorSupported(df)) {
+ throw new UnsupportedFlavorException(df);
+ }
+ return bufferedImage;
+ }
+ };
+ clipboard.setContents(imageTransferable, clipboardOwner);
+ final Object o = new Object();
+ synchronized (o) {
+ try {
+ o.wait();
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ }
+ System.out.println("Test Pass!");
+ }
+
+ public void initialize() throws Exception {
+ clipboard.setContents(textTransferable, this);
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ ImageTransferCrashTest.class.getName(),
+ "child"
+ );
+
+ Process process = ProcessTools.startProcess("Child", pb);
+ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(process);
+
+ if (!process.waitFor(15, TimeUnit.SECONDS)) {
+ process.destroyForcibly();
+ throw new TimeoutException("Timed out waiting for Child");
+ }
+
+ outputAnalyzer.shouldHaveExitValue(0);
+ }
+
+ public void lostOwnership(Clipboard clip, Transferable contents) {
+ final Runnable r = () -> {
+ while (true) {
+ try {
+ Thread.sleep(CLIPBOARD_DELAY);
+ Transferable t = clipboard.getContents(null);
+ t.getTransferData(DataFlavor.imageFlavor);
+ } catch (IllegalStateException e) {
+ e.printStackTrace();
+ System.err.println("clipboard is not prepared yet");
+ continue;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ break;
+ }
+ clipboard.setContents(textTransferable, null);
+ };
+ final Thread t = new Thread(r);
+ t.start();
+ }
+}