mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 14:17:36 +08:00
GP-1421 - Version Tracking - Converted 'command' to a 'task' and updated
the progress monitor to show continuous progress; fixed slow test Closes #3221
This commit is contained in:
@@ -31,10 +31,4 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation "org.jmockit:jmockit:1.44"
|
testImplementation "org.jmockit:jmockit:1.44"
|
||||||
testImplementation project(path: ':Project', configuration: 'testArtifacts')
|
testImplementation project(path: ':Project', configuration: 'testArtifacts')
|
||||||
}
|
}
|
||||||
integrationTest {
|
|
||||||
// tests to slow to run during automated testing
|
|
||||||
excludes = [
|
|
||||||
'**/VTAutoVersionTrackingTest*',
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -23,12 +23,13 @@ import java.util.List;
|
|||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.feature.vt.api.db.VTSessionDB;
|
import ghidra.feature.vt.api.db.VTSessionDB;
|
||||||
import ghidra.feature.vt.api.main.VTSession;
|
import ghidra.feature.vt.api.main.VTSession;
|
||||||
import ghidra.feature.vt.gui.actions.AutoVersionTrackingCommand;
|
import ghidra.feature.vt.gui.actions.AutoVersionTrackingTask;
|
||||||
import ghidra.feature.vt.gui.plugin.*;
|
import ghidra.feature.vt.gui.plugin.*;
|
||||||
import ghidra.framework.model.DomainFolder;
|
import ghidra.framework.model.DomainFolder;
|
||||||
import ghidra.framework.plugintool.Plugin;
|
import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.util.task.TaskLauncher;
|
||||||
|
|
||||||
public class AutoVersionTrackingScript extends GhidraScript {
|
public class AutoVersionTrackingScript extends GhidraScript {
|
||||||
@Override
|
@Override
|
||||||
@@ -72,15 +73,10 @@ public class AutoVersionTrackingScript extends GhidraScript {
|
|||||||
|
|
||||||
//String description = "AutoVTScript";
|
//String description = "AutoVTScript";
|
||||||
|
|
||||||
AutoVersionTrackingCommand autoVTcmd =
|
AutoVersionTrackingTask autoVtTask =
|
||||||
new AutoVersionTrackingCommand(controller, session, 1.0, 10.0);
|
new AutoVersionTrackingTask(controller, session, 1.0, 10.0);
|
||||||
|
|
||||||
controller.getTool().executeBackgroundCommand(autoVTcmd, session);
|
|
||||||
//destinationProgram.save(description, monitor);
|
|
||||||
|
|
||||||
//session.save(description, monitor);
|
|
||||||
//session.release(this);
|
|
||||||
|
|
||||||
|
TaskLauncher.launch(autoVtTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Plugin> T getPlugin(PluginTool tool, Class<T> c) {
|
public static <T extends Plugin> T getPlugin(PluginTool tool, Class<T> c) {
|
||||||
|
|||||||
+9
-10
@@ -25,10 +25,11 @@ import ghidra.feature.vt.gui.plugin.VTController;
|
|||||||
import ghidra.feature.vt.gui.plugin.VTPlugin;
|
import ghidra.feature.vt.gui.plugin.VTPlugin;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.task.TaskLauncher;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This action runs the {@link AutoVersionTrackingCommand}
|
* This action runs the {@link AutoVersionTrackingTask}
|
||||||
*/
|
*/
|
||||||
public class AutoVersionTrackingAction extends DockingAction {
|
public class AutoVersionTrackingAction extends DockingAction {
|
||||||
public static Icon AUTO_VT_ICON = ResourceManager.loadImage("images/wizard.png");
|
public static Icon AUTO_VT_ICON = ResourceManager.loadImage("images/wizard.png");
|
||||||
@@ -59,18 +60,16 @@ public class AutoVersionTrackingAction extends DockingAction {
|
|||||||
|
|
||||||
VTSession session = controller.getSession();
|
VTSession session = controller.getSession();
|
||||||
|
|
||||||
// In the future we might want to make these user options so the user can change them
|
// In the future we might want to make these user options so the user can change them.
|
||||||
// I don't want to make this change until the confidence option in the reference
|
// We don't want to make this change until the confidence option in the reference
|
||||||
// correlators is changed to make more sense to the user - currently the confidence has
|
// correlators is changed to make more sense to the user - currently the confidence has
|
||||||
// to be entered as the value before the log 10 is computed but the table shows log 10 value
|
// to be entered as the value before the log 10 is computed but the table shows log 10 value.
|
||||||
|
//
|
||||||
// The current passed values for score and confidence (.95 and 10.0)
|
// The current passed values for score and confidence (.95 and 10.0)
|
||||||
// get you accepted matches with similarity scores >= .95 and
|
// get you accepted matches with similarity scores >= .95 and
|
||||||
// confidence (log 10) scores 2.0 and up
|
// confidence (log 10) scores 2.0 and up
|
||||||
AutoVersionTrackingCommand command =
|
AutoVersionTrackingTask task = new AutoVersionTrackingTask(controller, session, 0.95, 10.0);
|
||||||
new AutoVersionTrackingCommand(controller, session, 0.95, 10.0);
|
TaskLauncher.launch(task);
|
||||||
|
|
||||||
controller.getTool().executeBackgroundCommand(command, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+221
-136
File diff suppressed because it is too large
Load Diff
+28
-31
@@ -82,7 +82,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
private SelectionOverrideMemento selectionMemento;
|
private SelectionOverrideMemento selectionMemento;
|
||||||
private boolean filteringFrozen;
|
private boolean filteringFrozen;
|
||||||
|
|
||||||
// a selection we may have to set later, after the table has finished loading
|
// a selection we may have to set later, after the table has finished loading
|
||||||
private VTMatch pendingMatchSelection;
|
private VTMatch pendingMatchSelection;
|
||||||
private SwingUpdateManager selectMatchUpdateManager;
|
private SwingUpdateManager selectMatchUpdateManager;
|
||||||
private MatchTableSelectionAction tableSelectionStateAction;
|
private MatchTableSelectionAction tableSelectionStateAction;
|
||||||
@@ -182,8 +182,8 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
int filteredCount = matchesTableModel.getRowCount();
|
int filteredCount = matchesTableModel.getRowCount();
|
||||||
int unfilteredCount = matchesTableModel.getUnfilteredRowCount();
|
int unfilteredCount = matchesTableModel.getUnfilteredRowCount();
|
||||||
int filteredOutCount = unfilteredCount - filteredCount;
|
int filteredOutCount = unfilteredCount - filteredCount;
|
||||||
ancillaryFilterButton.setToolTipText(
|
ancillaryFilterButton
|
||||||
"More Filters - " + filteredOutCount + " item(s) hidden");
|
.setToolTipText("More Filters - " + filteredOutCount + " item(s) hidden");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ancillaryFilterButton.setToolTipText("More Filters - no active filters");
|
ancillaryFilterButton.setToolTipText("More Filters - no active filters");
|
||||||
@@ -233,9 +233,9 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
int unfilteredCount = matchesTableModel.getUnfilteredRowCount();
|
int unfilteredCount = matchesTableModel.getUnfilteredRowCount();
|
||||||
|
|
||||||
String sessionName = controller.getVersionTrackingSessionName();
|
String sessionName = controller.getVersionTrackingSessionName();
|
||||||
StringBuffer buffy = new StringBuffer();
|
StringBuilder buffy = new StringBuilder();
|
||||||
buffy.append("[Session: ").append(sessionName).append("] ");
|
buffy.append("[Session: ").append(sessionName).append("] - ");
|
||||||
buffy.append('-').append(filteredCount).append(" matches");
|
buffy.append(filteredCount).append(" matches");
|
||||||
if (filteredCount != unfilteredCount) {
|
if (filteredCount != unfilteredCount) {
|
||||||
buffy.append(" (of ").append(unfilteredCount).append(')');
|
buffy.append(" (of ").append(unfilteredCount).append(')');
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
selectMatchUpdateManager.updateLater();
|
selectMatchUpdateManager.updateLater();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// for any selection that is not handled by the match changing we want to
|
// for any selection that is not handled by the match changing we want to
|
||||||
// notify that context has changed so that actions properly update
|
// notify that context has changed so that actions properly update
|
||||||
notifyContextChanged();
|
notifyContextChanged();
|
||||||
}
|
}
|
||||||
@@ -307,14 +307,14 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
|
|
||||||
int sourceLabelColumnIndex = matchesTableModel.getColumnIndex(SourceLabelTableColumn.class);
|
int sourceLabelColumnIndex = matchesTableModel.getColumnIndex(SourceLabelTableColumn.class);
|
||||||
TableColumn sourceLabelColumn = columnModel.getColumn(sourceLabelColumnIndex);
|
TableColumn sourceLabelColumn = columnModel.getColumn(sourceLabelColumnIndex);
|
||||||
sourceLabelColumn.setCellRenderer(
|
sourceLabelColumn
|
||||||
new VTSymbolRenderer(controller.getServiceProvider(), table));
|
.setCellRenderer(new VTSymbolRenderer(controller.getServiceProvider(), table));
|
||||||
|
|
||||||
int destinationLabelColumnIndex =
|
int destinationLabelColumnIndex =
|
||||||
matchesTableModel.getColumnIndex(DestinationLabelTableColumn.class);
|
matchesTableModel.getColumnIndex(DestinationLabelTableColumn.class);
|
||||||
TableColumn destinationLabelColumn = columnModel.getColumn(destinationLabelColumnIndex);
|
TableColumn destinationLabelColumn = columnModel.getColumn(destinationLabelColumnIndex);
|
||||||
destinationLabelColumn.setCellRenderer(
|
destinationLabelColumn
|
||||||
new VTSymbolRenderer(controller.getServiceProvider(), table));
|
.setCellRenderer(new VTSymbolRenderer(controller.getServiceProvider(), table));
|
||||||
|
|
||||||
int statusColumnIndex = matchesTableModel.getColumnIndex(StatusTableColumn.class);
|
int statusColumnIndex = matchesTableModel.getColumnIndex(StatusTableColumn.class);
|
||||||
TableColumn statusColumn = columnModel.getColumn(statusColumnIndex);
|
TableColumn statusColumn = columnModel.getColumn(statusColumnIndex);
|
||||||
@@ -352,8 +352,8 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
innerPanel.add(lengthFilterPanel);
|
innerPanel.add(lengthFilterPanel);
|
||||||
|
|
||||||
ancillaryFilterButton = new JButton(UNFILTERED_ICON);
|
ancillaryFilterButton = new JButton(UNFILTERED_ICON);
|
||||||
ancillaryFilterButton.addActionListener(
|
ancillaryFilterButton
|
||||||
e -> tool.showDialog(ancillaryFilterDialog, component));
|
.addActionListener(e -> tool.showDialog(ancillaryFilterDialog, component));
|
||||||
ancillaryFilterButton.setToolTipText("Filters Dialog");
|
ancillaryFilterButton.setToolTipText("Filters Dialog");
|
||||||
HelpService helpService = DockingWindowManager.getHelpService();
|
HelpService helpService = DockingWindowManager.getHelpService();
|
||||||
HelpLocation filterHelpLocation =
|
HelpLocation filterHelpLocation =
|
||||||
@@ -405,7 +405,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
int row = matchesTableModel.getRowIndex(match);
|
int row = matchesTableModel.getRowIndex(match);
|
||||||
if (row < 0) {
|
if (row < 0) {
|
||||||
pendingMatchSelection = match;
|
pendingMatchSelection = match;
|
||||||
// this happen while reloading. If so, save the match and listen for
|
// this happen while reloading. If so, save the match and listen for
|
||||||
// the table data changed and restore the selection at that point
|
// the table data changed and restore the selection at that point
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -517,7 +517,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (matchesContextChanged) {
|
if (matchesContextChanged) {
|
||||||
// Now that all records have been processed,
|
// Now that all records have been processed,
|
||||||
// since the match table changed perform a reload to apply filters.
|
// since the match table changed perform a reload to apply filters.
|
||||||
reload();
|
reload();
|
||||||
|
|
||||||
@@ -695,8 +695,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
"should become ignored by applying a match.");
|
"should become ignored by applying a match.");
|
||||||
|
|
||||||
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
||||||
.registerOptionsEditor(
|
.registerOptionsEditor(new ApplyMarkupPropertyEditor(controller));
|
||||||
new ApplyMarkupPropertyEditor(controller));
|
|
||||||
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
||||||
.setOptionsHelpLocation(
|
.setOptionsHelpLocation(
|
||||||
new HelpLocation("VersionTracking", "Apply Markup Options"));
|
new HelpLocation("VersionTracking", "Apply Markup Options"));
|
||||||
@@ -709,17 +708,15 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
vtOptions.setOptionsHelpLocation(applyOptionsHelpLocation);
|
vtOptions.setOptionsHelpLocation(applyOptionsHelpLocation);
|
||||||
|
|
||||||
vtOptions.getOptions(ACCEPT_MATCH_OPTIONS_NAME)
|
vtOptions.getOptions(ACCEPT_MATCH_OPTIONS_NAME)
|
||||||
.setOptionsHelpLocation(
|
.setOptionsHelpLocation(applyMatchOptionsHelpLocation);
|
||||||
applyMatchOptionsHelpLocation);
|
|
||||||
|
|
||||||
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
||||||
.setOptionsHelpLocation(
|
.setOptionsHelpLocation(applyMatchOptionsHelpLocation);
|
||||||
applyMatchOptionsHelpLocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// FilterDialogModel Methods
|
// FilterDialogModel Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFilter(Filter<VTMatch> filter) {
|
public void addFilter(Filter<VTMatch> filter) {
|
||||||
@@ -728,7 +725,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
matchesTableModel.addFilter(filter);
|
matchesTableModel.addFilter(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces a refilter, even though filtering operations may be disabled. The reload
|
* Forces a refilter, even though filtering operations may be disabled. The reload
|
||||||
* is necessary since the model contents may have changed
|
* is necessary since the model contents may have changed
|
||||||
*/
|
*/
|
||||||
@@ -794,11 +791,11 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
/**
|
/**
|
||||||
* A class meant to override the default table selection behavior <b>in special situations</b>.
|
* A class meant to override the default table selection behavior <b>in special situations</b>.
|
||||||
* <p>
|
* <p>
|
||||||
* <u>Issue 1:</u> Accepting or applying a match can trigger the match to be filtered out
|
* <u>Issue 1:</u> Accepting or applying a match can trigger the match to be filtered out
|
||||||
* of the table. The default SelectionManager does not restore the selection for that item,
|
* of the table. The default SelectionManager does not restore the selection for that item,
|
||||||
* as it knows that the item is gone.
|
* as it knows that the item is gone.
|
||||||
* <p>
|
* <p>
|
||||||
* <u>Issue 2:</u> Accepting or applying a match can trigger the match to be moved due to a
|
* <u>Issue 2:</u> Accepting or applying a match can trigger the match to be moved due to a
|
||||||
* sort operation after the edit.
|
* sort operation after the edit.
|
||||||
* <p>
|
* <p>
|
||||||
* <u>Desired Behavior:</u> Have the selection restored to the previous location, even if the
|
* <u>Desired Behavior:</u> Have the selection restored to the previous location, even if the
|
||||||
@@ -847,18 +844,18 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
ListSelectionModel selectionModel = matchesTable.getSelectionModel();
|
ListSelectionModel selectionModel = matchesTable.getSelectionModel();
|
||||||
int rowToSelect = row;
|
int rowToSelect = row;
|
||||||
if (row > matchesTableModel.getRowCount()) {
|
if (row > matchesTableModel.getRowCount()) {
|
||||||
// The model has shrunk. Not sure what the best action is?
|
// The model has shrunk. Not sure what the best action is?
|
||||||
tryToSelectMatch(selectionModel);// this only works if we are tracking by match and not index
|
tryToSelectMatch(selectionModel);// this only works if we are tracking by match and not index
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point the selection model may still believe that its selection is the
|
// At this point the selection model may still believe that its selection is the
|
||||||
// value we are setting. Calling clearSelection() will kick the model. Without the
|
// value we are setting. Calling clearSelection() will kick the model. Without the
|
||||||
// kick, the setSelectionInterval() call we make may ultimately have no effect.
|
// kick, the setSelectionInterval() call we make may ultimately have no effect.
|
||||||
selectionModel.clearSelection();
|
selectionModel.clearSelection();
|
||||||
|
|
||||||
if (tableSelectionState == MAINTAIN_SELECTED_ROW_INDEX) {
|
if (tableSelectionState == MAINTAIN_SELECTED_ROW_INDEX) {
|
||||||
// In this state we are tracking row selection, so just select the previously
|
// In this state we are tracking row selection, so just select the previously
|
||||||
// selected row.
|
// selected row.
|
||||||
selectionModel.setSelectionInterval(rowToSelect, rowToSelect);
|
selectionModel.setSelectionInterval(rowToSelect, rowToSelect);
|
||||||
matchesTable.scrollToSelectedRow();
|
matchesTable.scrollToSelectedRow();
|
||||||
@@ -874,7 +871,7 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tryToSelectMatch(ListSelectionModel selectionModel) {
|
private void tryToSelectMatch(ListSelectionModel selectionModel) {
|
||||||
// In this state we are tracking the value that was selected and we want to
|
// In this state we are tracking the value that was selected and we want to
|
||||||
// reselect that value.
|
// reselect that value.
|
||||||
int matchRow = matchesTableModel.getRowIndex(match);
|
int matchRow = matchesTableModel.getRowIndex(match);
|
||||||
if (matchRow >= 0 && matchRow < matchesTableModel.getRowCount()) {
|
if (matchRow >= 0 && matchRow < matchesTableModel.getRowCount()) {
|
||||||
@@ -890,8 +887,8 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the built-in SelectionManager so that we can respond to the current table
|
* Override the built-in SelectionManager so that we can respond to the current table
|
||||||
* selection mode.
|
* selection mode.
|
||||||
*/
|
*/
|
||||||
private class VTMatchTableSelectionManager extends RowObjectSelectionManager<VTMatch> {
|
private class VTMatchTableSelectionManager extends RowObjectSelectionManager<VTMatch> {
|
||||||
VTMatchTableSelectionManager(JTable table, AbstractSortedTableModel<VTMatch> tableModel) {
|
VTMatchTableSelectionManager(JTable table, AbstractSortedTableModel<VTMatch> tableModel) {
|
||||||
|
|||||||
+20
-5
@@ -41,11 +41,8 @@ public abstract class VtTask extends Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void run(TaskMonitor monitor) {
|
public final void run(TaskMonitor monitor) {
|
||||||
boolean restoreEvents = false;
|
boolean restoreEvents = suspendEvents();
|
||||||
if (session != null && shouldSuspendSessionEvents()) {
|
|
||||||
session.setEventsEnabled(false);
|
|
||||||
restoreEvents = true;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
success = doWork(monitor);
|
success = doWork(monitor);
|
||||||
}
|
}
|
||||||
@@ -62,6 +59,24 @@ public abstract class VtTask extends Task {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean suspendEvents() {
|
||||||
|
|
||||||
|
if (session == null) {
|
||||||
|
return false; // no events to suspend
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shouldSuspendSessionEvents()) {
|
||||||
|
return false; // this task has chosen not to suspend events
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session.isSendingEvents()) {
|
||||||
|
return false; // someone external to this task is managing events
|
||||||
|
}
|
||||||
|
|
||||||
|
session.setEventsEnabled(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if session events should be suspended during task execution.
|
* Determine if session events should be suspended during task execution.
|
||||||
* This can improve performance during task execution at the expense of bulk
|
* This can improve performance during task execution at the expense of bulk
|
||||||
|
|||||||
+18
-26
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -19,7 +19,6 @@ import static ghidra.feature.vt.db.VTTestUtils.*;
|
|||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
@@ -29,7 +28,7 @@ import ghidra.feature.vt.api.main.*;
|
|||||||
import ghidra.feature.vt.api.util.VTAssociationStatusException;
|
import ghidra.feature.vt.api.util.VTAssociationStatusException;
|
||||||
import ghidra.feature.vt.db.VTTestUtils;
|
import ghidra.feature.vt.db.VTTestUtils;
|
||||||
import ghidra.feature.vt.gui.VTTestEnv;
|
import ghidra.feature.vt.gui.VTTestEnv;
|
||||||
import ghidra.feature.vt.gui.actions.AutoVersionTrackingCommand;
|
import ghidra.feature.vt.gui.actions.AutoVersionTrackingTask;
|
||||||
import ghidra.feature.vt.gui.plugin.VTController;
|
import ghidra.feature.vt.gui.plugin.VTController;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.program.database.ProgramDB;
|
import ghidra.program.database.ProgramDB;
|
||||||
@@ -42,7 +41,7 @@ import ghidra.program.model.symbol.SourceType;
|
|||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskLauncher;
|
||||||
|
|
||||||
public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTest {
|
public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@@ -84,8 +83,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
controller = env.getVTController();
|
controller = env.getVTController();
|
||||||
|
|
||||||
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
|
// Score .999999 and confidence 10.0 (log10 confidence 2.0) and up
|
||||||
boolean success = runAutoVTCommand(0.999999999, 10.0);
|
runAutoVTCommand(0.999999999, 10.0);
|
||||||
assertTrue("Auto Version Tracking Command failed to run", success);
|
|
||||||
|
|
||||||
// verify that the default options are what we expect
|
// verify that the default options are what we expect
|
||||||
// if this assert fails then the follow-on tests will probably fail
|
// if this assert fails then the follow-on tests will probably fail
|
||||||
@@ -146,8 +144,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
|
|
||||||
// Score 0.5 and conf threshold 1.0 allow similarity scores of higher than 0.5 for combined
|
// Score 0.5 and conf threshold 1.0 allow similarity scores of higher than 0.5 for combined
|
||||||
// reference correlator and 1.0 and higher for the log 10 confidence score
|
// reference correlator and 1.0 and higher for the log 10 confidence score
|
||||||
boolean success = runAutoVTCommand(0.5, 1.0);
|
runAutoVTCommand(0.5, 1.0);
|
||||||
assertTrue("Auto Version Tracking Command failed to run", success);
|
|
||||||
|
|
||||||
// verify that the default options are what we expect
|
// verify that the default options are what we expect
|
||||||
// if this assert fails then the follow-on tests will probably fail
|
// if this assert fails then the follow-on tests will probably fail
|
||||||
@@ -613,8 +610,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
sourceProgram.endTransaction(startTransaction, true);
|
sourceProgram.endTransaction(startTransaction, true);
|
||||||
|
|
||||||
// run Auto VT
|
// run Auto VT
|
||||||
boolean success = runAutoVTCommand(1.0, 10.0);
|
runAutoVTCommand(1.0, 10.0);
|
||||||
assertTrue("Auto Version Tracking Command failed to run", success);
|
|
||||||
|
|
||||||
// Check that the match we are interested in got accepted
|
// Check that the match we are interested in got accepted
|
||||||
String correlator = "Combined Function and Data Reference Match";
|
String correlator = "Combined Function and Data Reference Match";
|
||||||
@@ -670,8 +666,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
sourceProgram.endTransaction(startTransaction, true);
|
sourceProgram.endTransaction(startTransaction, true);
|
||||||
|
|
||||||
// run Auto VT
|
// run Auto VT
|
||||||
boolean success = runAutoVTCommand(1.0, 10.0);
|
runAutoVTCommand(1.0, 10.0);
|
||||||
assertTrue("Auto Version Tracking Command failed to run", success);
|
|
||||||
|
|
||||||
// Check that the match we are interested in got accepted
|
// Check that the match we are interested in got accepted
|
||||||
String correlator = "Duplicate Function Instructions Match";
|
String correlator = "Duplicate Function Instructions Match";
|
||||||
@@ -735,8 +730,7 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
|
|
||||||
// Now run the AutoVT command with lower confidence thresholds to allow the match we want to
|
// Now run the AutoVT command with lower confidence thresholds to allow the match we want to
|
||||||
// test in as a match
|
// test in as a match
|
||||||
boolean success = runAutoVTCommand(0.5, 1.0);
|
runAutoVTCommand(0.5, 1.0);
|
||||||
assertTrue("Auto Version Tracking Command failed to run", success);
|
|
||||||
|
|
||||||
// Check that the match we are interested in got accepted
|
// Check that the match we are interested in got accepted
|
||||||
String correlator = "Combined Function and Data Reference Match";
|
String correlator = "Combined Function and Data Reference Match";
|
||||||
@@ -829,20 +823,18 @@ public class VTAutoVersionTrackingTest extends AbstractGhidraHeadedIntegrationTe
|
|||||||
assertEquals(expectedAcceptedMatchCount, getNumAcceptedMatches(vtSession, correlatorName));
|
assertEquals(expectedAcceptedMatchCount, getNumAcceptedMatches(vtSession, correlatorName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean runAutoVTCommand(double minReferenceCorrelatorScore,
|
private void runAutoVTCommand(double minReferenceCorrelatorScore,
|
||||||
double minReferenceCorrelatorConfidence) {
|
double minReferenceCorrelatorConfidence) {
|
||||||
AtomicBoolean result = new AtomicBoolean();
|
|
||||||
runSwing(() -> {
|
|
||||||
String transactionName = "Auto Version Tracking Test";
|
|
||||||
int startTransaction = session.startTransaction(transactionName);
|
|
||||||
|
|
||||||
AutoVersionTrackingCommand vtCommand = new AutoVersionTrackingCommand(controller,
|
AutoVersionTrackingTask task = new AutoVersionTrackingTask(controller, session,
|
||||||
session, minReferenceCorrelatorScore, minReferenceCorrelatorConfidence);
|
minReferenceCorrelatorScore, minReferenceCorrelatorConfidence);
|
||||||
result.set(vtCommand.applyTo(session, TaskMonitor.DUMMY));
|
TaskLauncher.launch(task);
|
||||||
|
waitForSession();
|
||||||
|
}
|
||||||
|
|
||||||
session.endTransaction(startTransaction, result.get());
|
private void waitForSession() {
|
||||||
});
|
session.flushEvents();
|
||||||
return result.get();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private VTMatchSet getVTMatchSet(VTSession vtSession, String correlatorName) {
|
private VTMatchSet getVTMatchSet(VTSession vtSession, String correlatorName) {
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public interface DomainObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the object has changed.
|
* Returns whether the object has changed.
|
||||||
|
* @return whether the object has changed.
|
||||||
*/
|
*/
|
||||||
public boolean isChanged();
|
public boolean isChanged();
|
||||||
|
|
||||||
@@ -87,17 +88,19 @@ public interface DomainObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this object has been marked as Temporary.
|
* Returns true if this object has been marked as Temporary.
|
||||||
|
* @return true if this object has been marked as Temporary.
|
||||||
*/
|
*/
|
||||||
public boolean isTemporary();
|
public boolean isTemporary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if changes are permitted.
|
* Returns true if changes are permitted.
|
||||||
|
* @return true if changes are permitted.
|
||||||
*/
|
*/
|
||||||
public boolean isChangeable();
|
public boolean isChangeable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this object can be saved; a read-only file
|
* Returns true if this object can be saved; a read-only file cannot be saved.
|
||||||
* cannot be saved.
|
* @return true if this object can be saved
|
||||||
*/
|
*/
|
||||||
public boolean canSave();
|
public boolean canSave();
|
||||||
|
|
||||||
@@ -118,8 +121,8 @@ public interface DomainObject {
|
|||||||
* Saves (i.e., serializes) the current content to a packed file.
|
* Saves (i.e., serializes) the current content to a packed file.
|
||||||
* @param outputFile packed output file
|
* @param outputFile packed output file
|
||||||
* @param monitor progress monitor
|
* @param monitor progress monitor
|
||||||
* @throws IOException
|
* @throws IOException if an exception occurs
|
||||||
* @throws CancelledException
|
* @throws CancelledException if the user cancels
|
||||||
* @throws UnsupportedOperationException if not supported by object implementation
|
* @throws UnsupportedOperationException if not supported by object implementation
|
||||||
*/
|
*/
|
||||||
public void saveToPackedFile(File outputFile, TaskMonitor monitor)
|
public void saveToPackedFile(File outputFile, TaskMonitor monitor)
|
||||||
@@ -127,9 +130,9 @@ public interface DomainObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the domain object that the specified consumer is no longer using it.
|
* Notify the domain object that the specified consumer is no longer using it.
|
||||||
* When the last consumer invokes this method, the domain object will be closed
|
* When the last consumer invokes this method, the domain object will be closed
|
||||||
* and will become invalid.
|
* and will become invalid.
|
||||||
* @param consumer the consumer (e.g., tool, plugin, etc) of the domain object
|
* @param consumer the consumer (e.g., tool, plugin, etc) of the domain object
|
||||||
* previously established with the addConsumer method.
|
* previously established with the addConsumer method.
|
||||||
*/
|
*/
|
||||||
public void release(Object consumer);
|
public void release(Object consumer);
|
||||||
@@ -149,14 +152,14 @@ public interface DomainObject {
|
|||||||
/**
|
/**
|
||||||
* Adds a listener that will be notified when this DomainObject is closed. This is meant
|
* Adds a listener that will be notified when this DomainObject is closed. This is meant
|
||||||
* for clients to have a chance to cleanup, such as reference removal.
|
* for clients to have a chance to cleanup, such as reference removal.
|
||||||
*
|
*
|
||||||
* @param listener the reference to add
|
* @param listener the reference to add
|
||||||
*/
|
*/
|
||||||
public void addCloseListener(DomainObjectClosedListener listener);
|
public void addCloseListener(DomainObjectClosedListener listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given close listener.
|
* Removes the given close listener.
|
||||||
*
|
*
|
||||||
* @param listener the listener to remove.
|
* @param listener the listener to remove.
|
||||||
*/
|
*/
|
||||||
public void removeCloseListener(DomainObjectClosedListener listener);
|
public void removeCloseListener(DomainObjectClosedListener listener);
|
||||||
@@ -179,11 +182,13 @@ public interface DomainObject {
|
|||||||
/**
|
/**
|
||||||
* Returns a word or short phrase that best describes or categorizes
|
* Returns a word or short phrase that best describes or categorizes
|
||||||
* the object in terms that a user will understand.
|
* the object in terms that a user will understand.
|
||||||
|
* @return the description
|
||||||
*/
|
*/
|
||||||
public String getDescription();
|
public String getDescription();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of this domain object.
|
* Get the name of this domain object.
|
||||||
|
* @return the name
|
||||||
*/
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
@@ -195,7 +200,7 @@ public interface DomainObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the domain file for this domain object.
|
* Get the domain file for this domain object.
|
||||||
* @return the associated domain file
|
* @return the associated domain file
|
||||||
*/
|
*/
|
||||||
public DomainFile getDomainFile();
|
public DomainFile getDomainFile();
|
||||||
|
|
||||||
@@ -207,13 +212,13 @@ public interface DomainObject {
|
|||||||
*/
|
*/
|
||||||
public boolean addConsumer(Object consumer);
|
public boolean addConsumer(Object consumer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of consumers on this domainObject
|
* Returns the list of consumers on this domainObject
|
||||||
* @return the list of consumers.
|
* @return the list of consumers.
|
||||||
*/
|
*/
|
||||||
public ArrayList<Object> getConsumerList();
|
public ArrayList<Object> getConsumerList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given consumer is using (has open) this domain object.
|
* Returns true if the given consumer is using (has open) this domain object.
|
||||||
* @param consumer the object to test to see if it is a consumer of this domain object.
|
* @param consumer the object to test to see if it is a consumer of this domain object.
|
||||||
* @return true if the given consumer is using (has open) this domain object;
|
* @return true if the given consumer is using (has open) this domain object;
|
||||||
@@ -229,8 +234,8 @@ public interface DomainObject {
|
|||||||
* <p>
|
* <p>
|
||||||
* NOTE: when re-enabling events, an event will be sent to the system to signal that
|
* NOTE: when re-enabling events, an event will be sent to the system to signal that
|
||||||
* every listener should update.
|
* every listener should update.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param enabled true means to enable events
|
* @param enabled true means to enable events
|
||||||
*/
|
*/
|
||||||
public void setEventsEnabled(boolean enabled);
|
public void setEventsEnabled(boolean enabled);
|
||||||
@@ -238,7 +243,8 @@ public interface DomainObject {
|
|||||||
/**
|
/**
|
||||||
* Returns true if this object is sending out events as it is changed. The default is
|
* Returns true if this object is sending out events as it is changed. The default is
|
||||||
* true. You can change this value by calling {@link #setEventsEnabled(boolean)}.
|
* true. You can change this value by calling {@link #setEventsEnabled(boolean)}.
|
||||||
*
|
*
|
||||||
|
* @return true if sending events
|
||||||
* @see #setEventsEnabled(boolean)
|
* @see #setEventsEnabled(boolean)
|
||||||
*/
|
*/
|
||||||
public boolean isSendingEvents();
|
public boolean isSendingEvents();
|
||||||
@@ -258,26 +264,27 @@ public interface DomainObject {
|
|||||||
* Returns true if a modification lock can be obtained on this
|
* Returns true if a modification lock can be obtained on this
|
||||||
* domain object. Care should be taken with using this method since
|
* domain object. Care should be taken with using this method since
|
||||||
* this will not prevent another thread from modifying the domain object.
|
* this will not prevent another thread from modifying the domain object.
|
||||||
|
* @return true if can lock
|
||||||
*/
|
*/
|
||||||
public boolean canLock();
|
public boolean canLock();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the domain object currenly has a modification lock enabled.
|
* Returns true if the domain object currently has a modification lock enabled.
|
||||||
|
* @return true if locked
|
||||||
*/
|
*/
|
||||||
public boolean isLocked();
|
public boolean isLocked();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to obtain a modification lock on the domain object. Multiple locks
|
* Attempt to obtain a modification lock on the domain object. Multiple locks may be granted
|
||||||
* may be granted on this domain object, although all lock owners must release their
|
* on this domain object, although all lock owners must release their lock in a timely fashion.
|
||||||
* lock in a timely fashion.
|
|
||||||
* @param reason very short reason for requesting lock
|
* @param reason very short reason for requesting lock
|
||||||
* @return true if lock obtained successfully, else false which indicates that a
|
* @return true if lock obtained successfully, else false which indicates that a modification
|
||||||
* modification is in process.
|
* is in process.
|
||||||
*/
|
*/
|
||||||
public boolean lock(String reason);
|
public boolean lock(String reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels any previous lock and aquires it.
|
* Cancels any previous lock and acquires it.
|
||||||
* @param rollback if true, any changes in made with the previous lock should be discarded.
|
* @param rollback if true, any changes in made with the previous lock should be discarded.
|
||||||
* @param reason very short reason for requesting lock
|
* @param reason very short reason for requesting lock
|
||||||
*/
|
*/
|
||||||
@@ -290,7 +297,7 @@ public interface DomainObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all properties lists contained by this domain object.
|
* Returns all properties lists contained by this domain object.
|
||||||
*
|
*
|
||||||
* @return all property lists contained by this domain object.
|
* @return all property lists contained by this domain object.
|
||||||
*/
|
*/
|
||||||
public List<String> getOptionsNames();
|
public List<String> getOptionsNames();
|
||||||
@@ -298,17 +305,20 @@ public interface DomainObject {
|
|||||||
/**
|
/**
|
||||||
* Get the property list for the given name.
|
* Get the property list for the given name.
|
||||||
* @param propertyListName name of property list
|
* @param propertyListName name of property list
|
||||||
|
* @return the options
|
||||||
*/
|
*/
|
||||||
public Options getOptions(String propertyListName);
|
public Options getOptions(String propertyListName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this domain object has been closed as a result of the last release
|
* Returns true if this domain object has been closed as a result of the last release
|
||||||
|
* @return true if closed
|
||||||
*/
|
*/
|
||||||
public boolean isClosed();
|
public boolean isClosed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the user has exclusive access to the domain object. Exclusive access means
|
* Returns true if the user has exclusive access to the domain object. Exclusive access means
|
||||||
* either the object is not shared or the user has an exclusive checkout on the object.
|
* either the object is not shared or the user has an exclusive checkout on the object.
|
||||||
|
* @return true if has exclusive access
|
||||||
*/
|
*/
|
||||||
public boolean hasExclusiveAccess();
|
public boolean hasExclusiveAccess();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user