From 617e69c2f15322fac592377abcc3305dc4b342eb Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:27:38 -0500 Subject: [PATCH] Test fixes --- .../byteviewer/ByteViewerPlugin2Test.java | 820 +++++++++--------- .../table/threaded/IncrementalLoadJob.java | 3 +- 2 files changed, 395 insertions(+), 428 deletions(-) diff --git a/Ghidra/Features/ByteViewer/src/test.slow/java/ghidra/app/plugin/core/byteviewer/ByteViewerPlugin2Test.java b/Ghidra/Features/ByteViewer/src/test.slow/java/ghidra/app/plugin/core/byteviewer/ByteViewerPlugin2Test.java index 57802da619..62bec52378 100644 --- a/Ghidra/Features/ByteViewer/src/test.slow/java/ghidra/app/plugin/core/byteviewer/ByteViewerPlugin2Test.java +++ b/Ghidra/Features/ByteViewer/src/test.slow/java/ghidra/app/plugin/core/byteviewer/ByteViewerPlugin2Test.java @@ -4,9 +4,9 @@ * Licensed 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. @@ -15,16 +15,19 @@ */ package ghidra.app.plugin.core.byteviewer; +import static java.awt.event.InputEvent.*; import static org.junit.Assert.*; import java.awt.*; -import java.awt.event.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.math.BigInteger; import java.util.Date; import java.util.List; import java.util.Map; -import javax.swing.*; +import javax.swing.JCheckBox; +import javax.swing.JLabel; import org.junit.*; @@ -42,7 +45,6 @@ import ghidra.app.services.GoToService; import ghidra.app.services.ProgramManager; import ghidra.app.util.bean.FixedBitSizeValueField; import ghidra.framework.options.Options; -import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; import ghidra.program.database.ProgramBuilder; import ghidra.program.model.address.Address; @@ -56,6 +58,7 @@ import ghidra.program.util.ProgramLocation; import ghidra.test.AbstractGhidraHeadedIntegrationTest; import ghidra.test.TestEnv; import ghidra.util.task.TaskMonitor; +import utility.function.ExceptionalCallback; /** * Test editing in the Byte Viewer. @@ -71,45 +74,28 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { private ByteViewerPanel panel; private CodeBrowserPlugin cbPlugin; - /** - * Constructor for ByteViewerPlugin3Test. - * @param arg0 - */ - public ByteViewerPlugin2Test() { - super(); - } - - /* - * @see TestCase#setUp() - */ @Before public void setUp() throws Exception { env = new TestEnv(); - try { - tool = env.getTool(); - tool.addPlugin(GoToAddressLabelPlugin.class.getName()); - tool.addPlugin(NavigationHistoryPlugin.class.getName()); - tool.addPlugin(NextPrevAddressPlugin.class.getName()); - tool.addPlugin(CodeBrowserPlugin.class.getName()); + tool = env.getTool(); + tool.addPlugin(GoToAddressLabelPlugin.class.getName()); + tool.addPlugin(NavigationHistoryPlugin.class.getName()); + tool.addPlugin(NextPrevAddressPlugin.class.getName()); + tool.addPlugin(CodeBrowserPlugin.class.getName()); - tool.addPlugin(ByteViewerPlugin.class.getName()); + tool.addPlugin(ByteViewerPlugin.class.getName()); - plugin = env.getPlugin(ByteViewerPlugin.class); - tool.showComponentProvider(plugin.getProvider(), true); - cbPlugin = env.getPlugin(CodeBrowserPlugin.class); + plugin = env.getPlugin(ByteViewerPlugin.class); + tool.showComponentProvider(plugin.getProvider(), true); + cbPlugin = env.getPlugin(CodeBrowserPlugin.class); - program = buildNotepad(); - memory = program.getMemory(); - listing = program.getListing(); - ProgramManager pm = tool.getService(ProgramManager.class); - pm.openProgram(program.getDomainFile()); - panel = plugin.getProvider().getByteViewerPanel(); - waitForSwing(); - } - catch (Exception e) { - env.dispose(); - throw e; - } + program = buildNotepad(); + memory = program.getMemory(); + listing = program.getListing(); + ProgramManager pm = tool.getService(ProgramManager.class); + pm.openProgram(program.getDomainFile()); + panel = plugin.getProvider().getByteViewerPanel(); + waitForSwing(); } private Program buildNotepad() throws Exception { @@ -124,12 +110,8 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { return p; } - /* - * @see TestCase#tearDown() - */ @After public void tearDown() throws Exception { - env.release(program); env.dispose(); } @@ -137,34 +119,36 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { public void testEditModeHex() throws Exception { env.showTool(); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001000)); + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); assertTrue(action.isSelected()); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + assertEquals((byte) 0xa0, program.getMemory().getByte(getAddr(0x01001000))); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, ((ByteField) c.getCurrentField()).getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -176,30 +160,30 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); Address addr = getAddr(0x01002000); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(addr); + FieldLocation loc = getFieldLocation(addr); byte b = memory.getByte(addr); assertEquals((byte) 0x50, b); assertEquals(256, loc.getIndex().intValue()); assertEquals(0, loc.getFieldNum()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); assertTrue(action.isSelected()); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); }); - Thread.sleep(100); + program.flushEvents(); waitForSwing(); assertEquals(b, program.getMemory().getByte(addr)); @@ -221,33 +205,32 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { waitForSwing(); - int transactionID = program.startTransaction("test"); - final Address addr = getAddr(0x01001530); - StructureDataType dt = new StructureDataType("test", 0); - for (int i = 0; i < 7; i++) { - dt.add(new ByteDataType()); - } - listing.createData(addr, dt, dt.getLength()); - program.endTransaction(transactionID, true); + Address addr = getAddr(0x01001530); + txSwing(() -> { + StructureDataType dt = new StructureDataType("test", 0); + for (int i = 0; i < 7; i++) { + dt.add(new ByteDataType()); + } + listing.createData(addr, dt, dt.getLength()); + }); - program.flushEvents(); - waitForSwing(); - - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + assertEquals((byte) 0xa0, program.getMemory().getByte(addr)); FieldLocation loc = getFieldLocation(addr); ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); @@ -263,50 +246,48 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { GoToService goToService = tool.getService(GoToService.class); goToService.goTo(new ProgramLocation(program, getAddr(01001530))); - waitForSwing(); - int transactionID = program.startTransaction("test"); - final Address addr = getAddr(0x01001530); - StructureDataType dt = new StructureDataType("test", 0); - for (int i = 0; i < 7; i++) { - dt.add(new ByteDataType()); - } - listing.createData(addr, dt, dt.getLength()); - program.endTransaction(transactionID, true); + Address addr = getAddr(0x01001530); + txSwing(() -> { + StructureDataType dt = new StructureDataType("test", 0); + for (int i = 0; i < 7; i++) { + dt.add(new ByteDataType()); + } + listing.createData(addr, dt, dt.getLength()); + }); - program.flushEvents(); - waitForSwing(); - - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + assertEquals((byte) 0xa0, program.getMemory().getByte(addr)); FieldLocation loc = getFieldLocation(addr); ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground()); - final ByteViewerComponent asciiC = findComponent(panel, "Ascii"); - SwingUtilities.invokeAndWait(() -> panel.setCurrentView(asciiC)); + ByteViewerComponent asciiC = findComponent(panel, "Ascii"); + runSwing(() -> panel.setCurrentView(asciiC)); loc = getFieldLocation(addr); field = asciiC.getField(loc.getIndex(), loc.getFieldNum()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground()); - final ByteViewerComponent hexIntC = findComponent(panel, "Hex Integer"); - SwingUtilities.invokeAndWait(() -> panel.setCurrentView(hexIntC)); + ByteViewerComponent hexIntC = findComponent(panel, "Hex Integer"); + runSwing(() -> panel.setCurrentView(hexIntC)); loc = getFieldLocation(addr); field = asciiC.getField(loc.getIndex(), loc.getFieldNum()); @@ -316,30 +297,33 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedo() throws Exception { env.showTool(); - final Address addr = getAddr(0x01001000); - final ToggleDockingAction action = + Address addr = getAddr(0x01001000); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent c = panel.getCurrentComponent(); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); byte value = program.getMemory().getByte(addr); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + assertEquals((byte) 0xa0, memory.getByte(addr)); undo(program); program.flushEvents(); + waitForSwing(); assertEquals(value, memory.getByte(addr)); FieldLocation loc = getFieldLocation(addr); @@ -360,19 +344,17 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedo2() throws Exception { - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - tool.removePlugins(new Plugin[] { cbPlugin }); + + disableCodeBrowserLocationEvents(); env.showTool(); // make 5 changes // verify that the Undo button is enabled and undo can be done 5 times - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { Address addr = getAddr(0x01001000); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent c = panel.getCurrentComponent(); @@ -380,9 +362,9 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { char[] values = { 'a', '1', '2', 'b', '3' }; int[] keyCodes = { KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3 }; @@ -422,7 +404,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { undo(program); testFieldColor(loc1, null); testFieldColor(loc2, null); - assertTrue(!program.canUndo()); + assertFalse(program.canUndo()); redo(program); testFieldColor(loc1, ByteViewerComponentProvider.CHANGED_VALUE_COLOR); @@ -447,26 +429,18 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(program.canUndo()); } - private void testFieldColor(FieldLocation loc, Color color) { - ByteViewerComponent c = panel.getCurrentComponent(); - ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); - Color fieldColor = field.getForeground(); - assertEquals(fieldColor, color); - - } - @Test public void testUndoRedoHexShort() throws Exception { env.showTool(); addViews(); - final Address addr = getAddr(0x01001003); - final ToggleDockingAction action = + Address addr = getAddr(0x01001003); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); ByteViewerComponent c = findComponent(panel, "Hex Short"); panel.setCurrentView(c); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), @@ -475,7 +449,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); byte value = program.getMemory().getByte(addr); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(addr); KeyEvent ev = @@ -509,13 +483,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final Address addr = getAddr(0x01001003); - final ToggleDockingAction action = + Address addr = getAddr(0x01001003); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); ByteViewerComponent c = findComponent(panel, "Hex Integer"); panel.setCurrentView(c); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), @@ -524,7 +498,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); byte value = program.getMemory().getByte(addr); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(addr); KeyEvent ev = @@ -558,13 +532,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final Address addr = getAddr(0x01001003); - final ToggleDockingAction action = + Address addr = getAddr(0x01001003); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); ByteViewerComponent c = findComponent(panel, "Hex Long"); panel.setCurrentView(c); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), @@ -573,7 +547,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); byte value = program.getMemory().getByte(addr); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(addr); KeyEvent ev = @@ -607,13 +581,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final Address addr = getAddr(0x01001003); - final ToggleDockingAction action = + Address addr = getAddr(0x01001003); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); ByteViewerComponent c = findComponent(panel, "Hex Long Long"); panel.setCurrentView(c); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), @@ -622,7 +596,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); byte value = program.getMemory().getByte(addr); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(addr); KeyEvent ev = @@ -653,10 +627,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedoHexShort2() throws Exception { - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - tool.removePlugins(new Plugin[] { cbPlugin }); + disableCodeBrowserLocationEvents(); env.showTool(); addViews(); @@ -665,10 +636,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { panel.setCurrentView(c); // make 3 changes // verify that the Undo button is enabled and undo can be done 5 times - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { Address addr = getAddr(0x01001003); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); @@ -677,7 +648,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { char[] values = { 'a', '1', '2' }; int[] keyCodes = { KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3 }; @@ -711,7 +682,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR); } } - assertTrue(!program.canUndo()); + assertFalse(program.canUndo()); for (int i = 0; i < 3; i++) { @@ -728,10 +699,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedoHexInteger2() throws Exception { - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - tool.removePlugins(new Plugin[] { cbPlugin }); + disableCodeBrowserLocationEvents(); env.showTool(); addViews(); @@ -740,10 +708,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { panel.setCurrentView(c); // make 5 changes // verify that the Undo button is enabled and undo can be done 5 times - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { Address addr = getAddr(0x01001003); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); @@ -752,7 +720,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { char[] values = { 'a', '1', '2', 'b', '3' }; int[] keyCodes = { KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3 }; @@ -786,7 +754,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR); } } - assertTrue(!program.canUndo()); + assertFalse(program.canUndo()); for (int i = 0; i < 5; i++) { @@ -803,10 +771,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedoHexLong2() throws Exception { - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - tool.removePlugins(new Plugin[] { cbPlugin }); + disableCodeBrowserLocationEvents(); env.showTool(); addViews(); @@ -815,10 +780,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { panel.setCurrentView(c); // make 9 changes // verify that the Undo button is enabled and undo can be done 5 times - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { Address addr = getAddr(0x01001003); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); @@ -827,7 +792,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { char[] values = { 'a', '1', '2', 'b', '3', 'c', '4', 'd', '5' }; int[] keyCodes = { KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3, @@ -862,7 +827,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR); } } - assertTrue(!program.canUndo()); + assertFalse(program.canUndo()); for (int i = 0; i < 9; i++) { @@ -879,10 +844,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testUndoRedoHexLongLong2() throws Exception { - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - tool.removePlugins(new Plugin[] { cbPlugin }); + disableCodeBrowserLocationEvents(); env.showTool(); addViews(); @@ -891,10 +853,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { panel.setCurrentView(c); // make 9 changes // verify that the Undo button is enabled and undo can be done 5 times - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { Address addr = getAddr(0x01001003); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); @@ -903,13 +865,15 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { action.actionPerformed(new DefaultActionContext()); }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { char[] values = { 'a', '1', '2', 'b', '3', 'c', '4', 'd', '5', 'e', '6', 'f', '7', 'a', '8', 'b', '9' }; int[] keyCodes = { KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3, - KeyEvent.VK_C, KeyEvent.VK_4, KeyEvent.VK_D, KeyEvent.VK_5, KeyEvent.VK_E, KeyEvent.VK_6, - KeyEvent.VK_F, KeyEvent.VK_7, KeyEvent.VK_G, KeyEvent.VK_8, KeyEvent.VK_H, KeyEvent.VK_9 }; + KeyEvent.VK_C, KeyEvent.VK_4, KeyEvent.VK_D, KeyEvent.VK_5, KeyEvent.VK_E, + KeyEvent.VK_6, + KeyEvent.VK_F, KeyEvent.VK_7, KeyEvent.VK_G, KeyEvent.VK_8, KeyEvent.VK_H, + KeyEvent.VK_9 }; ByteViewerComponent currentComponent = panel.getCurrentComponent(); for (int i = 0; i < 17; i++) { @@ -940,7 +904,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR); } } - assertTrue(!program.canUndo()); + assertFalse(program.canUndo()); for (int i = 0; i < 17; i++) { @@ -958,20 +922,20 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testEditInputHex() throws Exception { env.showTool(); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001000)); + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); assertTrue(action.isSelected()); - final ByteViewerComponent c = panel.getCurrentComponent(); + ByteViewerComponent c = panel.getCurrentComponent(); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); byte value = program.getMemory().getByte(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_P, 'p'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -985,13 +949,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); waitForSwing(); - final ByteViewerComponent c = findComponent(panel, "Ascii"); + ByteViewerComponent c = findComponent(panel, "Ascii"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001000)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1001,7 +965,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_Z, 'z'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1012,11 +976,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1026,12 +990,12 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); waitForSwing(); - final ByteViewerComponent c = findComponent(panel, "Octal"); + ByteViewerComponent c = findComponent(panel, "Octal"); panel.setCurrentView(c); - final Address addr = getAddr(0x01001000); - final ToggleDockingAction action = + Address addr = getAddr(0x01001000); + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1041,7 +1005,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { FieldLocation loc = getFieldLocation(addr); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), @@ -1054,11 +1018,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1068,13 +1032,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); waitForSwing(); - final ByteViewerComponent c = findComponent(panel, "Octal"); + ByteViewerComponent c = findComponent(panel, "Octal"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001000)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1084,7 +1048,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); byte value = program.getMemory().getByte(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_9, '9'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1098,13 +1062,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final ByteViewerComponent c = findComponent(panel, "Hex Short"); + ByteViewerComponent c = findComponent(panel, "Hex Short"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001003)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001003)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1113,7 +1077,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1123,11 +1087,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, ((ByteField) c.getCurrentField()).getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1137,13 +1101,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final ByteViewerComponent c = findComponent(panel, "Hex Integer"); + ByteViewerComponent c = findComponent(panel, "Hex Integer"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001003)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001003)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1152,7 +1116,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1162,11 +1126,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, ((ByteField) c.getCurrentField()).getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1176,13 +1140,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final ByteViewerComponent c = findComponent(panel, "Hex Long"); + ByteViewerComponent c = findComponent(panel, "Hex Long"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001003)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001003)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1191,7 +1155,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1201,11 +1165,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, ((ByteField) c.getCurrentField()).getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1215,13 +1179,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - final ByteViewerComponent c = findComponent(panel, "Hex Long Long"); + ByteViewerComponent c = findComponent(panel, "Hex Long Long"); panel.setCurrentView(c); - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - final FieldLocation loc = getFieldLocation(getAddr(0x01001003)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001003)); + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); action.setSelected(true); @@ -1230,7 +1194,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertTrue(action.isSelected()); assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(), c.getCurrentField()); @@ -1240,11 +1204,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, ((ByteField) c.getCurrentField()).getForeground()); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(false); action.actionPerformed(new DefaultActionContext()); }); - assertTrue(!action.isSelected()); + assertFalse(action.isSelected()); assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR, c.getFocusedCursorColor()); } @@ -1254,23 +1218,22 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); // put the byte viewer in edit mode - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); - // add a memory block - Address addr = getAddr(0x100); - int transactionID = program.startTransaction("test"); - memory.createInitializedBlock(".test", addr, 10, (byte) 0, null, false); - program.endTransaction(transactionID, true); - program.flushEvents(); + // add a memory block + txSwing(() -> { + Address addr = getAddr(0x100); + memory.createInitializedBlock(".test", addr, 10, (byte) 0, null, false); + }); // edit the first 3 bytes in the block - final ByteViewerComponent c = panel.getCurrentComponent(); - SwingUtilities.invokeAndWait(() -> { + ByteViewerComponent c = panel.getCurrentComponent(); + runSwing(() -> { Address testAddress = getAddr(0x100); FieldLocation loc = getFieldLocation(testAddress); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); @@ -1290,7 +1253,9 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + Address addr = getAddr(0x100); for (int i = 0; i < 3; i++) { // verify that the bytes are rendered in red FieldLocation loc = getFieldLocation(addr); @@ -1307,23 +1272,22 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); // put the byte viewer in edit mode - final ToggleDockingAction action = + ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { action.setSelected(true); action.actionPerformed(new DefaultActionContext()); }); // first add a memory block - Address addr = getAddr(0x100); - int transactionID = program.startTransaction("test"); - memory.createInitializedBlock(".test", addr, 10, (byte) 0, null, false); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + Address addr = getAddr(0x100); + memory.createInitializedBlock(".test", addr, 10, (byte) 0, null, false); + }); // edit the first 3 bytes in the block - final ByteViewerComponent c = panel.getCurrentComponent(); - SwingUtilities.invokeAndWait(() -> { + ByteViewerComponent c = panel.getCurrentComponent(); + runSwing(() -> { Address testAddress = getAddr(0x100); FieldLocation loc = getFieldLocation(testAddress); KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1'); @@ -1345,14 +1309,15 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { program.flushEvents(); // move the block - MemoryBlock block = memory.getBlock(addr); - Address newStart = getAddr(0x500); - transactionID = program.startTransaction("Test"); - memory.moveBlock(block, newStart, TaskMonitor.DUMMY); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + Address addr = getAddr(0x100); + MemoryBlock block = memory.getBlock(addr); + Address newStart = getAddr(0x500); + memory.moveBlock(block, newStart, TaskMonitor.DUMMY); + }); - FieldLocation loc = getFieldLocation(newStart); + Address addr = getAddr(0x500); + FieldLocation loc = getFieldLocation(addr); ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertNotNull(field); @@ -1368,10 +1333,9 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { MemoryBlock block = memory.getBlock(addr); Address newaddr = getAddr(0x01002009); - int transactionID = program.startTransaction("Test"); - memory.split(block, newaddr); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + memory.split(block, newaddr); + }); ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(newaddr); @@ -1384,7 +1348,8 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testMemoryBlockExpandUp() throws Exception { // expand up: create a block, then join to its successor - SwingUtilities.invokeAndWait(() -> tool.removePlugins(new Plugin[] { cbPlugin })); + + disableCodeBrowserLocationEvents(); env.showTool(); Address addr = getAddr(0x01001000); @@ -1394,30 +1359,29 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { Address newaddr = getAddr(0x01000500); - int transactionID = program.startTransaction("Test"); - MemoryBlock newblock = - memory.createInitializedBlock(".test", newaddr, 0xb00, (byte) 0, null, false); - memory.join(newblock, block); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + MemoryBlock newblock = + memory.createInitializedBlock(".test", newaddr, 0xb00, (byte) 0, null, false); + memory.join(newblock, block); + }); ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(newaddr); ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertNotNull(field); - loc = c.getCursorLocation(); + // cursor should remain where it was before the block expansion + loc = c.getCursorLocation(); assertEquals(getFieldLocation(addr), loc); // there should be no separator above the current location field = c.getField(loc.getIndex().subtract(BigInteger.ONE), 0); - assertTrue(!field.getText().equals("..")); - + assertFalse(field.getText().equals("..")); } @Test public void testMemoryBlockExpandDown() throws Exception { - SwingUtilities.invokeAndWait(() -> tool.removePlugins(new Plugin[] { cbPlugin })); + disableCodeBrowserLocationEvents(); // expand block down: create a block, then join to its predecessor env.showTool(); @@ -1428,12 +1392,11 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { Address newaddr = getAddr(0x01003000L); - int transactionID = program.startTransaction("Test"); - MemoryBlock newblock = - memory.createInitializedBlock(".test", newaddr, 0x100, (byte) 0, null, false); - memory.join(block, newblock); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + MemoryBlock newblock = + memory.createInitializedBlock(".test", newaddr, 0x100, (byte) 0, null, false); + memory.join(block, newblock); + }); ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(newaddr); @@ -1447,7 +1410,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testMemoryBlockDeletedInView() throws Exception { // delete a memory block that is showing in the view - SwingUtilities.invokeAndWait(() -> tool.removePlugins(new Plugin[] { cbPlugin })); + disableCodeBrowserLocationEvents(); env.showTool(); Address addr = getAddr(0x0f001000); MemoryBlock block = memory.getBlock(addr); @@ -1459,10 +1422,9 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { FieldLocation loc = c.getCursorLocation(); assertEquals(getFieldLocation(addr), loc); - int transactionID = program.startTransaction("Test"); - memory.removeBlock(block, TaskMonitor.DUMMY); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + memory.removeBlock(block, TaskMonitor.DUMMY); + }); addr = getAddr(0x0f002000); loc = getFieldLocation(addr); @@ -1474,10 +1436,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { public void testMemoryBlockDeletedNotInView() throws Exception { // delete a memory block that is not showing in the view - // remove code browser plugin so the cursor position does not - // get changed because of location events that the code browser - // generates. - SwingUtilities.invokeAndWait(() -> tool.removePlugins(new Plugin[] { cbPlugin })); + disableCodeBrowserLocationEvents(); env.showTool(); Address addr = getAddr(0x0f001000); @@ -1490,10 +1449,9 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(getFieldLocation(addr), loc); MemoryBlock block = memory.getBlock(getAddr(0x01001000)); - int transactionID = program.startTransaction("Test"); - memory.removeBlock(block, TaskMonitor.DUMMY); - program.endTransaction(transactionID, true); - program.flushEvents(); + txSwing(() -> { + memory.removeBlock(block, TaskMonitor.DUMMY); + }); loc = getFieldLocation(addr); // cursor position should not be affected @@ -1511,27 +1469,29 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); ByteViewerOptionsDialog d = launchByteViewerOptions(); - final FixedBitSizeValueField field = + FixedBitSizeValueField field = (FixedBitSizeValueField) getInstanceField("bytesPerLineField", d); - SwingUtilities.invokeAndWait(() -> field.setValue(BigInteger.valueOf(10))); + runSwing(() -> field.setValue(BigInteger.valueOf(10))); pressButtonByText(d.getComponent(), "OK"); + // add the block - int transactionID = program.startTransaction("Test"); - Address addr = getAddr(0x30); - memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); + txSwing(() -> { + Address addr = getAddr(0x30); + memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); - // add the second block at 0x48 - addr = getAddr(0x48); - memory.createInitializedBlock(".test2", addr, 0x100, (byte) 0, null, false); - program.endTransaction(transactionID, true); - program.flushEvents(); + // add the second block at 0x48 + Address addr2 = getAddr(0x48); + memory.createInitializedBlock(".test2", addr2, 0x100, (byte) 0, null, false); + }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); Address a = getAddr(0x48); FieldLocation loc = getFieldLocation(a); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol()); }); + + Address addr = getAddr(0x48); FieldLocation loc = getFieldLocation(addr); ByteViewerComponent c = panel.getCurrentComponent(); // cursor position should not be affected @@ -1543,55 +1503,40 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { public void testMemoryChange() throws Exception { env.showTool(); - SwingUtilities.invokeAndWait(() -> tool.showComponentProvider(plugin.getProvider(), false)); - final ProgramManager pm = tool.getService(ProgramManager.class); - SwingUtilities.invokeLater(() -> pm.closeProgram()); + runSwing(() -> tool.showComponentProvider(plugin.getProvider(), false)); + ProgramManager pm = tool.getService(ProgramManager.class); + runSwing(() -> pm.closeProgram(), false); waitForSwing(); pm.openProgram(program.getDomainFile()); // add a memory block - int transactionID = program.startTransaction("test"); - MemoryBlock block = null; - try { - block = memory.createInitializedBlock(".test", getAddr(0), 500, (byte) 0, - TaskMonitor.DUMMY, false); - } - finally { - program.endTransaction(transactionID, true); - } + txSwing(() -> { + memory.createInitializedBlock(".test", getAddr(0), 500, (byte) 0, TaskMonitor.DUMMY, + false); + }); - program.flushEvents(); - waitForSwing(); - - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { GoToService goToService = tool.getService(GoToService.class); goToService.goTo(new ProgramLocation(program, getAddr(0))); }); - SwingUtilities.invokeAndWait(() -> tool.showComponentProvider(plugin.getProvider(), true)); + runSwing(() -> tool.showComponentProvider(plugin.getProvider(), true)); waitForSwing(); - Thread.sleep(500); ByteViewerComponent c = panel.getCurrentComponent(); assertEquals(getFieldLocation(getAddr(0)), c.getCursorLocation()); - SwingUtilities.invokeAndWait(() -> tool.showComponentProvider(plugin.getProvider(), false)); + runSwing(() -> tool.showComponentProvider(plugin.getProvider(), false)); waitForSwing(); // now remove the block - transactionID = program.startTransaction("test"); - try { + txSwing(() -> { + MemoryBlock block = memory.getBlock(getAddr(0)); memory.removeBlock(block, TaskMonitor.DUMMY); - } - finally { - program.endTransaction(transactionID, true); - } - program.flushEvents(); - waitForSwing(); + }); - SwingUtilities.invokeAndWait(() -> tool.showComponentProvider(plugin.getProvider(), true)); + runSwing(() -> tool.showComponentProvider(plugin.getProvider(), true)); waitForSwing(); - Thread.sleep(500); c = panel.getCurrentComponent(); Address addr = cbPlugin.getCurrentAddress(); @@ -1607,35 +1552,35 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { pressButtonByText(dialog.getComponent(), "OK"); ByteViewerOptionsDialog d = launchByteViewerOptions(); - final FixedBitSizeValueField field = + FixedBitSizeValueField field = (FixedBitSizeValueField) getInstanceField("bytesPerLineField", d); - SwingUtilities.invokeAndWait(() -> field.setValue(BigInteger.valueOf(10))); + runSwing(() -> field.setValue(BigInteger.valueOf(10))); pressButtonByText(d.getComponent(), "OK"); - // add the block - int transactionID = program.startTransaction("Test"); - Address addr = getAddr(0x30); - memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); - // add the second block at 0x48 - addr = getAddr(0x48); - memory.createInitializedBlock(".test2", addr, 0x100, (byte) 0, null, false); - program.endTransaction(transactionID, true); - program.flushEvents(); + // add the block + txSwing(() -> { + Address addr = getAddr(0x30); + memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); - SwingUtilities.invokeAndWait(() -> { + // add the second block at 0x48 + Address addr2 = getAddr(0x48); + memory.createInitializedBlock(".test2", addr2, 0x100, (byte) 0, null, false); + }); + + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); Address a = getAddr(0x30); FieldLocation loc = getFieldLocation(a); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol()); }); - final FieldSelection fsel = new FieldSelection(); + FieldSelection fsel = new FieldSelection(); ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc1 = c.getCursorLocation(); FieldLocation loc2 = getFieldLocation(getAddr(0x000000cb)); fsel.addRange(new FieldLocation(loc1.getIndex(), loc1.getFieldNum(), 0, 0), new FieldLocation(loc2.getIndex(), loc2.getFieldNum(), 0, 0)); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent currentComponent = panel.getCurrentComponent(); currentComponent.selectionChanged(fsel, EventTrigger.GUI_ACTION); }); @@ -1654,18 +1599,18 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); - SwingUtilities.invokeLater(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); - }); + }, false); ByteViewerOptionsDialog d = launchByteViewerOptions(); - final FixedBitSizeValueField field = + FixedBitSizeValueField field = (FixedBitSizeValueField) getInstanceField("bytesPerLineField", d); - SwingUtilities.invokeAndWait(() -> field.setValue(BigInteger.valueOf(10))); + runSwing(() -> field.setValue(BigInteger.valueOf(10))); pressButtonByText(d.getComponent(), "OK"); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); action.setSelected(true); @@ -1673,17 +1618,16 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { }); // add the block - int transactionID = program.startTransaction("Test"); - Address addr = getAddr(0x30); - memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); + txSwing(() -> { + Address addr = getAddr(0x30); + memory.createInitializedBlock(".test", addr, 0x12, (byte) 0, null, false); - // add the second block at 0x48 - addr = getAddr(0x48); - memory.createInitializedBlock(".test2", addr, 0x100, (byte) 0, null, false); - program.endTransaction(transactionID, true); - program.flushEvents(); + // add the second block at 0x48 + Address addr2 = getAddr(0x48); + memory.createInitializedBlock(".test2", addr2, 0x100, (byte) 0, null, false); + }); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); Address a = getAddr(0x41); FieldLocation loc = getFieldLocation(a); @@ -1694,6 +1638,8 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + assertEquals((byte) 0x30, memory.getByte(getAddr(0x41))); } @@ -1701,7 +1647,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { public void testEditOptionCurrentViewColor() throws Exception { env.showTool(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1721,7 +1667,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1741,7 +1687,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1756,21 +1702,13 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertColorsEqual(Palette.CYAN, c.getNonFocusCursorColor()); } - private void putFont(final Options options, final String optionName, final Font font) { - runSwing(() -> options.setFont(optionName, font)); - } - - private void putColor(final Options options, final String optionName, final Color color) { - runSwing(() -> options.setColor(optionName, color)); - } - @Test public void testEditOptionEditColor() throws Exception { // color for changed bytes env.showTool(); addViews(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1780,8 +1718,8 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { // change the color for Edit Color putColor(opt, ByteViewerComponentProvider.CHANGED_VALUE_COLOR_OPTION_NAME, Palette.GREEN); - final FieldLocation loc = getFieldLocation(getAddr(0x01001000)); - SwingUtilities.invokeAndWait(() -> { + FieldLocation loc = getFieldLocation(getAddr(0x01001000)); + runSwing(() -> { ToggleDockingAction action = (ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing"); action.setSelected(true); @@ -1796,6 +1734,8 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { c.getCurrentField()); }); program.flushEvents(); + waitForSwing(); + ByteViewerComponent c = panel.getCurrentComponent(); ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); assertColorsEqual(Palette.GREEN, field.getForeground()); @@ -1806,7 +1746,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1828,7 +1768,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { env.showTool(); addViews(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { ByteViewerComponent c = panel.getCurrentComponent(); FieldLocation loc = getFieldLocation(getAddr(0x01001000)); c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); @@ -1847,7 +1787,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { @Test public void testGoToUpdatesByteViewer() throws Exception { env.showTool(); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { GoToService goToService = tool.getService(GoToService.class); goToService.goTo(new ProgramLocation(program, getAddr(0x01001050))); }); @@ -1884,7 +1824,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { Assert.assertNotEquals("Snapshot triggered navigation unexpectedly", address, cbLocation.getAddress()); - modifiers = DockingUtils.CONTROL_KEY_MODIFIER_MASK | InputEvent.SHIFT_MASK; + modifiers = DockingUtils.CONTROL_KEY_MODIFIER_MASK | SHIFT_DOWN_MASK; clickLocation(snapshot, modifiers); cbLocation = cbPlugin.getCurrentLocation(); @@ -1918,11 +1858,96 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { assertEquals(null, currentHighlightText); } + @Test + public void testSaveRestoreState() throws Exception { + env.showTool(); + addViews(); + ByteViewerComponent c = panel.getCurrentComponent(); + + FieldLocation loc = getFieldLocation(getAddr(0x0100100b)); + runSwing(() -> { + ByteViewerComponent currentComponent = panel.getCurrentComponent(); + currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); + }); + + ByteViewerOptionsDialog dialog = launchByteViewerOptions(); + FixedBitSizeValueField field = + (FixedBitSizeValueField) getInstanceField("groupSizeField", dialog); + runSwing(() -> field.setValue(BigInteger.valueOf(4))); + pressButtonByText(dialog.getComponent(), "OK"); + + // change the font + Options opt = tool.getOptions("ByteViewer"); + Font font = new Font("Times New Roman", Font.BOLD, 12); + + runSwing(() -> { + + opt.setFont(ByteViewerComponentProvider.OPTION_FONT, font); + GoToService goToService = tool.getService(GoToService.class); + goToService.goTo(new ProgramLocation(program, getAddr(0x01002500))); + }); + assertEquals(4, plugin.getProvider().getGroupSize()); + + ViewerPosition vp = panel.getViewerPosition(); + runSwing(() -> env.saveRestoreToolState()); + + waitForSwing(); + c = panel.getCurrentComponent(); + assertEquals(4, plugin.getProvider().getGroupSize()); + + assertEquals(getFieldLocation(getAddr(0x01002500)), c.getCursorLocation()); + assertEquals(font, panel.getFontMetrics().getFont()); + waitForSwing(); + + assertEquals(vp, panel.getViewerPosition()); + } + + // Remove code browser plugin so the cursor position does not get changed because of location + // events that the code browser generates. + private void disableCodeBrowserLocationEvents() throws Exception { + runSwing(() -> tool.removePlugins(List.of(cbPlugin))); + } + + private void testFieldColor(FieldLocation loc, Color color) { + ByteViewerComponent c = panel.getCurrentComponent(); + ByteField field = c.getField(loc.getIndex(), loc.getFieldNum()); + Color fieldColor = field.getForeground(); + assertEquals(fieldColor, color); + } + + // perform the given callback in a transaction on the Swing thread + private void txSwing(ExceptionalCallback c) { + + int txId = program.startTransaction("Test - Function in Transaction"); + boolean commit = true; + try { + runSwingWithException(c); + program.flushEvents(); + } + catch (Exception e) { + commit = false; + failWithException("Exception modifying program '" + program.getName() + "'", e); + } + finally { + program.endTransaction(txId, commit); + } + + waitForSwing(); + } + + private void putFont(Options options, String optionName, Font font) { + runSwing(() -> options.setFont(optionName, font)); + } + + private void putColor(Options options, String optionName, Color color) { + runSwing(() -> options.setColor(optionName, color)); + } + private void clickMiddleMouseLocation(ProgramByteViewerComponentProvider testProvider, int mouseModifiers) { ByteViewerPanel byteViewerPanel = testProvider.getByteViewerPanel(); - final ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); + ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); Rectangle cursorBounds = component.getCursorBounds(); @@ -1935,7 +1960,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { int mouseModifiers) { ByteViewerPanel byteViewerPanel = testProvider.getByteViewerPanel(); - final ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); + ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); Rectangle cursorBounds = component.getCursorBounds(); @@ -1947,10 +1972,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { private void setByteViewerLocation(ProgramByteViewerComponentProvider testProvider, Address address) throws Exception { ByteViewerPanel byteViewerPanel = testProvider.getByteViewerPanel(); - final ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); - final FieldLocation byteViewerLocation = getFieldLocation(address); + ByteViewerComponent component = byteViewerPanel.getCurrentComponent(); + FieldLocation byteViewerLocation = getFieldLocation(address); - SwingUtilities.invokeAndWait(() -> { + runSwing(() -> { component.setCursorPosition(byteViewerLocation.getIndex(), byteViewerLocation.getFieldNum(), byteViewerLocation.getRow(), byteViewerLocation.getCol()); @@ -1967,73 +1992,16 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { return providers.get(0); } - @Test - public void testSaveRestoreState() throws Exception { - env.showTool(); - addViews(); - ByteViewerComponent c = panel.getCurrentComponent(); - - final FieldLocation loc = getFieldLocation(getAddr(0x0100100b)); - SwingUtilities.invokeAndWait(() -> { - ByteViewerComponent currentComponent = panel.getCurrentComponent(); - currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0); - }); - - ByteViewerOptionsDialog dialog = launchByteViewerOptions(); - final FixedBitSizeValueField field = - (FixedBitSizeValueField) getInstanceField("groupSizeField", dialog); - SwingUtilities.invokeAndWait(() -> field.setValue(BigInteger.valueOf(4))); - pressButtonByText(dialog.getComponent(), "OK"); - - // change the font - final Options opt = tool.getOptions("ByteViewer"); - final Font font = new Font("Times New Roman", Font.BOLD, 12); - - SwingUtilities.invokeAndWait(() -> { - - opt.setFont(ByteViewerComponentProvider.OPTION_FONT, font); - GoToService goToService = tool.getService(GoToService.class); - goToService.goTo(new ProgramLocation(program, getAddr(0x01002500))); - -// FieldLocation loc = getFieldLocation(getAddr(0x0100f3ff)); -// ByteViewerComponent c = panel.getCurrentComponent(); -// c.setCursorPosition(loc.getIndex(), loc.getFieldNum(), -// loc.getRow(), loc.getCol()); -// c.scrollToCursor(); - }); - assertEquals(4, plugin.getProvider().getGroupSize()); - - ViewerPosition vp = panel.getViewerPosition(); - SwingUtilities.invokeAndWait(() -> env.saveRestoreToolState()); - - waitForSwing(); - c = panel.getCurrentComponent(); - assertEquals(4, plugin.getProvider().getGroupSize()); - - assertEquals(getFieldLocation(getAddr(0x01002500)), c.getCursorLocation()); - assertEquals(font, panel.getFontMetrics().getFont()); - waitForSwing(); - Thread.sleep(1000); - assertEquals(vp, panel.getViewerPosition()); - - } - private ByteViewerOptionsDialog launchByteViewerOptions() { - final DockingActionIf action = getAction(plugin, "Byte Viewer Options"); + DockingActionIf action = getAction(plugin, "Byte Viewer Options"); assertTrue(action.isEnabled()); - SwingUtilities.invokeLater(() -> action.actionPerformed(new DefaultActionContext())); + performAction(action, false); waitForSwing(); - ByteViewerOptionsDialog d = env.waitForDialogComponent(ByteViewerOptionsDialog.class, 2000); + ByteViewerOptionsDialog d = waitForDialogComponent(ByteViewerOptionsDialog.class); return d; } -// private boolean isHeaderShowing() { -// FieldScrollPane sp = (FieldScrollPane)findContainer(panel, FieldScrollPane.class); -// ByteViewerHeader header = (ByteViewerHeader)findContainer(sp, ByteViewerHeader.class); -// return header != null; -// } - private ByteViewerComponent findComponent(Container container, String name) { Component[] c = container.getComponents(); for (Component element : c) { @@ -2085,7 +2053,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest { Component[] c = container.getComponents(); for (Component element : c) { if (element instanceof JLabel) { - if (name.equals(((JLabel) element).getName())) { + if (name.equals(element.getName())) { return ((JLabel) element).getText(); } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/threaded/IncrementalLoadJob.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/threaded/IncrementalLoadJob.java index 371dfc829e..6113e9676b 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/threaded/IncrementalLoadJob.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/threaded/IncrementalLoadJob.java @@ -38,9 +38,8 @@ public class IncrementalLoadJob extends Job implements ThreadedTable * by this job. By default, the value is 0, which means there is nothing to wait for. If we * flush, this will be set to 1. */ - private CountDownLatch completedCallbackLatch = new CountDownLatch(0); + private volatile CountDownLatch completedCallbackLatch = new CountDownLatch(0); private volatile boolean isCancelled = false; - private volatile IncrementalUpdatingAccumulator incrementalAccumulator; IncrementalLoadJob(ThreadedTableModel threadedModel,