private String buildTestFileDigest(HashSet<String> duplicateTests) {

		StringBuilder testFileDigest = new StringBuilder();
		String title = "*** " + getClass().getSimpleName() + " P-Code Test Suite (" +
			processorDesignator + ") ";
		title = StringUtilities.pad(title, '*', -80);
		testFileDigest.append(title);
		testFileDigest.append("\n");
		for (PCodeTestControlBlock controlBlock : testControlBlocks) {
			testFileDigest.append("* ");
			testFileDigest.append(controlBlock.testFile.fileReferencePath);
			testFileDigest.append(" (TestInfo @ ");
			testFileDigest.append(controlBlock.getInfoStructureAddress().toString(true));
			testFileDigest.append(")\n");

			// compute column width for group function name and address
			int paddedLen = 0;
			for (PCodeTestGroup testGroup : controlBlock.getTestGroups()) {
				int len = testGroup.testGroupName.length() +
					testGroup.functionEntryPtr.toString(true).length() + 3;
				if (len > paddedLen) {
					paddedLen = len;
				}
			}

			for (PCodeTestGroup testGroup : controlBlock.getTestGroups()) {
				testFileDigest.append("*   - ");
				String nameAndAddr =
					testGroup.testGroupName + " @ " + testGroup.functionEntryPtr.toString(true);
				nameAndAddr = StringUtilities.pad(nameAndAddr, ' ', -paddedLen);
				testFileDigest.append(nameAndAddr);
				testFileDigest.append(" (GroupInfo @ ");
				testFileDigest
						.append(testGroup.controlBlock.getInfoStructureAddress().toString(true));
				testFileDigest.append(")");
				if (duplicateTests.contains(testGroup.testGroupName)) {
					testFileDigest.append(" *DUPLICATE*");
				}
				testFileDigest.append("\n");
			}
		}
		testFileDigest.append(StringUtilities.pad("", '*', 80));

		return testFileDigest.toString();
	}
@return true if test run should fail up-front if binary contains relocation errors
Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/ProcessorEmulatorTestAdapter.java