Package generic.test

Class AbstractGenericTest

java.lang.Object
generic.test.AbstractGTest
generic.test.AbstractGenericTest
Direct Known Subclasses:
AbstractDockingTest

public abstract class AbstractGenericTest extends AbstractGTest
  • Field Details

    • TESTDATA_DIRECTORY_NAME

      public static final String TESTDATA_DIRECTORY_NAME
      See Also:
    • DEFAULT_TOOL_NAME

      public static final String DEFAULT_TOOL_NAME
      See Also:
    • DEFAULT_TEST_TOOL_NAME

      public static final String DEFAULT_TEST_TOOL_NAME
      See Also:
    • watchman

      public org.junit.rules.TestWatcher watchman
    • concurrentTestExceptionRule

      public org.junit.rules.TestRule concurrentTestExceptionRule
    • ruleChain

      public org.junit.rules.RuleChain ruleChain
    • repeatedRule

      public org.junit.rules.TestRule repeatedRule
      This rule handles the Repeated annotation

      During batch mode, this rule should never be needed. This rule is included here as a convenience, in case a developer wants to use the Repeated annotation to diagnose a non-deterministic test failure. Without this rule, the annotation would be silently ignored.

  • Constructor Details

    • AbstractGenericTest

      public AbstractGenericTest()
  • Method Details

    • initializeSystemProperties

      protected void initializeSystemProperties()
      A place to initialize and needed static properties
    • initializeLayout

      protected void initializeLayout(ApplicationLayout layout)
      A method to update any ApplicationLayout values
      Parameters:
      layout - the layout to initialize
    • createApplicationLayout

      protected ApplicationLayout createApplicationLayout()
    • createApplicationConfiguration

      protected ApplicationConfiguration createApplicationConfiguration()
    • hasTestFailed

      protected boolean hasTestFailed()
      Determine if test failure occur (for use within tear down methods)
      Returns:
      true if test failure detected
    • testFailed

      protected void testFailed(Throwable e)
      A callback for subclasses when a test has failed. This will be called after tearDown(). This means that any diagnostics will have to take into account items that have already been disposed.
      Parameters:
      e - the exception that happened when the test failed
    • windowForComponent

      public static Window windowForComponent(Component c)
      Returns the window parent of c. If c is a window, then c is returned.

      Warning: this differs from SwingUtilities.windowForComponent(Component) in that the latter method will not return the given component if it is a window.

      Parameters:
      c - the component
      Returns:
      the window
    • getAllWindows

      public static Set<Window> getAllWindows()
      Gets all windows in the system (including Frames).
      Returns:
      all windows
    • getLocalResourceFile

      public File getLocalResourceFile(String relativePath)
    • loadTextResource

      public static List<String> loadTextResource(Class<?> cls, String name) throws IOException
      Load a text resource file into an ArrayList. Each line of the file is stored as an item in the list.
      Parameters:
      cls - class where resource exists
      name - resource filename
      Returns:
      list of lines contained in file
      Throws:
      IOException - if an exception occurs reading the given resource
    • loadTextResource

      public static ArrayList<String> loadTextResource(String name) throws IOException
      Throws:
      IOException
    • getTestDataFile

      public static File getTestDataFile(String path) throws FileNotFoundException
      Returns the file within the data directory of the TestResources module that matches the given relative path

      A FileNotFoundException is throw if the file does not exist.

      Parameters:
      path - path relative to the data directory of the TestResources module.
      Returns:
      the file within the data directory of the TestResources module that matches the given relative path
      Throws:
      FileNotFoundException - if the given file does not exist
    • getTestDataDir

      public static File getTestDataDir(String relativePath) throws FileNotFoundException, IOException
      Returns a file that points to the location on disk of the given relative path name. The path is relative to the test resources directory.
      Parameters:
      relativePath - the path of the file
      Returns:
      a file that points to the location on disk of the relative path.
      Throws:
      FileNotFoundException - If the directory does not exist
      IOException - if the given path does not represent a directory
    • findTestDataFile

      public static File findTestDataFile(String path)
      Returns the file within the data directory of the TestResources module that matches the given relative path.

      Null is returned if the file could not be found.

      Parameters:
      path - path relative to the data directory of the TestResources module.
      Returns:
      the file within the data directory of the TestResources module that matches the given relative path
    • getTestDataDirectory

      public static File getTestDataDirectory()
      Returns the data directory containing test programs and data
      Returns:
      the data directory containing test programs and data
    • printMemory

      public static void printMemory()
    • waitForTasks

      public static void waitForTasks()
      Waits for all system tasks to complete. These tasks are tracked by the SystemUtilities during testing only.
      Throws:
      junit.framework.AssertionFailedError - if the timeout period expires while waiting for tasks
    • waitForPostedSwingRunnables

      public static void waitForPostedSwingRunnables()
    • findComponent

      public static <T extends Component> T findComponent(Container parent, Class<T> desiredClass)
    • findComponent

      public static <T extends Component> T findComponent(Container parent, Class<T> desiredClass, boolean checkOwnedWindows)
    • getInstanceFieldByClassType

      public static <T> T getInstanceFieldByClassType(Class<T> classType, Object ownerInstance)
      Get the first field object contained within object ownerInstance which has the type classType. This method is only really useful if it is known that only a single field of classType exists within the ownerInstance.
      Type Parameters:
      T - the type
      Parameters:
      classType - the class type of the desired field
      ownerInstance - the object instance that owns the field
      Returns:
      field object of type classType or null
    • setInstanceField

      public static void setInstanceField(String fieldName, Object ownerInstance, Object value) throws RuntimeException
      Sets the instance field by the given name on the given object instance.

      Note: if the field is static, then the ownerInstance field can be the class of the object that contains the variable.

      Parameters:
      fieldName - The name of the field to retrieve.
      ownerInstance - The object instance from which to get the variable instance.
      value - The value to use when setting the given field
      Throws:
      RuntimeException - if there is a problem accessing the field using reflection. A RuntimeException is used so that calling tests can avoid using a try/catch block, but will still fail when an error is encountered.
      See Also:
    • getInstanceField

      public static Object getInstanceField(String fieldName, Object ownerInstance) throws RuntimeException
      Gets the instance field by the given name on the given object instance. The value is a primitive wrapper if it is a primitive type.

      Note: if the field is static, then the ownerInstance field can be the class of the object that contains the variable.

      Parameters:
      fieldName - The name of the field to retrieve.
      ownerInstance - The object instance from which to get the variable instance.
      Returns:
      The field instance.
      Throws:
      RuntimeException - if there is a problem accessing the field using reflection. A RuntimeException is used so that calling tests can avoid using a try/catch block, but will still fail when an error is encountered.
      Since:
      Tracker Id 267
      See Also:
    • invokeConstructor

      public static Object invokeConstructor(Class<?> containingClass, Class<?>[] parameterTypes, Object[] args) throws RuntimeException
      Uses reflection to execute the constructor for the given class with the given parameters. The new instance of the given class will be returned.

      Parameters:
      containingClass - The class that contains the desired constructor.
      parameterTypes - The parameter types that the constructor takes. This value can be null or zero length if there are no parameters to pass
      args - The parameter values that should be passed to the constructor. This value can be null or zero length if there are no parameters to pass
      Returns:
      The new class instance
      Throws:
      RuntimeException - if there is a problem accessing the constructor using reflection. A RuntimeException is used so that calling tests can avoid using a try/catch block, but will still fail when an error is encountered.
    • invokeInstanceMethod

      public static Object invokeInstanceMethod(String methodName, Object ownerInstance, Class<?>[] parameterTypes, Object[] args) throws RuntimeException
      Uses reflection to execute the method denoted by the given method name. If any value is returned from the method execution, then it will be returned from this method. Otherwise, null is returned.

      Note: if the method is static, then the ownerInstance field can be the class of the object that contains the method.

      Parameters:
      methodName - The name of the method to execute.
      ownerInstance - The object instance of which the method will be executed.
      parameterTypes - The parameter types that the method takes.
      args - The parameter values that should be passed to the method. This value can be null or zero length if there are no parameters to pass
      Returns:
      The return value as returned from executing the method.
      Throws:
      RuntimeException - if there is a problem accessing the field using reflection. A RuntimeException is used so that calling tests can avoid using a try/catch block, but will still fail when an error is encountered.
      Since:
      Tracker Id 267
      See Also:
    • invokeInstanceMethod

      public static Object invokeInstanceMethod(String methodName, Object ownerInstance) throws RuntimeException
      This method is just a "pass through" method for invokeInstanceMethod(String, Object, Class[], Object[]) so that callers do not need to pass null to that method when the underlying instance method does not have any parameters.
      Parameters:
      methodName - The name of the method to execute.
      ownerInstance - The object instance of which the method will be executed.
      Returns:
      The return value as returned from executing the method.
      Throws:
      RuntimeException - if there is a problem accessing the field using reflection. A RuntimeException is used so that calling tests can avoid using a try/catch block, but will still fail when an error is encountered.
      See Also:
    • findOwnedWindows

      public static void findOwnedWindows(Window win, Set<Window> winList)
    • pressButtonByText

      public static void pressButtonByText(Container container, String buttonText)
      Finds the button with the indicated TEXT that is a sub-component of the indicated container, and then programmatically presses the button.
      The following is a sample JUnit test use:
       env.showTool();
       OptionDialog dialog = (OptionDialog) env.waitForDialog(OptionDialog.class, 1000);
       assertNotNull(dialog);
       pressButtonByText(dialog, "OK");
       
      Parameters:
      container - the container to search. (Typically a dialog.)
      buttonText - the text on the desired JButton.
      Throws:
      AssertionError - if the button isn't found, isn't showing or isn't enabled
    • pressButtonByText

      public static void pressButtonByText(Container container, String buttonText, boolean waitForCompletion)
      Finds the button with the indicated TEXT that is a sub-component of the indicated container, and then programmatically presses the button.
      Parameters:
      container - the container to search. (Typically a dialog.)
      buttonText - the text on the desired JButton.
      waitForCompletion - if true wait for action to complete before returning, otherwise schedule action to be performed and return immediately.
      Throws:
      AssertionError - if the button isn't found, isn't showing or isn't enabled
    • pressButtonByName

      public static void pressButtonByName(Container container, String buttonName)
      Finds the button with the indicated NAME that is a subcomponent of the indicated container, and then programmatically presses the button.
      Parameters:
      container - the container to search. (Typically a dialog)
      buttonName - the name on the desired AbstractButton (see Component.setName())
    • pressButtonByName

      public static void pressButtonByName(Container container, String buttonName, boolean waitForCompletion)
      Finds the button with the indicated NAME that is a subcomponent of the indicated container, and then programmatically presses the button.
      Parameters:
      container - the container to search. (Typically a dialog.)
      buttonName - the name on the desired AbstractButton (see Component.setName()).
      waitForCompletion - if true wait for action to complete before returning, otherwise schedule action to be performed and return immediately
    • pressButton

      public static void pressButton(AbstractButton button)
      Programmatically presses the indicated button.
      Parameters:
      button - the button
    • pressButton

      public static void pressButton(AbstractButton button, boolean waitForCompletion)
      Programmatically presses the indicated button.
      Parameters:
      button - the button
      waitForCompletion - if true wait for action to complete before returning, otherwise schedule action to be performed and return immediately.
    • findComponentByName

      public static Component findComponentByName(Container container, String componentName)
      Searches the subcomponents of the indicated container and returns the component with the specified name.
      Parameters:
      container - the container to search
      componentName - the name of the desired component
      Returns:
      the component, or null if not found
    • findComponentByName

      public static Component findComponentByName(Container container, String componentName, boolean checkOwnedWindows)
    • findComponentsByName

      public static List<Component> findComponentsByName(Container container, String componentName, boolean checkOwnedWindows)
    • findButtonByIcon

      public static JButton findButtonByIcon(Container container, Icon icon)
    • findButtonByText

      public static JButton findButtonByText(Container container, String text)
      Searches the subcomponents of the the given container and returns the JButton that has the specified text.
      Parameters:
      container - the container to search
      text - the button text
      Returns:
      the JButton, or null the button was not found
    • findAbstractButtonByText

      public static AbstractButton findAbstractButtonByText(Container container, String text)
      Searches the sub-components of the given container and returns the AbstractButton that has the specified text.

      This differs from findButtonByText(Container, String) in that this method will find buttons that do not extend from JButton. That method is convenient when you do not wish to cast the result from AbstractButton to JButton. Other than that, this method can handle all cases the other method cannot.

      Parameters:
      container - container to search
      text - button text
      Returns:
      null if the button was not found
    • findAbstractButtonByName

      public static AbstractButton findAbstractButtonByName(Container container, String name)
      Searches the sub-components of the given container and returns the AbstractButton that has the specified name.
      Parameters:
      container - container to search
      name - the button name (you must set this manually).
      Returns:
      null if the button was not found
    • leftClick

      public static void leftClick(JComponent comp, int x, int y)
    • middleClick

      public static void middleClick(JComponent comp, int x, int y)
    • rightClick

      public static void rightClick(JComponent comp, int x, int y)
    • doubleClick

      public static void doubleClick(JComponent comp, int x, int y)
    • clickMouse

      public static void clickMouse(Component comp, int button, int x, int y, int clickCount, int modifiers, boolean popupTrigger)
      Simulates click the mouse button.
      Parameters:
      comp - the component to click on.
      button - the mouse button (1, 2, or 3)
      x - the x coordinate of the click location
      y - the y coordinate of the click location
      clickCount - the number of clicks (2 = double click)
      modifiers - additional modifiers (e.g. MouseEvent.SHIFT_MASK)
      popupTrigger - a boolean, true if this event is a trigger for a popup menu
    • clickMouse

      public static void clickMouse(Component comp, int button, int x, int y, int clickCount, int modifiers)
      Simulates click the mouse button.
      Parameters:
      comp - the component to click on.
      button - the mouse button (1, 2, or 3)
      x - the x coordinate of the click location
      y - the y coordinate of the click location
      clickCount - the number of clicks (2 = double click)
      modifiers - additional modifiers (e.g. MouseEvent.SHIFT_MASK)
    • dragMouse

      public static void dragMouse(Component comp, int button, int startX, int startY, int endX, int endY, int modifiers)
      Simulates a mouse drag action
      Parameters:
      comp - the component to drag on.
      button - the mouse button (1, 2, or 3)
      startX - the x coordinate of the start drag location
      startY - the y coordinate of the start drag location
      endX - the x coordinate of the end drag location
      endY - the y coordinate of the end drag location
      modifiers - additional modifiers (e.g. MouseEvent.SHIFT_MASK)
    • moveMouse

      public static void moveMouse(Component comp, int x, int y)
      Fire a mouse moved event for the given component.
      Parameters:
      comp - source of the event.
      x - x position relative to the component
      y - y position relative to the component
    • postEvent

      public static void postEvent(AWTEvent ev)
    • runSwing

      public static <T> T runSwing(Supplier<T> s)
      Returns the value from the given Supplier, invoking the call in the Swing thread. This is useful when you may have values that are being changed on the Swing thread and you need the test thread to see the changes.
      Parameters:
      s - the supplier
      Returns:
      the value returned by the supplier
    • runSwing

      public static void runSwing(Runnable r)
      Run the given code snippet on the Swing thread and wait for it to finish
      Parameters:
      r - the runnable code snippet
    • runSwingLater

      public void runSwingLater(Runnable r)
      Run the given code snippet on the Swing thread later, not blocking the current thread. Use this if the code snippet causes a blocking operation.

      This is a shortcut for runSwing(r, false);.

      Parameters:
      r - the runnable code snippet
    • runSwingWithException

      public static <E extends Exception> void runSwingWithException(ExceptionalCallback<E> callback) throws Exception
      Call this version of runSwing(Runnable) when you expect your runnable may throw exceptions
      Parameters:
      callback - the runnable code snippet to call
      Throws:
      Exception - any exception that is thrown on the Swing thread
    • runSwing

      public static void runSwing(Runnable runnable, boolean wait)
    • executeOnSwingWithoutBlocking

      public static void executeOnSwingWithoutBlocking(Runnable runnable)
      Launches the runnable on a new thread so as to not block the calling thread. This is very useful for performing actions on the Swing thread that show modal dialogs, which would otherwise block the calling thread, such as a testing thread.
      Parameters:
      runnable - The runnable that will be executed in a new Thread that will place the runnable on the Swing thread.
    • clickTableCell

      public static void clickTableCell(JTable table, int row, int col, int clickCount)
    • clickListRange

      public static void clickListRange(JList<?> list, int row, int count)
      Clicks a range of items in a list (simulates holding SHIFT and selecting each item in the range in-turn)
      Parameters:
      list - the list to select from
      row - the initial index
      count - the number of rows to select
    • clickTableRange

      public static void clickTableRange(JTable table, int row, int count)
      Clicks a range of items in a table (simulates holding SHIFT and selecting each item in the range)
      Parameters:
      table - the table to select
      row - the starting row index
      count - the number of rows to select
    • editCell

      public static TableCellEditor editCell(JTable table, int row, int col)
    • getRenderedTableCellValue

      public static String getRenderedTableCellValue(JTable table, int row, int column)
      Gets the rendered value for the specified table cell. The actual value at the cell may not be a String. This method will get the String display value, as created by the table.
      Parameters:
      table - the table to query
      row - the row to query
      column - the column to query
      Returns:
      the String value
      Throws:
      IllegalArgumentException - if there is no renderer or the rendered component is something from which this method can get a String (such as a JLabel)
    • setComboBoxSelection

      public static <T> void setComboBoxSelection(JComboBox<T> comboField, T selection)
    • setText

      public static void setText(JTextComponent field, String text)
    • getText

      public static String getText(JTextComponent field)
    • findTreePathToText

      public static TreePath findTreePathToText(JTree tree, String text)
      Finds the path of a tree node in the indicated tree with the specified text. The matching tree node is determined by comparing the specified text with the string returned by the tree node's toString() method.
      Note: This method affects the expansion state of the tree. It will expand nodes starting at the root until a match is found or all of the tree is checked.
      Parameters:
      tree - the tree
      text - the tree node's text
      Returns:
      the tree path
    • findPathToText

      protected static TreePath findPathToText(JTree tree, TreePath startTreePath, String text)
      Performs a depth first search for the named tree node.
      Parameters:
      tree - the tree to search
      startTreePath - path indicating node to begin searching from in the tree
      text - the name of the node to find
      Returns:
      the path to the named node or null if it can't be found.
    • createStackTraceForAllThreads

      public static String createStackTraceForAllThreads()
      Returns a string which is a printout of a stack trace for each thread running in the current JVM
      Returns:
      the stack trace string
    • toString

      public static String toString(Collection<?> collection)
      Prints the contents of the given collection by way of the Object.toString() method.
      Parameters:
      collection - The contents of which to print
      Returns:
      A string representation of the given collection
    • fixupGUI

      public static void fixupGUI() throws InterruptedException, InvocationTargetException
      Invoke fixupGUI at the beginning of your JUnit test or in its setup() method to make your GUI for the JUnit test appear using the system Look and Feel. The system look and feel is the default that Ghidra uses. This will also change the default fonts for the JUnit test to be the same as those in Ghidra.
      Throws:
      InterruptedException - if we're interrupted while waiting for the event dispatching thread to finish excecuting doRun.run()
      InvocationTargetException - if an exception is thrown while running doRun
    • getFontMetrics

      public static FontMetrics getFontMetrics(Font font)
      Returns a font metrics for the given font using a generic buffered image graphics context.
      Parameters:
      font - the font
      Returns:
      the font metrics
    • setErrorsExpected

      public static void setErrorsExpected(boolean expected)
      Signals that the client expected the System Under Test (SUT) to report errors. Use this when you wish to verify that errors are reported and you do not want those errors to fail the test. The default value for this setting is false, which means that any errors reported will fail the running test.
      Parameters:
      expected - true if errors are expected.
    • waitForSwing

      public static boolean waitForSwing()
      Waits for the Swing thread to process any pending events. This method also waits for any SwingUpdateManagers that have pending events to be flushed.
      Returns:
      true if the any SwingUpdateManagers were busy.
    • privateWaitForPostedSwingRunnables_SwingSafe

      @Deprecated public static void privateWaitForPostedSwingRunnables_SwingSafe()
      Deprecated.
      This is not a test writer's method, but instead an infrastructure method.
      This is only for internal use. If you need to wait for the Swing thread from your test, then use waitForSwing().
    • yieldToSwing

      protected static void yieldToSwing()
    • getDebugFileDirectory

      public static File getDebugFileDirectory()
      Returns the directory into which tests can write debug files, such as files containing print statements or image files.

      This is not a temporary directory that will be deleted between tests, which is useful in that the debug files will persist after a test run.

      Examples of this directory:

      • server: {share dir}/junits.new/JunitTest_version/reports
      • local gradle: {user home}/git/{repo}/ghidra/build/JUnit/reports
      • eclipse: {module}/bin/
      Returns:
      the directory
    • createTempDirectory

      public static File createTempDirectory(String name) throws IOException
      Creates a sub-directory with the given name as a child of the Java temp directory. The given name will be the prefix of the new directory name, with any additional text as created by Files.createTempDirectory(Path, String, java.nio.file.attribute.FileAttribute...). Any left-over test directories will be cleaned-up before creating the new directory.

      Note: you should not call this method multiple times, as each call will cleanup the previously created directories.

      Parameters:
      name - the name of the directory to create
      Returns:
      the newly created directory
      Throws:
      IOException - of there is a problem creating the new directory
    • createTempFilePath

      public String createTempFilePath(String name) throws IOException
      Creates a file path with a filename that is under the system temp directory. The path returned will not point to an existing file. The suffix of the file will be .tmp.
      Parameters:
      name - the filename
      Returns:
      a new file path
      Throws:
      IOException - if there is any problem ensuring that the created path is non-existent
      See Also:
    • createTempFilePath

      public String createTempFilePath(String name, String extension) throws IOException
      Creates a file path with a filename that is under the system temp directory. The path returned will not point to an existing file. This method is the same as createTempFilePath(String), except that you must provide the extension.
      Parameters:
      name - the filename
      extension - the file extension
      Returns:
      a new file path
      Throws:
      IOException - if there is any problem ensuring that the created path is non-existent
      See Also:
    • createTempFileForTest

      public File createTempFileForTest() throws IOException
      Creates a temp file for the current test, using the test name as a prefix for the filename. This method calls createTempFile(String), which will cleanup any pre-existing temp files whose name pattern matches this test name. This helps to avoid old temp files from accumulating.
      Returns:
      the new temp file
      Throws:
      IOException - if there is a problem creating the new file
    • createTempFileForTest

      public File createTempFileForTest(String suffix) throws IOException
      Creates a temp file for the current test, using the test name as a prefix for the filename. This method calls createTempFile(String), which will cleanup any pre-existing temp files whose name pattern matches this test name. This helps to avoid old temp files from accumulating.
      Parameters:
      suffix - the suffix to provide for the temp file
      Returns:
      the new temp file
      Throws:
      IOException - if there is a problem creating the new file
    • createTempFile

      public File createTempFile(String name) throws IOException
      Creates a file in the Java temp directory using the given name as a prefix and the given suffix. The final filename will also include the current test name, as well as any data added by File.createTempFile(String, String). The file suffix will be .tmp

      The file will be marked to delete on JVM exit. This will not work if the JVM is taken down the hard way, as when pressing the stop button in Eclipse.

      Parameters:
      name - the prefix to put on the file, before the test name
      Returns:
      the newly created file
      Throws:
      IOException - if there is a problem creating the new file
      See Also:
    • createTempFile

      public File createTempFile(String name, String suffix) throws IOException
      Creates a file in the Java temp directory using the given name as a prefix and the given suffix. The final filename will also include the current test name, as well as any data added by File.createTempFile(String, String).

      The file will be marked to delete on JVM exit. This will not work if the JVM is taken down the hard way, as when pressing the stop button in Eclipse.

      Note: This method will create the file on disk! If you need the file to not exist, then you must delete the file yourself. Alternatively, you could instead call createTempFilePath(String, String), which will ensure that the created temp file is deleted.

      Finally, this method will delete any files that match the given name and suffix values before creating the given temp file. This is important, as it will delete any files already created by the test that match this info.

      Parameters:
      name - the prefix to put on the file, before the test name
      suffix - the file suffix
      Returns:
      the newly created file
      Throws:
      IOException - if there is a problem creating the new file
      See Also:
    • deleteSimilarTempFiles

      public static void deleteSimilarTempFiles(String nameText)
      Delete any files under the Java temp directory that have the given text in their name.
      Parameters:
      nameText - the partial name text to match against the files
      See Also:
    • deleteMatchingTempFiles

      public static void deleteMatchingTempFiles(String namePattern)
      Delete any files under the this test case's specific temp directory that match the give regex Pattern
      Parameters:
      namePattern - the pattern to match against the files
      See Also: