Index: jedit4.2_test/scenario.txt =================================================================== --- jedit4.2_test/scenario.txt (revision 0) +++ jedit4.2_test/scenario.txt (revision 0) @@ -0,0 +1,217 @@ +This file describes original ("manual") test scenario after which automated +test scenarios were developed. Main purpose of automated tests is to make sure +that implementation under test (Harmony's DRLVM for example, see +http://harmony.apache.org) is able to run jEdit application and an user is able +to perform some work in jEdit. +------------------------------------------------------------ + + +jEdit test scenario + +Software requirements: +jEdit 4.2final +J2SE 1.5 SDK + + +1. Installation jEdit & plugins + +1.1 Download jEdit 4.2final from here: + + http://www.jEdit.org/index.php?page=download. + +1.2 Install it (see installation instructions on this page as well). + +1.3 Change to directory where jEdit is installed (). + Run jEdit with the command “java –jar jEdit.jar” + (JAVA_HOME should point to java 5.0). + Read and close “Tips of the Day” window. + +1.4 Install the following plugins: + + * JavaStyle: Java code beautifier and template Javadoc comment generator + * JCompiler: in-process compiler for Java files in the edit buffer + * ProjectViewer: tree-structured view of related project files + In fact more plugins will be installed because of plugin dependencies. + + +1.4.1 For that perform the following steps: + + Go to menu "Utilities" -> "Global Options…" -> "Proxy Servers", + check "Use HTTP proxy server", + set "HTTP proxy host" to proper value, + set "HTTP proxy port" to proper value, + click "Apply", and "OK" + +1.4.2 Go to menu "Plugins" -> "Plugin Manager", select tab "Install", + click on “Name” title to sort plugins in alphabet order. + Check the plugins listed above and press "Install" button. + Select "Manage" tab to make sure that all the plugins were + installed without errors (their status should be "Loaded"). + Close Plugin Manager. + +1.4.3 If you experience any difficulties try to change mirror settings. + Open "Plugin Manager" -> "Download options..." and press + "Update mirror list" button. + Then choose "North America: University of Minnesota (Minneapolis, MN)" + as preferred download mirror, press "Apply", and "OK" and repeat plugins + installation. + +1.4.4 You can also install plugins manually. + For that use the following link and instructions + + http://plugins.jEdit.org/list.php + + Download and save plugins to "jar" subdirectory of your + directory, unzip them and link them up in the Plugins Manager. + +1.5 This item is a workaround for a bug in JCompile plugin, + described here: http://community.jEdit.org/?q=node/view/2729. + +1.5.1 Download the plugin “Console” 4.1.2 (not 4.2.6.4) from here: + + http://plugins.jEdit.org/list.php + + to \jars directory, unzip it. + +1.5.2 Go to “Plugins” -> “Plugin Manager”, choose “Manage” tab. + +1.5.3 Remove the latest version of Console plugin + (click on “Console 4.2.6.4” plugin and press “Remove”. + You will be asked for confirmation, answer “Yes”. + +1.5.4 Then check “Console.jar” plugin. Now you installed Console 4.1.2. + +1.6 Close jEdit (“File” -> “Exit” or “Ctrl-q”). + + + +2. Data preparation + +2.1 Make directory “\project”. Cd to it. + + + +3. Running jEdit and tune its settings + +3.1 Download one of the JRE to be tested. + +3.2 Run the following commands: + + $TESTED_JAVA –jar jedit.jar + + Where $TESTED_JAVApoints to runtime under test + + jEdit should open. Read and close “Tip of the Day” window. + +3.3 Configure editor panes. + +3.3.1 Open menu "Utilities" -> "Global Options" -> "Docking". + +3.3.2 Set Docking position for "File System Browser" window to "left" value. + +3.3.3 Set Docking position for "Console" window to "bottom" value. + +3.3.4 You can resize docked windows by dragging the splitters. + + + +4. Compile and run a simple java class + +4.1 Open File System Browser pane. The file tree will be shown. + +4.2 Expand -> “project”. + +4.3 Right click on “project” and choose “New File” from pop-up menu. + +4.4 Rename new file to “Hello.java” (“File” -> “Save As…”), + enter file name “Hello.java”. Make sure that the title of + the main pane is changed to "Hello.java". + +4.5 Paste the following code to the edior: + ------ Hello.java ------ + + public class Hello { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } + } + ------ end of Hello.java ------ + +4.6 Save the changes. + ("File" -> "Save" or press the appropriate icon on + the main pane tool bar or just press "Ctrl-s”). + +4.7 Compile java file: + Open "Plugins" -> "Console" -> "Compile Current Buffer..." menu. + Set "Source file(s)" to \project\Hello.java. + Set "Output directory" to \project. Press "OK". + +4.8 Click "Refresh" icon in File System Browser pane. + Make sure that Hello.class file appeared under "project" directory. + +4.9 Open menu "Plugins" -> "Java Browser" -> "Open Java Browser". + The window with class outline should appear. Close this window. + +4.10 Run Hello class. Open "Plugins" -> "Console" -> "Run Current Buffer..." + Set “Class path” to "\project" and press "OK" button. + Open Console pane and make sure that the output is "Hello, world! + Process java exited with code 0". + +4.11 Go to “Search” -> “Find…” menu or press “Ctrl-f. + Set “Search for” to < ”Hello, World!” > (don’t forget commas). + Set “Replace with” to < System.getProperty(“java.home”) >. + Press “Replace All”. + +4.12 Go to "Plugins" -> "JavaStyle" -> "JavaStyle Preformat Buffer" menu. + +4.13 Save changes (“Ctrl-s”). + +4.14 Repeat class compilation and running + (“Console” -> “Compile Current Buffer” and “Console” -> “Run Current Buffer”). + + + +5. Using miscellaneous functions + +5.1 Open “Utilities” -> “Global Options…”. + A new popup window “Options: jEdit” will appear. + Click “Text Area” field on the left of the window. + Click on the rectangle titles “Background color”. + Make sure that a new popup window “Pick Color” appears and + its tab “Swatches” is selected. Choose some background color + and press “OK” to close “Pick Color” window. + Press “Apply” and “OK” buttons in the “Option jEdit” window. + Make sure that the background color changed. + +5.2 Open “File” -> “Print” or “Ctrl-P”. + Make sure that popup window titled “Print” appeared. + Press “Print”. Make sure that the file Hello.java is printed. + +5.3 Open “Help” -> “About jEdit”. A new popup window “About jEdit” will appear. + Wait till some text will be loaded (the text should appear not very slow) + and close the window. + +5.4 Open “Help” -> “jEdit Help” or “F1”. + A new popup window “jEdit Help” will appear. + Make sure that the window has 2 frames. + A left one should contain 2 tabs – “Contents” and “Search”. + “Contents” tab is selected by default and represents the content tree. + Switch to “Search” tab and type “font” in the text area. Press “Enter”. + Make sure that search gives some entries. + Double-click one of the entries and make sure that the appropriate + content appears in the right frame. + +5.5 Move the mouse over the icons on toolbar and make sure + that the appropriate tooltips pop up. + +5.6 Close “jEdit Help” window. + + + +6. Cleanup + +6.1 Close all the files in the main pane buffer. + Press "Close" icon on the main pane tool bar or press "Ctrl-w" + on each open file. + +6.2 Close jEdit. Index: jedit4.2_test/patches/harmony/java/awt/Toolkit.java =================================================================== --- jedit4.2_test/patches/harmony/java/awt/Toolkit.java (revision 0) +++ jedit4.2_test/patches/harmony/java/awt/Toolkit.java (revision 0) @@ -0,0 +1,1440 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.awt; + +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.dnd.MouseDragGestureRecognizer; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.event.AWTEventListener; +import java.awt.event.AWTEventListenerProxy; +import java.awt.event.InputEvent; +import java.awt.im.InputMethodHighlight; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.peer.ButtonPeer; +import java.awt.peer.CanvasPeer; +import java.awt.peer.CheckboxMenuItemPeer; +import java.awt.peer.CheckboxPeer; +import java.awt.peer.ChoicePeer; +import java.awt.peer.DialogPeer; +import java.awt.peer.FileDialogPeer; +import java.awt.peer.FontPeer; +import java.awt.peer.FramePeer; +import java.awt.peer.LabelPeer; +import java.awt.peer.LightweightPeer; +import java.awt.peer.ListPeer; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.MenuPeer; +import java.awt.peer.MouseInfoPeer; +import java.awt.peer.PanelPeer; +import java.awt.peer.PopupMenuPeer; +import java.awt.peer.ScrollPanePeer; +import java.awt.peer.ScrollbarPeer; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.WindowPeer; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Collections; +import java.util.EventListener; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.Properties; +import java.util.ResourceBundle; +import org.apache.harmony.awt.ChoiceStyle; +import org.apache.harmony.awt.ComponentInternals; +import org.apache.harmony.awt.ContextStorage; +import org.apache.harmony.awt.MouseEventPreprocessor; +import org.apache.harmony.awt.ReadOnlyIterator; +import org.apache.harmony.awt.Theme; +import org.apache.harmony.awt.datatransfer.DTK; +import org.apache.harmony.awt.datatransfer.NativeClipboard; +import org.apache.harmony.awt.gl.MultiRectArea; +import org.apache.harmony.awt.internal.nls.Messages; +import org.apache.harmony.awt.text.TextFieldKit; +import org.apache.harmony.awt.text.TextKit; +import org.apache.harmony.awt.wtk.CreationParams; +import org.apache.harmony.awt.wtk.GraphicsFactory; +import org.apache.harmony.awt.wtk.NativeCursor; +import org.apache.harmony.awt.wtk.NativeEventQueue; +import org.apache.harmony.awt.wtk.NativeEventThread; +import org.apache.harmony.awt.wtk.NativeMouseInfo; +import org.apache.harmony.awt.wtk.NativeWindow; +import org.apache.harmony.awt.wtk.ShutdownWatchdog; +import org.apache.harmony.awt.wtk.Synchronizer; +import org.apache.harmony.awt.wtk.WTK; +import org.apache.harmony.awt.wtk.WindowFactory; + +public abstract class Toolkit { + private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$ + + private static final ResourceBundle properties = loadResources(RECOURCE_PATH); + + final Dispatcher dispatcher; + + private EventQueueCore systemEventQueueCore; + + final EventDispatchThread dispatchThread; + + NativeEventThread nativeThread; + + private final AWTEventsManager awtEventsManager; + + /* key = nativeWindow, value = Component, should be Map */ + private final Map windowComponentMap = new HashMap(); + + /* key = nativeWindow, value = MenuComponent */ + private final Map windowPopupMap = new HashMap(); + + private final Map windowFocusProxyMap = new HashMap(); + + private class AWTTreeLock { + } + + final Object awtTreeLock = new AWTTreeLock(); + + private final Synchronizer synchronizer = ContextStorage.getSynchronizer(); + + final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog(); + + final Theme theme = createTheme(); + + final AutoNumber autoNumber = new AutoNumber(); + + final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup(); + + final Frame.AllFrames allFrames = new Frame.AllFrames(); + + KeyboardFocusManager currentKeyboardFocusManager; + + MouseEventPreprocessor mouseEventPreprocessor; + + NativeClipboard systemClipboard = null; + + private NativeClipboard systemSelection = null; + + private boolean bDynamicLayoutSet = true; + + /** + * The set of desktop properties that user set directly. + */ + private final HashSet userPropSet = new HashSet(); + + protected final Map desktopProperties; + + protected final PropertyChangeSupport desktopPropsSupport; + + /** + * For this component the native window is being created + * It is used in the callback-driven window creation + * (e.g. on Windows in the handler of WM_CREATE event) + * to establish the connection between this component + * and its native window + */ + private Object recentNativeWindowComponent; + + final WindowList windows = new WindowList(); + + private WTK wtk; + + final DTK dtk; + + private final class ComponentInternalsImpl extends ComponentInternals { + @Override + public NativeWindow getNativeWindow(Component component) { + lockAWT(); + try { + return component != null ? component.getNativeWindow() : null; + } finally { + unlockAWT(); + } + } + + @Override + public void startMouseGrab(Window grabWindow, Runnable whenCanceled) { + lockAWT(); + try { + dispatcher.mouseGrabManager.startGrab(grabWindow, whenCanceled); + } finally { + unlockAWT(); + } + } + + @Override + public void endMouseGrab() { + lockAWT(); + try { + dispatcher.mouseGrabManager.endGrab(); + } finally { + unlockAWT(); + } + } + + @Override + public Window attachNativeWindow(long nativeWindowId) { + lockAWT(); + try { + Window window = new EmbeddedWindow(nativeWindowId); + windowComponentMap.put(window.getNativeWindow(), window); + windows.add(window); + return window; + } finally { + unlockAWT(); + } + } + + @Override + public void makePopup(Window window) { + lockAWT(); + try { + window.setPopup(true); + } finally { + unlockAWT(); + } + } + + @Override + public void onDrawImage(Component comp, Image image, Point destLocation, + Dimension destSize, Rectangle source) { + lockAWT(); + try { + comp.onDrawImage(image, destLocation, destSize, source); + } finally { + unlockAWT(); + } + } + + @Override + public void setCaretPos(Component c, int x, int y) { + c.setCaretPos(x, y); + } + + @Override + public void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException, + InvocationTargetException { + Toolkit.this.unsafeInvokeAndWait(runnable); + } + + @Override + public TextKit getTextKit(Component comp) { + lockAWT(); + try { + return comp.getTextKit(); + } finally { + unlockAWT(); + } + } + + @Override + public void setTextKit(Component comp, TextKit kit) { + lockAWT(); + try { + comp.setTextKit(kit); + } finally { + unlockAWT(); + } + } + + @Override + public TextFieldKit getTextFieldKit(Component comp) { + lockAWT(); + try { + return comp.getTextFieldKit(); + } finally { + unlockAWT(); + } + } + + @Override + public void setTextFieldKit(Component comp, TextFieldKit kit) { + lockAWT(); + try { + comp.setTextFieldKit(kit); + } finally { + unlockAWT(); + } + } + + @Override + public void shutdown() { + dispatchThread.shutdown(); + } + + @Override + public void setMouseEventPreprocessor(MouseEventPreprocessor preprocessor) { + lockAWT(); + try { + mouseEventPreprocessor = preprocessor; + } finally { + unlockAWT(); + } + } + + @Override + public Choice createCustomChoice(ChoiceStyle style) { + return new Choice(style); + } + + @Override + public Insets getNativeInsets(Window w) { + lockAWT(); + try { + return (w != null) ? w.getNativeInsets() : new Insets(0, 0, 0, 0); + } finally { + unlockAWT(); + } + } + + @Override + public MultiRectArea getRepaintRegion(Component c) { + return c.repaintRegion; + } + + @Override + public MultiRectArea subtractPendingRepaintRegion(Component c, MultiRectArea mra) { + lockAWT(); + try { + RedrawManager rm = c.getRedrawManager(); + if (rm == null) { + return null; + } + return rm.subtractPendingRepaintRegion(c, mra); + } finally { + unlockAWT(); + } + } + + @Override + public boolean wasPainted(Window w) { + lockAWT(); + try { + return w.painted; + } finally { + unlockAWT(); + } + } + + @Override + public MultiRectArea getObscuredRegion(Component c) { + return c.getObscuredRegion(null); + } + + @Override + public void setDesktopProperty(String name, Object value) { + Toolkit.this.setDesktopProperty(name, value); + } + + @Override + public void runModalLoop(Dialog dlg) { + dlg.runModalLoop(); + } + + @Override + public void endModalLoop(Dialog dlg) { + dlg.endModalLoop(); + } + + @Override + public void setVisibleFlag(Component comp, boolean visible) { + comp.visible = visible; + } + + @Override + public void addObscuredRegions(MultiRectArea mra, Component c, Container container) { + if (container != null) { + container.addObscuredRegions(mra, c); + } + } + } + + /* + * A lot of methods must throw HeadlessException + * if GraphicsEnvironment.isHeadless() returns true. + */ + static void checkHeadless() throws HeadlessException { + if (GraphicsEnvironment.isHeadless()) { + throw new HeadlessException(); + } + } + + final void lockAWT() { + synchronizer.lock(); + } + + static final void staticLockAWT() { + ContextStorage.getSynchronizer().lock(); + } + + final void unlockAWT() { + synchronizer.unlock(); + } + + static final void staticUnlockAWT() { + ContextStorage.getSynchronizer().unlock(); + } + + /** + * InvokeAndWait under AWT lock. W/o this method system can hang up. + * Added to support modality (Dialog.show() & PopupMenu.show()) from + * not event dispatch thread. Use in other cases is not recommended. + * + * Still can be called only for whole API methods that + * cannot be called from other classes API methods. + * Examples: + * show() for modal dialogs - correct, only user can call it, + * directly or through setVisible(true) + * setBounds() for components - incorrect, setBounds() + * can be called from layoutContainer() + * for layout managers + */ + final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException, + InvocationTargetException { + synchronizer.storeStateAndFree(); + try { + EventQueue.invokeAndWait(runnable); + } finally { + synchronizer.lockAndRestoreState(); + } + } + + final Synchronizer getSynchronizer() { + return synchronizer; + } + + final WTK getWTK() { + return wtk; + } + + public static String getProperty(String propName, String defVal) { + if (propName == null) { + // awt.7D=Property name is null + throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$ + } + staticLockAWT(); + try { + String retVal = null; + if (properties != null) { + try { + retVal = properties.getString(propName); + } catch (MissingResourceException e) { + } catch (ClassCastException e) { + } + } + return (retVal == null) ? defVal : retVal; + } finally { + staticUnlockAWT(); + } + } + + public static Toolkit getDefaultToolkit() { + synchronized (ContextStorage.getContextLock()) { + if (ContextStorage.shutdownPending()) { + return null; + } + Toolkit defToolkit = ContextStorage.getDefaultToolkit(); + if (defToolkit != null) { + return defToolkit; + } + staticLockAWT(); + try { + defToolkit = new ToolkitImpl(); + ContextStorage.setDefaultToolkit(defToolkit); + return defToolkit; + } finally { + staticUnlockAWT(); + } + //TODO: read system property named awt.toolkit + //and create an instance of the specified class, + //by default use ToolkitImpl + } + } + + Font getDefaultFont() { + return wtk.getSystemProperties().getDefaultFont(); + } + + private static ResourceBundle loadResources(String path) { + try { + return ResourceBundle.getBundle(path); + } catch (MissingResourceException e) { + return null; + } + } + + private static String getWTKClassName() { + String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + String packageBase = "org.apache.harmony.awt.wtk", win = "windows", lin = "linux"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (osName.startsWith(lin)) { + return packageBase + "." + lin + ".LinuxWTK"; //$NON-NLS-1$ //$NON-NLS-2$ + } + if (osName.startsWith(win)) { + return packageBase + "." + win + ".WinWTK"; //$NON-NLS-1$ //$NON-NLS-2$ + } + return null; + } + + Component getComponentById(long id) { + if (id == 0) { + return null; + } + return (Component) windowComponentMap.get(getWindowFactory().getWindowById(id)); + } + + PopupBox getPopupBoxById(long id) { + if (id == 0) { + return null; + } + return (PopupBox) windowPopupMap.get(getWindowFactory().getWindowById(id)); + } + + Window getFocusProxyOwnerById(long id) { + if (id == 0) { + return null; + } + return windowFocusProxyMap.get(getWindowFactory().getWindowById(id)); + } + + final WindowFactory getWindowFactory() { + return wtk.getWindowFactory(); + } + + final GraphicsFactory getGraphicsFactory() { + return wtk.getGraphicsFactory(); + } + + public Toolkit() { + lockAWT(); + try { + ComponentInternals.setComponentInternals(new ComponentInternalsImpl()); + new EventQueue(this); // create the system EventQueue + dispatcher = new Dispatcher(this); + final String className = getWTKClassName(); + desktopProperties = new HashMap(); + desktopPropsSupport = new PropertyChangeSupport(this); + awtEventsManager = new AWTEventsManager(); + dispatchThread = new EventDispatchThread(this, dispatcher); + nativeThread = new NativeEventThread(); + dtk = DTK.getDTK(); + NativeEventThread.Init init = new NativeEventThread.Init() { + public WTK init() { + wtk = createWTK(className); + wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog); + synchronizer.setEnvironment(wtk, dispatchThread); + ContextStorage.setWTK(wtk); + dtk.initDragAndDrop(); + return wtk; + } + }; + nativeThread.start(init); + dispatchThread.start(); + wtk.getNativeEventQueue().awake(); + } finally { + unlockAWT(); + } + } + + public abstract void sync(); + + protected abstract TextAreaPeer createTextArea(TextArea a0) throws HeadlessException; + + public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3); + + public abstract Image createImage(ImageProducer a0); + + public abstract Image createImage(byte[] a0, int a1, int a2); + + public abstract Image createImage(URL a0); + + public abstract Image createImage(String a0); + + public abstract ColorModel getColorModel() throws HeadlessException; + + /** + * @deprecated + */ + @Deprecated + public abstract FontMetrics getFontMetrics(Font font); + + public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3); + + public abstract void beep(); + + protected abstract ButtonPeer createButton(Button a0) throws HeadlessException; + + protected abstract CanvasPeer createCanvas(Canvas a0); + + protected abstract CheckboxPeer createCheckbox(Checkbox a0) throws HeadlessException; + + protected abstract CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem a0) + throws HeadlessException; + + protected abstract ChoicePeer createChoice(Choice a0) throws HeadlessException; + + protected abstract DialogPeer createDialog(Dialog a0) throws HeadlessException; + + public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent a0) + throws InvalidDnDOperationException; + + protected abstract FileDialogPeer createFileDialog(FileDialog a0) throws HeadlessException; + + protected abstract FramePeer createFrame(Frame a0) throws HeadlessException; + + protected abstract LabelPeer createLabel(Label a0) throws HeadlessException; + + protected abstract ListPeer createList(List a0) throws HeadlessException; + + protected abstract MenuPeer createMenu(Menu a0) throws HeadlessException; + + protected abstract MenuBarPeer createMenuBar(MenuBar a0) throws HeadlessException; + + protected abstract MenuItemPeer createMenuItem(MenuItem a0) throws HeadlessException; + + protected abstract PanelPeer createPanel(Panel a0); + + protected abstract PopupMenuPeer createPopupMenu(PopupMenu a0) throws HeadlessException; + + protected abstract ScrollPanePeer createScrollPane(ScrollPane a0) throws HeadlessException; + + protected abstract ScrollbarPeer createScrollbar(Scrollbar a0) throws HeadlessException; + + protected abstract TextFieldPeer createTextField(TextField a0) throws HeadlessException; + + protected abstract WindowPeer createWindow(Window a0) throws HeadlessException; + + /** + * @deprecated + */ + @Deprecated + public abstract String[] getFontList(); + + /** + * @deprecated + */ + @Deprecated + protected abstract FontPeer getFontPeer(String a0, int a1); + + public abstract Image getImage(String a0); + + public abstract Image getImage(URL a0); + + public abstract PrintJob getPrintJob(Frame a0, String a1, Properties a2); + + public abstract int getScreenResolution() throws HeadlessException; + + public abstract Dimension getScreenSize() throws HeadlessException; + + public abstract Clipboard getSystemClipboard() throws HeadlessException; + + protected abstract EventQueue getSystemEventQueueImpl(); + + public abstract Map mapInputMethodHighlight( + InputMethodHighlight highlight) throws HeadlessException; + + Map mapInputMethodHighlightImpl( + InputMethodHighlight highlight) throws HeadlessException { + checkHeadless(); + HashMap map = new HashMap(); + wtk.getSystemProperties().mapInputMethodHighlight(highlight, map); + return Collections. unmodifiableMap(map); + } + + public void addPropertyChangeListener(String propName, PropertyChangeListener l) { + lockAWT(); + try { + if (desktopProperties.isEmpty()) { + initializeDesktopProperties(); + } + } finally { + unlockAWT(); + } + if (l != null) { // there is no guarantee that null listener will not be added + desktopPropsSupport.addPropertyChangeListener(propName, l); + } + } + + protected java.awt.peer.MouseInfoPeer getMouseInfoPeer() { + return new MouseInfoPeer() { + }; + } + + protected LightweightPeer createComponent(Component a0) throws org.apache.harmony.luni.util.NotImplementedException { + lockAWT(); + try { + } finally { + unlockAWT(); + } + if (true) { + throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ + } + return null; + } + + public Image createImage(byte[] imagedata) { + return createImage(imagedata, 0, imagedata.length); + } + + protected static Container getNativeContainer(Component c) { + staticLockAWT(); + try { + //TODO: implement + return c.getWindowAncestor(); + } finally { + staticUnlockAWT(); + } + } + + public PropertyChangeListener[] getPropertyChangeListeners() { + return desktopPropsSupport.getPropertyChangeListeners(); + } + + public PropertyChangeListener[] getPropertyChangeListeners(String propName) { + return desktopPropsSupport.getPropertyChangeListeners(propName); + } + + public void removePropertyChangeListener(String propName, PropertyChangeListener l) { + desktopPropsSupport.removePropertyChangeListener(propName, l); + } + + public Cursor createCustomCursor(Image img, Point hotSpot, String name) + throws IndexOutOfBoundsException, HeadlessException { + lockAWT(); + try { + checkHeadless(); + int w = img.getWidth(null), x = hotSpot.x; + int h = img.getHeight(null), y = hotSpot.y; + if (x < 0 || x >= w || y < 0 || y >= h) { + // awt.7E=invalid hotSpot + throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$ + } + return new Cursor(name, img, hotSpot); + } finally { + unlockAWT(); + } + } + + @SuppressWarnings("unchecked") + public T createDragGestureRecognizer( + Class recognizerAbstractClass, DragSource ds, Component c, int srcActions, + DragGestureListener dgl) { + if (recognizerAbstractClass == null) { + return null; + } + if (recognizerAbstractClass.isAssignableFrom(MouseDragGestureRecognizer.class)) { + return (T) new DefaultMouseDragGestureRecognizer(ds, c, srcActions, dgl); + } + return null; + } + + public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight); + } finally { + unlockAWT(); + } + } + + public final Object getDesktopProperty(String propName) { + lockAWT(); + try { + if (desktopProperties.isEmpty()) { + initializeDesktopProperties(); + } + if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$ + // dynamicLayoutSupported is special case + return Boolean.valueOf(isDynamicLayoutActive()); + } + Object val = desktopProperties.get(propName); + if (val == null) { + // try to lazily load prop value + // just for compatibility, our lazilyLoad is empty + val = lazilyLoadDesktopProperty(propName); + } + return val; + } finally { + unlockAWT(); + } + } + + public boolean getLockingKeyState(int a0) throws UnsupportedOperationException { + lockAWT(); + try { + return false; + } finally { + unlockAWT(); + } +// if (true) { +// throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ +// } + } + + public int getMaximumCursorColors() throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + return wtk.getCursorFactory().getMaximumCursorColors(); + } finally { + unlockAWT(); + } + } + + public int getMenuShortcutKeyMask() throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + return InputEvent.CTRL_MASK; + } finally { + unlockAWT(); + } + } + + public PrintJob getPrintJob(Frame a0, String a1, JobAttributes a2, PageAttributes a3) throws org.apache.harmony.luni.util.NotImplementedException { + lockAWT(); + try { + } finally { + unlockAWT(); + } + if (true) { + throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ + } + return null; + } + + public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException { + if (gc == null) { + throw new NullPointerException(); + } + lockAWT(); + try { + return new Insets(0, 0, 0, 0); //TODO: get real screen insets + } finally { + unlockAWT(); + } + } + + public final EventQueue getSystemEventQueue() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkAwtEventQueueAccess(); + } + return getSystemEventQueueImpl(); + } + + EventQueueCore getSystemEventQueueCore() { + return systemEventQueueCore; + } + + void setSystemEventQueueCore(EventQueueCore core) { + systemEventQueueCore = core; + } + + public Clipboard getSystemSelection() throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSystemClipboardAccess(); + } + if (systemSelection == null) { + systemSelection = dtk.getNativeSelection(); + } + return systemSelection; + } finally { + unlockAWT(); + } + } + + protected void initializeDesktopProperties() { + lockAWT(); + try { + wtk.getSystemProperties().init(desktopProperties); + } finally { + unlockAWT(); + } + } + + public boolean isDynamicLayoutActive() throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + // always return true + return true; + } finally { + unlockAWT(); + } + } + + protected boolean isDynamicLayoutSet() throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + return bDynamicLayoutSet; + } finally { + unlockAWT(); + } + } + + public boolean isFrameStateSupported(int state) throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + return wtk.getWindowFactory().isWindowStateSupported(state); + } finally { + unlockAWT(); + } + } + + protected Object lazilyLoadDesktopProperty(String propName) { + return null; + } + + protected void loadSystemColors(int[] colors) throws HeadlessException { + lockAWT(); + try { + } finally { + unlockAWT(); + } + } + + protected final void setDesktopProperty(String propName, Object value) { + Object oldVal; + lockAWT(); + try { + oldVal = getDesktopProperty(propName); + userPropSet.add(propName); + desktopProperties.put(propName, value); + } finally { + unlockAWT(); + } + desktopPropsSupport.firePropertyChange(propName, oldVal, value); + } + + public void setDynamicLayout(boolean dynamic) throws HeadlessException { + lockAWT(); + try { + checkHeadless(); + bDynamicLayoutSet = dynamic; + } finally { + unlockAWT(); + } + } + + public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException { + lockAWT(); + try { + } finally { + unlockAWT(); + } + if (true) { + throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$ + } + return; + } + + void onQueueEmpty() { + if (windows.isEmpty()) { + if (systemClipboard != null) { + systemClipboard.onShutdown(); + } + if (systemSelection != null) { + systemSelection.onShutdown(); + } + shutdownWatchdog.setWindowListEmpty(true); + } else { + for (Iterator i = windows.iterator(); i.hasNext();) { + ((Window) i.next()).redrawAll(); + } + } + } + + private WTK createWTK(String clsName) { + WTK newWTK = null; + try { + newWTK = (WTK) Class.forName(clsName).newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return newWTK; + } + + /** + * Connect the component to its native window + * This method is called after the synchronous window creation, + * and also in the window creation callback if it exists (WM_CREATE on Windows) + * Calling this method twice is OK because in second time it just does nothing. + * + * This is done this way because on Windows the native window gets a series of native + * events before windowFactory.CreateWindow() returns, and the WinWindow object should be created + * to process them. The WM_CREATE message is guaranteed to be first in the series, so that the + * the WM_CREATE handler creates the WinWindow object and calls nativeWindowCreated() + * for it. + * + * @param win - native window just created + */ + void nativeWindowCreated(NativeWindow win) { + if (recentNativeWindowComponent == null) { + return; + } + if (recentNativeWindowComponent instanceof Component) { + windowComponentMap.put(win, recentNativeWindowComponent); + ((Component) recentNativeWindowComponent).nativeWindowCreated(win); + } else if (recentNativeWindowComponent instanceof PopupBox) { + windowPopupMap.put(win, recentNativeWindowComponent); + } + recentNativeWindowComponent = null; + } + + /** + * Connect the component to its native window + * @param winId - id of native window just created + */ + boolean onWindowCreated(long winId) { + nativeWindowCreated(getWindowFactory().getWindowById(winId)); + return false; + } + + NativeWindow createEmbeddedNativeWindow(EmbeddedWindow ew) { + windows.add(ew); + CreationParams cp = new CreationParams(); + cp.child = true; + cp.disabled = false; + cp.name = "EmbeddedWindow"; //$NON-NLS-1$ + cp.parentId = ew.nativeWindowId; + cp.x = 0; + cp.y = 0; + Dimension size = getWindowFactory().getWindowSizeById(ew.nativeWindowId); + cp.w = size.width; + cp.h = size.height; + recentNativeWindowComponent = ew; + NativeWindow win = getWindowFactory().createWindow(cp); + nativeWindowCreated(win); + shutdownWatchdog.setWindowListEmpty(false); + return win; + } + + NativeWindow createNativeWindow(Component c) { + if (c instanceof Window) { + windows.add(c); + } + Component parent = null; + Point location = c.getLocation(); + CreationParams cp = new CreationParams(); + cp.child = !(c instanceof Window); + cp.disabled = !c.isEnabled(); + if (c instanceof Window) { + Window w = (Window) c; + cp.resizable = w.isResizable(); + cp.undecorated = w.isUndecorated(); + parent = w.getOwner(); + cp.locationByPlatform = w.locationByPlatform; + if (c instanceof Frame) { + Frame frame = (Frame) c; + int state = frame.getExtendedState(); + cp.name = frame.getTitle(); + cp.iconified = (state & Frame.ICONIFIED) != 0; + cp.maximizedState = 0; + if ((state & Frame.MAXIMIZED_BOTH) != 0) { + cp.maximizedState |= cp.MAXIMIZED; + } + if ((state & Frame.MAXIMIZED_HORIZ) != 0) { + cp.maximizedState |= cp.MAXIMIZED_HORIZ; + } + if ((state & Frame.MAXIMIZED_VERT) != 0) { + cp.maximizedState |= cp.MAXIMIZED_VERT; + } + cp.decorType = CreationParams.DECOR_TYPE_FRAME; + } else if (c instanceof Dialog) { + Dialog dlg = (Dialog) c; + cp.name = dlg.getTitle(); + cp.decorType = CreationParams.DECOR_TYPE_DIALOG; + } else if (w.isPopup()) { + cp.decorType = CreationParams.DECOR_TYPE_POPUP; + } else { + cp.decorType = CreationParams.DECOR_TYPE_UNDECOR; + } + } else { + parent = c.getHWAncestor(); + cp.name = c.getName(); + //set location relative to the nearest heavy weight ancestor + location = MouseDispatcher.convertPoint(c, 0, 0, parent); + } + if (parent != null) { + NativeWindow nativeParent = parent.getNativeWindow(); + if (nativeParent == null) { + if (cp.child) { + return null; //component's window will be created when its parent is created ??? + } + parent.mapToDisplay(true); //TODO: verify it + nativeParent = parent.getNativeWindow(); + } + cp.parentId = nativeParent.getId(); + } + cp.x = location.x; + cp.y = location.y; + cp.w = c.getWidth(); + cp.h = c.getHeight(); + recentNativeWindowComponent = c; + NativeWindow win = getWindowFactory().createWindow(cp); + nativeWindowCreated(win); + if (c instanceof Window) { + shutdownWatchdog.setWindowListEmpty(false); + } + return win; + } + + void removeNativeWindow(NativeWindow w) { + Component comp = (Component) windowComponentMap.get(w); + if ((comp != null) && (comp instanceof Window)) { + windows.remove(comp); + } + windowComponentMap.remove(w); + } + + NativeWindow createPopupNativeWindow(PopupBox popup) { + CreationParams cp = new CreationParams(); + cp.child = popup.isMenuBar(); + cp.disabled = false; + cp.resizable = false; + cp.undecorated = true; + cp.iconified = false; + cp.visible = false; + cp.maximizedState = 0; + cp.decorType = CreationParams.DECOR_TYPE_POPUP; + NativeWindow nativeParent; + if (popup.getParent() != null) { + nativeParent = popup.getParent().getNativeWindow(); + } else { + nativeParent = popup.getOwner().getNativeWindow(); + } + assert nativeParent != null; + cp.parentId = nativeParent.getId(); + cp.x = popup.getLocation().x; + cp.y = popup.getLocation().y; + cp.w = popup.getSize().width; + cp.h = popup.getSize().height; + recentNativeWindowComponent = popup; + NativeWindow win = getWindowFactory().createWindow(cp); + nativeWindowCreated(win); + return win; + } + + void removePopupNativeWindow(NativeWindow w) { + windowPopupMap.remove(w); + } + + NativeWindow createFocusProxyNativeWindow(Window owner) { + CreationParams cp = new CreationParams(); + cp.child = true; + cp.disabled = false; + cp.resizable = false; + cp.undecorated = true; + cp.iconified = false; + cp.visible = true; + cp.maximizedState = 0; + cp.decorType = CreationParams.DECOR_TYPE_NONE; + cp.parentId = owner.getNativeWindow().getId(); + cp.x = -10; + cp.y = -10; + cp.w = 1; + cp.h = 1; + NativeWindow win = getWindowFactory().createWindow(cp); + windowFocusProxyMap.put(win, owner); + return win; + } + + void removeFocusProxyNativeWindow(NativeWindow w) { + windowFocusProxyMap.remove(w); + } + + NativeEventQueue getNativeEventQueue() { + return wtk.getNativeEventQueue(); + } + + /** + * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor + * for current platform for + * @param type - Java Cursor type + * @return new instance of implementation of NativeCursor + */ + NativeCursor createNativeCursor(int type) { + return wtk.getCursorFactory().getCursor(type); + } + + /** + * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor + * for current platform for custom cursor + * @param type - Java Cursor type + * @return new instance of implementation of NativeCursor + */ + NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) { + return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y); + } + + /** + * Returns implementation of org.apache.harmony.awt.wtk.NativeMouseInfo + * for current platform. + * @return implementation of NativeMouseInfo + */ + NativeMouseInfo getNativeMouseInfo() { + return wtk.getNativeMouseInfo(); + } + + public void addAWTEventListener(AWTEventListener listener, long eventMask) { + lockAWT(); + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(awtEventsManager.permission); + } + awtEventsManager.addAWTEventListener(listener, eventMask); + } finally { + unlockAWT(); + } + } + + public void removeAWTEventListener(AWTEventListener listener) { + lockAWT(); + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(awtEventsManager.permission); + } + awtEventsManager.removeAWTEventListener(listener); + } finally { + unlockAWT(); + } + } + + public AWTEventListener[] getAWTEventListeners() { + lockAWT(); + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(awtEventsManager.permission); + } + return awtEventsManager.getAWTEventListeners(); + } finally { + unlockAWT(); + } + } + + public AWTEventListener[] getAWTEventListeners(long eventMask) { + lockAWT(); + try { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(awtEventsManager.permission); + } + return awtEventsManager.getAWTEventListeners(eventMask); + } finally { + unlockAWT(); + } + } + + void dispatchAWTEvent(AWTEvent event) { + awtEventsManager.dispatchAWTEvent(event); + } + + private static Theme createTheme() { + String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + String packageBase = "org.apache.harmony.awt.theme", win = "windows", lin = "linux"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + PrivilegedAction action = new PrivilegedAction() { + public String run() { + return System.getProperty("awt.theme"); //$NON-NLS-1$ + } + }; + String className = AccessController.doPrivileged(action); + if (className == null) { + if (osName.startsWith(lin)) { + className = packageBase + "." + lin + ".LinuxTheme"; //$NON-NLS-1$ //$NON-NLS-2$ + } else if (osName.startsWith(win)) { + className = packageBase + "." + win + ".WinTheme"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + if (className != null) { + try { + return (Theme) Class.forName(className).newInstance(); + } catch (Exception e) { + } + } + return new Theme(); + } + + final class AWTEventsManager { + AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$ + + private final AWTListenerList listeners = new AWTListenerList(); + + void addAWTEventListener(AWTEventListener listener, long eventMask) { + if (listener != null) { + listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener)); + } + } + + void removeAWTEventListener(AWTEventListener listener) { + if (listener != null) { + for (AWTEventListenerProxy proxy : listeners.getUserListeners()) { + if (listener == proxy.getListener()) { + listeners.removeUserListener(proxy); + return; + } + } + } + } + + AWTEventListener[] getAWTEventListeners() { + HashSet listenersSet = new HashSet(); + for (AWTEventListenerProxy proxy : listeners.getUserListeners()) { + listenersSet.add(proxy.getListener()); + } + return listenersSet.toArray(new AWTEventListener[listenersSet.size()]); + } + + AWTEventListener[] getAWTEventListeners(long eventMask) { + HashSet listenersSet = new HashSet(); + for (AWTEventListenerProxy proxy : listeners.getUserListeners()) { + if ((proxy.getEventMask() & eventMask) == eventMask) { + listenersSet.add(proxy.getListener()); + } + } + return listenersSet.toArray(new AWTEventListener[listenersSet.size()]); + } + + void dispatchAWTEvent(AWTEvent event) { + AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event); + if (descriptor == null) { + return; + } + for (AWTEventListenerProxy proxy : listeners.getUserListeners()) { + if ((proxy.getEventMask() & descriptor.eventMask) != 0) { + proxy.eventDispatched(event); + } + } + } + } + + static final class AutoNumber { + int nextComponent = 0; + + int nextCanvas = 0; + + int nextPanel = 0; + + int nextWindow = 0; + + int nextFrame = 0; + + int nextDialog = 0; + + int nextButton = 0; + + int nextMenuComponent = 0; + + int nextLabel = 0; + + int nextCheckBox = 0; + + int nextScrollbar = 0; + + int nextScrollPane = 0; + + int nextList = 0; + + int nextChoice = 0; + + int nextFileDialog = 0; + + int nextTextArea = 0; + + int nextTextField = 0; + } + + /** + * Thread-safe collection of Window objects + */ + static final class WindowList { + /** + * If a non-dispatch thread adds/removes a window, + * this set it is replaced to avoid the possible conflict + * with concurrently running lock-free iterator loop + */ + private LinkedHashSet windows = new LinkedHashSet(); + + private class Lock { + } + + private final Object lock = new Lock(); + + @SuppressWarnings("unchecked") + void add(Component w) { + synchronized (lock) { + if (isDispatchThread()) { + windows.add(w); + } else { + windows = (LinkedHashSet) windows.clone(); + windows.add(w); + } + } + } + + @SuppressWarnings("unchecked") + void remove(Component w) { + synchronized (lock) { + if (isDispatchThread()) { + windows.remove(w); + } else { + windows = (LinkedHashSet) windows.clone(); + windows.remove(w); + } + } + } + + Iterator iterator() { + synchronized (lock) { + return new ReadOnlyIterator(windows.iterator()); + } + } + + boolean isEmpty() { + synchronized (lock) { + return windows.isEmpty(); + } + } + + private boolean isDispatchThread() { + return Thread.currentThread() instanceof EventDispatchThread; + } + } +} Index: jedit4.2_test/patches/patch.txt =================================================================== --- jedit4.2_test/patches/patch.txt (revision 0) +++ jedit4.2_test/patches/patch.txt (revision 0) @@ -0,0 +1,209 @@ +Index: C:/mol/wrk/ws/abbot.plain/test/abbot/util/NamedTimerTest.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/test/abbot/util/NamedTimerTest.java (revision 2056) ++++ C:/mol/wrk/ws/abbot.plain/test/abbot/util/NamedTimerTest.java (working copy) +@@ -21,7 +21,7 @@ + public void testSetName() throws Exception { + class Flag { volatile String name; } + final Flag flag = new Flag(); +- timer.schedule(new TimerTask() { ++ timer.schedule(new ExtendedTimerTask() { + public void run() { + flag.name = Thread.currentThread().getName(); + } +@@ -39,7 +39,7 @@ + public void testExceptionThrowingTimerTask() throws Exception { + class Flag { volatile boolean taskRan; } + final Flag flag = new Flag(); +- TimerTask task = new TimerTask() { ++ TimerTask task = new ExtendedTimerTask() { + public void run() { + try { + throw new RuntimeException("Purposely throwing"); +@@ -57,13 +57,13 @@ + Thread.yield(); + } + // This will throw an exception if the Timer was canceled +- timer.schedule(new TimerTask() { public void run() { }}, 0); ++ timer.schedule(new ExtendedTimerTask() { public void run() { }}, 0); + } + + public void testCancelTask() throws Exception { + class Flag { volatile boolean taskRan; } + final Flag flag = new Flag(); +- TimerTask task = new TimerTask() { ++ TimerTask task = new ExtendedTimerTask() { + public void run() { + flag.taskRan = true; + } +Index: C:/mol/wrk/ws/abbot.plain/src/abbot/tester/WindowTracker.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/src/abbot/tester/WindowTracker.java (revision 2056) ++++ C:/mol/wrk/ws/abbot.plain/src/abbot/tester/WindowTracker.java (working copy) +@@ -8,6 +8,7 @@ + + import abbot.Log; + import abbot.util.AWT; ++import abbot.util.ExtendedTimerTask; + import abbot.util.Properties; + import abbot.util.WeakAWTEventListener; + import abbot.util.NamedTimer; +@@ -369,7 +370,7 @@ + synchronized(openWindows) { + // At worst, time out and say the window is ready + // after the configurable delay +- TimerTask task = new TimerTask() { ++ TimerTask task = new ExtendedTimerTask() { + public void run() { + markWindowReady(w); + } +Index: C:/mol/wrk/ws/abbot.plain/src/abbot/util/PathClassLoader.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/src/abbot/util/PathClassLoader.java (revision 2056) ++++ C:/mol/wrk/ws/abbot.plain/src/abbot/util/PathClassLoader.java (working copy) +@@ -99,7 +99,11 @@ + + /** Taken from sun.misc.Launcher. */ + private static class Factory implements URLStreamHandlerFactory { +- private static final String PREFIX = "sun.net.www.protocol"; ++ private static final String PREFIX; ++ static { ++ PREFIX=System.getProperty("abbot.util.url_stream_handler_prefix", ++ "sun.net.www.protocol"); ++ } + private Factory() { } + public URLStreamHandler createURLStreamHandler(String protocol) { + String name = PREFIX + "." + protocol + ".Handler"; +Index: C:/mol/wrk/ws/abbot.plain/src/abbot/util/EventDispatchExceptionHandler.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/src/abbot/util/EventDispatchExceptionHandler.java (revision 2056) ++++ C:/mol/wrk/ws/abbot.plain/src/abbot/util/EventDispatchExceptionHandler.java (working copy) +@@ -53,6 +53,12 @@ + throw new IllegalStateException("Handler must not be installed from the event dispatch thread"); + } + ++ // Check if we don't want this hack ++ if (Boolean.getBoolean("abbot.util.do_not_install_handler")) { ++ Log.log("Skipped own handler for event dispatch exceptions installation"); ++ return; ++ } ++ + Class cls = getClass(); + final String className = cls.getName(); + try { +Index: C:/mol/wrk/ws/abbot.plain/src/abbot/util/ExtendedTimerTask.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/src/abbot/util/ExtendedTimerTask.java (revision 0) ++++ C:/mol/wrk/ws/abbot.plain/src/abbot/util/ExtendedTimerTask.java (revision 0) +@@ -0,0 +1,46 @@ ++package abbot.util; ++ ++import java.util.TimerTask; ++ ++/** ++ * ExtendedTimerTask instances may be checked on cancellation state. ++ * This class must be a base for all timer tasks scheduled in abbot.util.NamedTimer ++ * @see abbot.util.NamedTimer ++ */ ++public abstract class ExtendedTimerTask extends TimerTask { ++ /** ++ * 'false' initially, 'true' after cancel() invocation ++ */ ++ private boolean cancelled; ++ ++ /** ++ * Creates a new extended timer task ++ */ ++ protected ExtendedTimerTask() { ++ super(); ++ } ++ ++ /** ++ * @see java.util.TimerTask#run() ++ */ ++ public abstract void run(); ++ ++ /** ++ * @see java.util.TimerTask#cancel() ++ */ ++ public boolean cancel() { ++ cancelled = true; ++ return super.cancel(); ++ } ++ ++ /** ++ * Returns this timer task's cancellation state ++ * ++ * @return ++ * true if this timer task has been cancelled ++ * false otherwise ++ */ ++ public boolean isCancelled() { ++ return cancelled; ++ } ++} +Index: C:/mol/wrk/ws/abbot.plain/src/abbot/util/NamedTimer.java +=================================================================== +--- C:/mol/wrk/ws/abbot.plain/src/abbot/util/NamedTimer.java (revision 2056) ++++ C:/mol/wrk/ws/abbot.plain/src/abbot/util/NamedTimer.java (working copy) +@@ -1,7 +1,6 @@ + package abbot.util; + + import java.util.Timer; +-import java.lang.reflect.Field; + import java.util.TimerTask; + import java.util.Date; + import abbot.Log; +@@ -21,7 +20,7 @@ + /** Creates a named timer, optionally running as a daemon thread. */ + public NamedTimer(final String name, boolean isDaemon) { + super(isDaemon); +- schedule(new TimerTask() { ++ schedule(new ExtendedTimerTask() { + public void run() { + Thread.currentThread().setName(name); + } +@@ -40,12 +39,17 @@ + // cancel the wrapper when + + private class ProtectingTimerTask extends TimerTask { +- private TimerTask task; ++ private ExtendedTimerTask task; ++ /* ProtectingTimerTask ctor ++ * @param orig Timer task object to be wrapped ++ * @throws java.lang.ClassCastException if ++ * orig is not ExtendedTimerTask instance ++ */ + public ProtectingTimerTask(TimerTask orig) { +- this.task = orig; ++ this.task = (ExtendedTimerTask)orig; + } + public void run() { +- if (isCanceled()) { ++ if (task.isCancelled()) { + cancel(); + } + else { +@@ -53,20 +57,6 @@ + catch(Throwable thrown) { handleException(thrown); } + } + } +- private boolean isCanceled() { +- boolean canceled = false; +- final int CANCELED = 3; +- try { +- Field f = TimerTask.class.getDeclaredField("state"); +- f.setAccessible(true); +- int state = ((Integer)f.get(task)).intValue(); +- canceled = state == CANCELED; +- } +- catch(Exception e) { +- Log.warn(e); +- } +- return canceled; +- } + } + + public void schedule(TimerTask task, Date time) { + + Index: jedit4.2_test/scripts/jedit_fn_00.xml =================================================================== --- jedit4.2_test/scripts/jedit_fn_00.xml (revision 0) +++ jedit4.2_test/scripts/jedit_fn_00.xml (revision 0) @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: jedit4.2_test/scripts/jedit_st_00.xml =================================================================== --- jedit4.2_test/scripts/jedit_st_00.xml (revision 0) +++ jedit4.2_test/scripts/jedit_st_00.xml (revision 0) @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + Index: jedit4.2_test/scripts/jedit_st_01.xml =================================================================== --- jedit4.2_test/scripts/jedit_st_01.xml (revision 0) +++ jedit4.2_test/scripts/jedit_st_01.xml (revision 0) @@ -0,0 +1,504 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: jedit4.2_test/scripts/jedit_ln_00.xml =================================================================== --- jedit4.2_test/scripts/jedit_ln_00.xml (revision 0) +++ jedit4.2_test/scripts/jedit_ln_00.xml (revision 0) @@ -0,0 +1,26 @@ + + + + + + + + + + + + Index: jedit4.2_test/scripts/jedit_st_fixture.xml =================================================================== --- jedit4.2_test/scripts/jedit_st_fixture.xml (revision 0) +++ jedit4.2_test/scripts/jedit_st_fixture.xml (revision 0) @@ -0,0 +1,21 @@ + + + + + + + Index: jedit4.2_test/src/org/apache/harmony/guitests/JEditFunctionalTest.java =================================================================== --- jedit4.2_test/src/org/apache/harmony/guitests/JEditFunctionalTest.java (revision 0) +++ jedit4.2_test/src/org/apache/harmony/guitests/JEditFunctionalTest.java (revision 0) @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.harmony.guitests; + +import junit.extensions.abbot.ScriptFixture; + +/** + * This test launches jEdit application and checks that some work + * scenario can be performed in jEdit. The scenario (script) is played + * using Abbot Java GUI test automation framework + * (see http://sourceforge.net/projects/abbot). + */ +public class JEditFunctionalTest extends ScriptFixture { + + public JEditFunctionalTest(String name) { + super("../scripts/jedit_fn_00.xml"); + } + + public void test() throws Throwable { + runTest(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(JEditFunctionalTest.class); + } +} Index: jedit4.2_test/src/org/apache/harmony/guitests/JEditStressTest.java =================================================================== --- jedit4.2_test/src/org/apache/harmony/guitests/JEditStressTest.java (revision 0) +++ jedit4.2_test/src/org/apache/harmony/guitests/JEditStressTest.java (revision 0) @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.harmony.guitests; + +import junit.extensions.abbot.ScriptFixture; +import junit.framework.TestCase; + +/** + * This test launches jEdit application and checks that some work + * scenario can be performed in jEdit given number of times (iterations). + * The scenario (script) is played using Abbot Java GUI test automation + * framework (see http://sourceforge.net/projects/abbot). + */ +public class JEditStressTest extends TestCase { + + // test prolog script must be invoked once + private final RepeatableScript prolog = + new RepeatableScript("../scripts/jedit_st_00.xml"); + // test body script must be invoked specified + // number of times (ITERATIONS_NUMBER) + private final RepeatableScript loop = + new RepeatableScript("../scripts/jedit_st_01.xml"); + // test body iterations number + private final int ITERATIONS_NUMBER = + Integer.parseInt(System.getProperty("JEditStressTest.it_num", "1")); + + public JEditStressTest(String name) { + super(name); + } + + protected void setUp() throws Exception { + prolog.setUp(); + loop.setUp(); + } + + protected void tearDown() throws Exception { + loop.tearDown(); + prolog.tearDown(); + } + + public void test() throws Throwable { + prolog.runTest(1); + loop.runTest(ITERATIONS_NUMBER); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(JEditStressTest.class); + } + + // + // ScriptFixture Wrapper. + // Makes underlying test(script) repeatable. + // + private static class RepeatableScript extends ScriptFixture { + RepeatableScript(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + void runTest(int itNumber) throws Throwable { + for (int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: jedit4.2_test/build.properties =================================================================== --- jedit4.2_test/build.properties (revision 0) +++ jedit4.2_test/build.properties (revision 0) @@ -0,0 +1,94 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# BUILDTIME EDITABLE PARAMETERS ------------------ + +# +# For proxy connection uncomment and update +# accordingly the following two lines (needed for build phase only) +# +#http.proxy.host= +#http.proxy.port= + +# Directory where Harmony's jars located +# NOTE: +# - Always use forward slashes in your path here +# - Use the default value for CruiseControl integration. +# +harmony.boot.dir=${wdir}/projects/drlvm/trunk/build/${os}_${build_arch}_${cc}_${build_cfg}/deploy/jdk/jre/lib/boot + +# +# RUNTIME EDITABLE PARAMETERS ------------------ + +# +# Root location of the implementation under test +# (${test.java.home}/bin/java must be available). +# NOTE: +# - Always use forward slashes in your path here +# - Use the default value for CruiseControl integration. +# +test.java.home=${wdir}/projects/drlvm/trunk/build/${os}_${build_arch}_${cc}_${build_cfg}/deploy/jdk/jre + +# +# Number of iterations in "stress" test scenario +# +test.stress.iterations=2 + +# +# For test runs on Harmony's VMs leave the following three lines as is; +# For test runs on RI make the values empty as follows: +#test.vmarg.bootclasspath= +#test.vmarg.ush_prefix= +#test.vmarg.do_not_install_handler= +# +test.vmarg.bootclasspath=-Xbootclasspath/p:${basedir}/${harmony.patched.classes.dir} +test.vmarg.ush_prefix=-Dabbot.util.url_stream_handler_prefix=org.apache.harmony.luni.internal.net.www.protocol +test.vmarg.do_not_install_handler=-Dabbot.util.do_not_install_handler=true + + +# +# USUALLY THERE IS NOTHING TO EDIT BELOW THIS LINE ------------------ + +classes.dir=classes +harmony.patched.classes.dir=${classes.dir}/harmony +tests.src.dir=src +tests.classes.dir=${classes.dir}/tests +tests.report.dir=report +tests.working.dir=working + +download.dir=downloads +jedit.install.dir=jedit + +sf.download.url=http://prdownloads.sourceforge.net + +jedit.url=jedit +jedit.distr=jedit42install.jar +jedit.settings.backup.dir=.jedit.backup + +jedit.plugin.url=jedit-plugins +jedit.plugin.javastyle.distr=JavaStyle-1.2-bin.zip +jedit.plugin.jcompiler.distr=JCompiler-1.7.2-bin.zip +jedit.plugin.console.distr=Console-4.2.6.5-bin.zip +jedit.plugin.errlist.distr=ErrorList-1.4.2-bin.zip +jedit.plugin.jcore.distr=JavaCore-0.7.1-bin.zip +jedit.plugin.jaccomms.distr=JakartaCommons-0.4.4-bin.zip +jedit.plugin.pviewer.distr=ProjectViewer-2.1.3.5-bin.zip +jedit.plugin.commcntl.distr=CommonControls-0.9.1-bin.zip + +abbot.url=abbot +abbot.distr=abbot-1.0.0.rc5.zip +patched.src.dir=abbot-1.0.0.rc5/psrc +patched.jar=abbot-patched.jar Index: jedit4.2_test/readme.txt =================================================================== --- jedit4.2_test/readme.txt (revision 0) +++ jedit4.2_test/readme.txt (revision 0) @@ -0,0 +1,323 @@ +INTEL CONTRIBUTION TO APACHE HARMONY + January ??, 2007 +===================================== + +This archive contains the contribution to the Apache Harmony project from Intel. +The contribution contains the following component: + + - jEdit4.2 automated GUI test suite + +Main purpose of these tests is to make sure that implementation +under test (Harmony's VM's primarily) is able to run jEdit application +and an user is able to perform some work in jEdit. Tests automation is based +on Abbot Java GUI test automation framework (see http://abbot.sourceforge.net). + +The contribution contains three tests: + + - "launch" test; This test just checks that jEdit application + can be launched using runtime under test; + + - "functional" test; This test launches jEdit application and + checks that some standard work scenario can be performed in jEdit; + + - "stress" test; This test launches jEdit application and checks + that some work scenario (almost the same as in "functional" test) + can be performed in jEdit given number of times. + +All tests implemented as jUnit testcases. + +Also there is configuration file for CruiseControl system integration +(see http://sourceforge.net/projects/cruisecontrol). + + +This readme contains the following chapters: +-------------------------------------------- +1. ARCHIVE CONTENTS +2. TOOLS REQUIRED FOR THE BUILD +3. BUILDING + 3.1 BUILD ARTIFACTS +4. RUNNING TESTS + 4.1 ON HARMONY's VM + 4.2 ON RI + 4.3 TEST RUN ARTIFACTS +5. CRUISE CONTROL INTEGRATION +6. KNOWN ISSUES +7. TODO +8. DISCLAIMER AND LEGAL INFORMATION + + +1. ARCHIVE CONTENTS +------------------- + +The contribution contains test source files, test scripts and build/run environment. + +Here and below is the location into which you installed this +contribution. + +NOTE: + - To work properly under CruiseControl system with the provided config + the contribution must be integrated into the "buildtest" SVN souce tree + so as =/harmony/enhanced/buildtest/trunk/. + +After extracting the archive, the following files and directories appear under +/jedit4.2_test/ + + /jedit4.2_test/ + | + +-- build.xml - Ant build/run file + | + +-- build.properties - Ant build/run config. Usually + | it is the only file which should + | be modified in order to configure + | regular build/test-run process + | + +-- readme.txt - This text + | + +-- scenario.txt - "functional" scenario description + | + +-- cc.config.xml - CruiseControl integration config + | + +-- src/org/apache/harmony/guitests/ - Test sources + | | + | +-- JEditLaunchTest.java - "launch" test + | +-- JEditFunctionalTest.java - "functional" test + | +-- JEditStressTest.java - "stress" test + | + +-- scripts/ - Test scripts + | | + | +-- jedit_ln_00.xml - "launch" test script + | +-- jedit_fn_00.xml - "functional" test script + | +-- jedit_st_00.xml - "stress" test script prolog + | +-- jedit_st_01.xml - "stress" test script body + | +-- jedit_st_fixture.xml - "stress" test script support + | + +-- patches/ - Patches which enable Abbot + | framework on Harmony's runtime* + | + +-- patch.txt - Patch for Abbot classes + +-- harmony/java/awt/Toolkit.java - Patch for Harmony + +*) These small patches are temporary. + Corresponding Abbot patch is on the project's web-page already: + http://sourceforge.net/tracker/index.php?func=detail&aid=1618017&group_id=50939&atid=461492 + Harmony's patch contains stub for nonimplemented method + java.awt.Toolkit.getLockingKeyState and will be eliminated after + the method implementation. + + +2. TOOLS REQUIRED FOR THE BUILD +---------------------------------------------------------- + +To build Java** sources contained in the contribution, install and +configure the following tools in the user environment: + + Apache Ant - Build tool: Ant 1.6.5 or higher from http://ant.apache.org + + Junit - Testing framework 3.8.1 or higher from http://junit.org + + J2SDK 1.5.0 - J2SE** 1.5.0 compatible SDK, for example + http://java.sun.com/javase/downloads/index.jsp + + Patch - Utility for applying patches to source files. On Windows + you may use one from Cygwin distribution, for example v2.5.8 + from ftp://ftp.cise.ufl.edu/pub/mirrors/cygwin/release/patch/ + + +3. BUILDING +----------- + +1) Make sure that you have internet connection because external project + dependencies will be downloaded using it during build. If you connected + through proxy uncomment and update with actual info two related lines in + the beginning of 'build.properties' file + +2) Set in 'build.properties' file directory where Harmony's jars located + by modifying 'harmony.boot.dir' property + +NOTE: + - The default 'harmony.boot.dir' value (and variables used in it) + is suitable only for CruiseControl integration (described in chapter 5 below) + and should not be changed in that case + +3) Set/verify the values for the following environment variables: + + - PATH (Path on Windows) must contain the path to + path utility executable, ant bin/ and J2SDK bin/ directories; + - junit.jar must be in CLASSPATH + +4) Build tests by executing the following commands: + + cd /jedit4.2_test + ant setup + +NOTE: + - You may get help on build/run system usage by executing 'ant' + command without target specification in /jedit4.2_test/ directory. + +3.1 BUILD ARTIFACTS + +The build produces a set of additional directories placed in the following +tree structure (not fully expanded here): + + /jedit4.2_test/ + | + +-- abbot-1.0.0.rc5/ - Abbot framework (patched) + +-- classes/ + | | + | +-- harmony - Compiled Harmony patch + | +-- tests - Compiled test classes + | + +-- downloads/ - Downloaded external dependencies + +-- jedit/ - jEdit4.2final application + + +4. RUNNING TESTS +---------------- + +The tests may be run on both Harmony's VM's and on the RI. +At the moment of contribution all three tests pass on RI. +Only "launch" test passes on Harmony's VMs. Both "functional" +and "stress" tests fail after several successfull scenario steps +because of errors in Harmony's AWT/Swing implementation. + +There is no need in internet connection and patch executable +during tests run. + +4.1 ON HARMONY's VM +~~~~~~~~~~~~~~~~~~~ + +1) As for build process (step 2 above) set/verify + the values for PATH and CLASSPATH environment variables. + 'javac' must be in your PATH because "functional" and + "stress" test will execute it from within jEdit + +2) Configure runtime under test in 'build.properties' file + by modifying 'test.java.home' property's value. You must provide + full path to the root of Harmony's JRE here. + +NOTE: + - The default 'test.java.home' value (and variables used in it) + is suitable only for CruiseControl integration (described in chapter 5 below) + and must not be changed in that case + +3) Run the tests by executing the following commands: + + cd /jedit4.2_test + ant + + Where is one of + + launch + functional + stress + +NOTE: + - DO NOT TOUCH keyboard/mouse during test run. + - Use 'build.properties' file to set number of "stress" test iterations by + modifying 'test.stress.iterations' property's value (default is 2) + - FOR jEdit USERS: The tests need some initial jEdit configuration. Test run + system creates it before each new test run. If user's jEdit configuration + exists in user's home directory /.jedit/ it will be saved in + /.jedit.backup/ before the first test run. + + +4.2 ON RI +~~~~~~~~~ + +Do it exactly as described in 4.1 above with the following changes in step 2): + +2) Configure runtime under test in 'build.properties' file + by modifying 'test.java.home' property's value providing + full path to the root dir of RI's JRE (or root dir of RI's JDK); + Set 'test.vmarg.bootclasspath', 'test.vmarg.ush_prefix' and + 'test.vmarg.do_not_install_handler' properties' values in + 'build.properties' file to empty as follows: + + test.vmarg.bootclasspath= + test.vmarg.ush_prefix= + test.vmarg.do_not_install_handler= + +4.3 TEST RUN ARTIFACTS + +Any test run produces the following set of additional directories +(not expanded here): + + /jedit4.2_test/ + | + +-- report/ - Test run reports dir. Contains + | test run reports. Can be + | removed by 'clean.report' + | ant target invocation. + | + +-- working/ - Working directory for the tests. + Contains temporary files created + during test run. Removed/created + empty before each new test run. + + +5. CRUISE CONTROL INTEGRATION +----------------------------- + +There is sample configuration file for CruiseControl (CC) system integration +'cc.config.xml'. It includes 'classlib', 'drlvm' and 'jedit4.2_test' +CC projects. + +IMPORTANT: + To work properly under CC with the provided config the contribution must be + integrated into the "buildtest" SVN souce tree so as: + + =/harmony/enhanced/buildtest/trunk + +If this condition satisfied running jEdit tests under CC is very simple: + +1) build "buildtest" module and setup CC environment as described + in "buildtest" module documentation; + +2) Setup test build/run environment as described in chapters 3 (steps 1-3) +and 4.1 (step 2) above; + +3) cd into /cc and start CC system + by executing the following command (Windows): + + cruisecontrol.bat -configfile ..\jedit4.2_test\cc.config.xml + + On Linux execute: + + ./cruisecontrol.sh -configfile ../jedit4.2_test/cc.config.xml + +The tests will be built/run during the first 'jedit4.2_test' project invocation +under CC. All subsequent invocations will only run the tests. + + +6. KNOWN ISSUES +--------------- + +1. At the moment of this contribution only "launch" test passes on + Harmony's VMs. Both "functional" and "stress" tests fail after several + successfull scenario steps because of errors in Harmony's AWT/Swing + implementation. + +2. Because of 1 above only "launch" test can be integrated into CruiseControl + system at the moment of this contribution. It must be replaced with + "functional" one as soon as Harmony's AWT/Swing implementation improved. + +3. There are patches for both Harmony's classes and Abbot framework in the + contribution. However they are temporary. Corresponding Abbot patch is on + the project's web-page already: + + http://sourceforge.net/tracker/index.php?func=detail&aid=1618017&group_id=50939&atid=461492 + + Harmony's patch contains stub for nonimplemented method in class + java.awt.Toolkit and will be eliminated after the method implementation. + + +7. TODO +------- + +1. Eliminate Abbot/Harmony patches (see 3 in chapter 6 above). + + +8. DISCLAIMER AND LEGAL INFORMATION +------------------------------------ + +**) Other brands and names are the property of their respective owners. Index: jedit4.2_test/build.xml =================================================================== --- jedit4.2_test/build.xml (revision 0) +++ jedit4.2_test/build.xml (revision 0) @@ -0,0 +1,484 @@ + + + + + + + Main purpose: + Run automated GUI test scenarios for jEdit application (http://www.jedit.org/) + using Abbot Java GUI Test Framework (http://abbot.sourceforge.net) + on Harmony's DRLVM (http://harmony.apache.org) + + + + + + + + Builds/runs automated GUI tests for jEdit application (http://www.jedit.org) +using Abbot Java GUI Test Framework (http://abbot.sourceforge.net) on specified VM + +Usage: + + ant [help] + Displays this help + + ant setup + Builds jEdit tests + + ant launch + Runs jEdit launch test + + ant functional + Runs jEdit functional test + + ant stress + Runs jEdit stress test + + ant clean.report + Cleans jEdit test(s) report(s) + + ant clean.partial + Cleans all except dowloads + + ant clean + Cleans all + +Use 'build.properties' file to configure build/test-run process. +All configurable parameters are at the beginning of the file. + +Build/test run preconditions: + - Internet connection (only once during build for external dependencies downloads); + - Ant 1.6.5 or higher from http://ant.apache.org (ant binaries are in your PATH); + - J2SE 1.5 JDK ('java' and 'javac' must be in your PATH); + - Patch utility (must be in your PATH); + - Junit framework 3.8.1 or higher from http://junit.org ('junit.jar' in your CLASSPATH). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Proxy: ${http.proxy.host}:${http.proxy.port} + + + + + + + + + + + + + #jEdit properties +mode.java.commando.compile=javac +firstTime=false + + + + + + + + Your personal jEdit settings have been backed up in + ${user.home}/${jedit.settings.backup.dir} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +