## @file
# Unit and functional tests for GenFv XIP rebase behavior
#
# Tests the ,XIP suffix generation in Python GenFds and the
# ForceRebase/XIP decision logic in C GenFv.
#
# Test Plan Summary:
#
# FfsRebase() in GenFvInternalLib.c decides whether to rebase each PE/COFF
# image in an FV based on three inputs: ForceRebase, BaseAddress, and XipFile[].
#
#   ForceRebase  BaseAddress  XipFileCount  XipFile[]  Result
#   -----------  -----------  ------------  ---------  ---------------------------------
#   -1 (unset)   0            any           any        No rebase (early return)
#   0  (FALSE)   any          any           any        No rebase (early return)
#   1  (TRUE)    any          0             any        Rebase ALL files (legacy compat)
#   1  (TRUE)    any          > 0           FALSE      No rebase (skip non-XIP file)
#   1  (TRUE)    any          > 0           TRUE       Rebase (XIP file selected)
#   -1 (unset)   != 0         any           any        Rebase ALL files (legacy path)
#
# Unit Tests (TestDetermineXipEnabled):
#   11 parameterized subtests calling FfsInfStatement.DetermineXipEnabled()
#   with RuleComplexFile and RuleSimpleFile objects to verify Xip attribute
#   parsing (TRUE/FALSE/None, case insensitive, boolean vs string).
#
# Functional Tests (TestFunctionalBuildXipRebase):
#   8 test cases using real edk2 builds with generated DSC/FDF files
#   containing a test package (2 PEIMs + 1 DXE driver). Each test
#   verifies:
#     1. FV INF file has correct ,XIP suffix on EFI_FILE_NAME entries
#     2. FV map file shows correct rebase status (Fixed Flash Address)
#     3. PE/COFF ImageBase in the FV binary matches expected value
#
#   TC1: ForceRebase=unset, Base=0        -> no rebase
#   TC2: ForceRebase=unset, Base!=0       -> rebase all (legacy)
#   TC3: ForceRebase=FALSE, Base!=0       -> no rebase
#   TC4: ForceRebase=TRUE,  all Xip=TRUE  -> rebase all
#   TC5: ForceRebase=TRUE,  selective Xip -> rebase only Xip=TRUE
#   TC6: ForceRebase=TRUE,  no Xip        -> rebase all (legacy compat)
#   TC7: ForceRebase=TRUE,  mixed Xip     -> rebase Xip=TRUE only
#   TC8: ForceRebase=TRUE,  Base=0, Xip   -> rebase (force overrides)
#
# Copyright (c) 2026, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

import ctypes
import os
import re
import shutil
import subprocess
import sys
import threading
import unittest
from pathlib import Path

# Add BaseTools Python source to path
_TESTS_DIR = Path(__file__).resolve().parent
_PYTHON_SRC = str(_TESTS_DIR.parent / 'Source' / 'Python')
if _PYTHON_SRC not in sys.path:
    sys.path.insert(0, _PYTHON_SRC)

from GenFds.RuleComplexFile import RuleComplexFile
from GenFds.RuleSimpleFile import RuleSimpleFile
from GenFds.EfiSection import EfiSection
from GenFds.FfsInfStatement import FfsInfStatement
from FirmwareStorageFormat.FvHeader import EFI_FIRMWARE_VOLUME_HEADER
from FirmwareStorageFormat.FfsFileHeader import EFI_FFS_FILE_HEADER
from FirmwareStorageFormat.SectionHeader import (
    EFI_COMMON_SECTION_HEADER,
    EFI_SECTION_PE32,
)
from FirmwareStorageFormat.PECOFFHeader import (
    EFI_IMAGE_DOS_HEADER,
    EFI_IMAGE_DOS_SIGNATURE,
    EFI_IMAGE_NT_HEADERS32,
    EFI_IMAGE_NT_HEADERS64,
    EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC,
    EFI_IMAGE_NT_SIGNATURE,
)


class TestDetermineXipEnabled(unittest.TestCase):
    """Test FfsInfStatement.DetermineXipEnabled() with real Rule objects.

    This calls the actual production code that determines whether XIP
    is enabled based on a Rule object's Xip attribute(s).
    """

    _UNSET = object()  # sentinel: do not set the Xip attribute

    # (rule_class, section_xip_list, rule_xip, expected, description)
    #
    # For RuleComplexFile:
    #   section_xip_list is a list of Xip values per EfiSection (_UNSET = no attr).
    #   rule_xip is ignored (_UNSET).
    #
    # For RuleSimpleFile:
    #   section_xip_list is None (no SectionList used).
    #   rule_xip is the value to assign to rule.Xip (_UNSET = leave default).
    TEST_CASES = [
        # RuleComplexFile: one section with Xip='TRUE'.
        # DetermineXipEnabled iterates SectionList looking for any section with
        # Xip set to 'TRUE' (case-insensitive string match).
        # A single section set to 'TRUE' should return True (XIP-eligible).
        (RuleComplexFile, ['TRUE'],         _UNSET, True,
         'Complex: section Xip=TRUE'),
        # RuleComplexFile: Xip='true' (lowercase).
        # The FDF parser normalizes keywords but DetermineXipEnabled uses
        # case-insensitive matching. Verifies 'true' is equivalent to 'TRUE'.
        (RuleComplexFile, ['true'],         _UNSET, True,
         'Complex: section Xip=true (case insensitive)'),
        # RuleComplexFile: one section with Xip='FALSE'.
        # An explicit 'FALSE' must not be confused with 'TRUE'. Confirms the
        # string 'FALSE' does not accidentally match the 'TRUE' comparison.
        (RuleComplexFile, ['FALSE'],        _UNSET, False,
         'Complex: section Xip=FALSE'),
        # RuleComplexFile: section with no Xip attribute set.
        # EfiSection.__init__ does not set Xip by default. Verifies that when
        # the FDF rule omits the Xip keyword, DetermineXipEnabled returns False
        # without raising an AttributeError.
        (RuleComplexFile, [_UNSET],         _UNSET, False,
         'Complex: section with no Xip attribute'),
        # RuleComplexFile: two sections, only the second has Xip=TRUE.
        # DetermineXipEnabled should return True if ANY section in the list has
        # Xip=TRUE, not just the first. Tests iteration with Xip=TRUE at index 1.
        (RuleComplexFile, [_UNSET, 'TRUE'], _UNSET, True,
         'Complex: multiple sections, one Xip=TRUE'),
        # RuleComplexFile: empty SectionList.
        # Edge case: a complex rule with no sections should safely return False
        # without raising an exception from iterating an empty list.
        (RuleComplexFile, [],               _UNSET, False,
         'Complex: empty section list'),
        # RuleSimpleFile: Xip='TRUE' (string).
        # Unlike RuleComplexFile, RuleSimpleFile stores Xip directly on the
        # rule object. Verifies the string 'TRUE' path via isinstance check.
        (RuleSimpleFile,  None, 'TRUE',  True,
         'Simple: Xip=TRUE (string)'),
        # RuleSimpleFile: Xip=True (Python boolean).
        # The FDF parser may set Xip as a boolean True rather than the string
        # 'TRUE'. Verifies that a Python boolean True is recognized as XIP.
        (RuleSimpleFile,  None, True,    True,
         'Simple: Xip=True (boolean)'),
        # RuleSimpleFile: Xip='FALSE' (string).
        # Verifies that an explicit 'FALSE' string causes DetermineXipEnabled
        # to return False. Complement of the 'TRUE' string test.
        (RuleSimpleFile,  None, 'FALSE', False,
         'Simple: Xip=FALSE'),
        # RuleSimpleFile: default Xip value from RuleClassObject.__init__.
        # When constructed without setting Xip, the default is False (boolean).
        # Represents the common case where the FDF rule omits the Xip keyword.
        (RuleSimpleFile,  None, _UNSET,  False,
         'Simple: default Xip (not set)'),
        # RuleSimpleFile: Xip=None.
        # Edge case: if code or a parser bug sets Xip=None, it should be
        # treated as falsy and return False rather than raising a TypeError.
        (RuleSimpleFile,  None, None,    False,
         'Simple: Xip=None'),
    ]

    def test_determine_xip_enabled(self) -> None:
        """Parameterized test for DetermineXipEnabled with Rule objects."""
        for rule_class, section_xip_list, rule_xip, expected, desc in self.TEST_CASES:
            with self.subTest(desc):
                rule = rule_class()
                if section_xip_list is not None:
                    # RuleComplexFile: build SectionList
                    rule.SectionList = []
                    for xip_val in section_xip_list:
                        sect = EfiSection()
                        if xip_val is not self._UNSET:
                            sect.Xip = xip_val
                        rule.SectionList.append(sect)
                elif rule_xip is not self._UNSET:
                    # RuleSimpleFile: set Xip on rule
                    rule.Xip = rule_xip
                self.assertEqual(
                    FfsInfStatement.DetermineXipEnabled(rule), expected
                )


class TestFunctionalBuildXipRebase(unittest.TestCase):
    """Functional tests that build with generated DSC/FDF files to exercise
    all ForceRebase/BaseAddress/Xip combinations.

    Prerequisites:
    - edksetup has been run (sets WORKSPACE and puts build in PATH)
    - BaseTools C binaries built (GenFv.exe, etc.)
    - A working compiler toolchain (VS2022, GCC5, etc.)

    Each test case verifies:
    1. FV INF file has correct ,XIP suffix on EFI_FILE_NAME entries
    2. FV map file shows correct rebase status (Fixed Flash Address)
    3. PE/COFF ImageBase in the FV binary matches expected value
    """

    WORKSPACE = None
    TOOLCHAIN = None
    BUILD_AVAILABLE = False

    # Module names in FV file order (matches INF listing in FDF_TEMPLATE)
    _MODULE_NAMES = ('TestPeim', 'TestPeim2', 'TestDxeDriver')

    # --- File content constants / templates ---

    DEC_CONTENT = """\
[Defines]
  DEC_SPECIFICATION = 0x00010005
  PACKAGE_NAME      = TestXipRebasePkg
  PACKAGE_GUID      = FC530350-34AA-4498-88F5-BF71987785B2
  PACKAGE_VERSION   = 1.0
"""

    PEIM_C_TEMPLATE = """\
#include <PiPei.h>
#include <Library/PeimEntryPoint.h>

EFI_STATUS
EFIAPI
{entry_point} (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{{
  return EFI_SUCCESS;
}}
"""

    PEIM_INF_TEMPLATE = """\
[Defines]
  INF_VERSION    = 0x00010005
  BASE_NAME      = {base_name}
  FILE_GUID      = {file_guid}
  MODULE_TYPE    = PEIM
  VERSION_STRING = 1.0
  ENTRY_POINT    = {entry_point}

[Sources]
  {source_file}

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  PeimEntryPoint

[Depex]
  TRUE
"""

    DXE_C_SOURCE = """\
#include <Uefi.h>
#include <Library/UefiDriverEntryPoint.h>

EFI_STATUS
EFIAPI
TestDxeDriverEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EFI_SUCCESS;
}
"""

    DXE_INF = """\
[Defines]
  INF_VERSION    = 0x00010005
  BASE_NAME      = TestDxeDriver
  FILE_GUID      = FEC0E1C9-544F-493E-9BD1-91263C7970FC
  MODULE_TYPE    = DXE_DRIVER
  VERSION_STRING = 1.0
  ENTRY_POINT    = TestDxeDriverEntry

[Sources]
  TestDxeDriver.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiDriverEntryPoint

[Depex]
  TRUE
"""

    DSC_CONTENT = """\
[Defines]
  PLATFORM_NAME           = TestXipRebase
  PLATFORM_GUID           = A44E9966-C1A1-47E8-8B21-8B773705DD79
  PLATFORM_VERSION        = 1.0
  DSC_SPECIFICATION       = 0x00010005
  OUTPUT_DIRECTORY        = Build/TestXipRebase
  SUPPORTED_ARCHITECTURES = X64
  BUILD_TARGETS           = DEBUG
  SKUID_IDENTIFIER        = DEFAULT

!include MdePkg/MdeLibs.dsc.inc

[LibraryClasses]
  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf

[Components]
  TestXipRebasePkg/TestPeim/TestPeim.inf
  TestXipRebasePkg/TestPeim2/TestPeim2.inf
  TestXipRebasePkg/TestDxeDriver/TestDxeDriver.inf {
    <BuildOptions>
      MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096
      GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
  }
"""

    PEIM2_RULE_TEMPLATE = """
[Rule.Common.PEIM.PEIM2RULE]
  FILE PEIM = $(NAMED_GUID) {{
    PE32  PE32  Align=Auto{peim2_xip_clause}  $(INF_OUTPUT)/$(MODULE_NAME).efi
  }}
"""

    FDF_TEMPLATE = """\

[FV.{fv_name}]
FvNameGuid = 15942B69-82DC-41DC-9F01-D60162870C4A
{base_line}\
{force_line}\
BlockSize = 0x10000
NumBlocks = 0x10
FvAlignment = 16
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE

INF  TestXipRebasePkg/TestPeim/TestPeim.inf
{peim2_inf_line}
INF  TestXipRebasePkg/TestDxeDriver/TestDxeDriver.inf

[Rule.Common.PEIM]
  FILE PEIM = $(NAMED_GUID) {{
    PE32  PE32  Align=Auto{peim1_xip_clause}  $(INF_OUTPUT)/$(MODULE_NAME).efi
  }}
{peim2_rule}\
[Rule.Common.DXE_DRIVER]
  FILE DRIVER = $(NAMED_GUID) {{
    PE32  PE32{dxe_xip_clause}  $(INF_OUTPUT)/$(MODULE_NAME).efi
  }}
"""

    @classmethod
    def _detect_toolchain(cls) -> str:
        """Get toolchain from --toolchain command line option (default: VS2022).

        Returns:
            Toolchain tag string (e.g. 'VS2022', 'GCC5').
        """
        for i, arg in enumerate(sys.argv):
            if arg == '--toolchain' and i + 1 < len(sys.argv):
                return sys.argv[i + 1]
            if arg.startswith('--toolchain='):
                return arg.split('=', 1)[1]
        return 'VS2022'

    @classmethod
    def setUpClass(cls) -> None:
        cls.WORKSPACE = os.environ.get('WORKSPACE')
        if cls.WORKSPACE is None:
            return
        cls.TOOLCHAIN = cls._detect_toolchain()
        try:
            result = subprocess.run(
                'build --version', capture_output=True, text=True,
                timeout=30, cwd=cls.WORKSPACE, shell=True
            )
            cls.BUILD_AVAILABLE = result.returncode == 0
        except (FileNotFoundError, subprocess.TimeoutExpired):
            pass

    @classmethod
    def tearDownClass(cls) -> None:
        """Clean up generated test package directory."""
        if cls.WORKSPACE:
            pkg_dir = Path(cls.WORKSPACE, 'TestXipRebasePkg')
            if pkg_dir.is_dir():
                shutil.rmtree(pkg_dir, ignore_errors=True)

    def setUp(self) -> None:
        if self.WORKSPACE is None:
            self.fail("WORKSPACE environment variable is not set. "
                      "Run edksetup before running tests.")
        if not self.BUILD_AVAILABLE:
            self.fail("edk2 'build' command not found in PATH. "
                      "Run edksetup before running tests.")

    # --- Test package generation ---

    def _create_test_package(self) -> str:
        """Create a minimal test package with two PEIMs and one DXE driver.

        Returns:
            Absolute path to the created package directory.
        """
        pkg = Path(self.WORKSPACE, 'TestXipRebasePkg')
        pkg.mkdir(parents=True, exist_ok=True)
        (pkg / 'TestXipRebasePkg.dec').write_text(self.DEC_CONTENT)

        # Generate PEIM modules from template
        for name, guid, entry in [
            ('TestPeim',  'F43835C3-245F-4951-9D35-8684B98328DA', 'TestPeimEntry'),
            ('TestPeim2', '816C5A1F-23A8-485F-B005-D565FD01E303', 'TestPeim2Entry'),
        ]:
            mod = pkg / name
            mod.mkdir(parents=True, exist_ok=True)
            (mod / f'{name}.c').write_text(
                self.PEIM_C_TEMPLATE.format(entry_point=entry))
            (mod / f'{name}.inf').write_text(
                self.PEIM_INF_TEMPLATE.format(
                    base_name=name, file_guid=guid,
                    entry_point=entry, source_file=f'{name}.c'))

        # DXE driver (different includes/signature, not templated)
        dxe = pkg / 'TestDxeDriver'
        dxe.mkdir(parents=True, exist_ok=True)
        (dxe / 'TestDxeDriver.c').write_text(self.DXE_C_SOURCE)
        (dxe / 'TestDxeDriver.inf').write_text(self.DXE_INF)

        return str(pkg)

    def _generate_fdf(self, pkg_dir: str, fv_name: str,
                      base_address: str | None, force_rebase: str | None,
                      peim1_xip: str | None, peim2_xip: str | None,
                      dxe_xip: str | None) -> str:
        """Generate an FDF file with the specified FV settings.

        Args:
            pkg_dir: Package directory path.
            fv_name: Name for the firmware volume.
            base_address: Hex string (e.g. '0xFFF00000') or None.
            force_rebase: 'TRUE', 'FALSE', or None.
            peim1_xip: 'TRUE', 'FALSE', or None (omit Xip keyword).
            peim2_xip: 'TRUE', 'FALSE', or None.
            dxe_xip:   'TRUE', 'FALSE', or None.

        Returns:
            Absolute path to the generated FDF file.
        """
        def xip_clause(setting):
            return f'  Xip={setting}' if setting is not None else ''

        base_line = f'FvBaseAddress = {base_address}\n' if base_address is not None else ''
        force_line = f'FvForceRebase = {force_rebase}\n' if force_rebase is not None else ''

        # Use RuleOverride when PEIM2 needs a different Xip than PEIM1
        if peim2_xip != peim1_xip:
            peim2_inf_line = 'INF  RuleOverride=PEIM2RULE  TestXipRebasePkg/TestPeim2/TestPeim2.inf'
            peim2_rule = self.PEIM2_RULE_TEMPLATE.format(
                peim2_xip_clause=xip_clause(peim2_xip))
        else:
            peim2_inf_line = 'INF  TestXipRebasePkg/TestPeim2/TestPeim2.inf'
            peim2_rule = ''

        fdf_content = self.FDF_TEMPLATE.format(
            fv_name=fv_name, base_line=base_line, force_line=force_line,
            peim2_inf_line=peim2_inf_line,
            peim1_xip_clause=xip_clause(peim1_xip),
            peim2_rule=peim2_rule,
            dxe_xip_clause=xip_clause(dxe_xip),
        )

        fdf_path = Path(pkg_dir, 'TestXipRebase.fdf')
        fdf_path.write_text(fdf_content)
        return str(fdf_path)

    def _run_build(self, dsc_path: Path, fdf_path: str) -> tuple[int, str, str]:
        """Run the edk2 build command and return (returncode, stdout, stderr).

        When verbose mode is enabled (-v / --verbose), streams build output
        in real-time.

        Args:
            dsc_path: Path to the DSC platform description file.
            fdf_path: Path to the FDF flash description file.

        Returns:
            Tuple of (returncode, stdout, stderr) from the build process.
        """
        rel_dsc = os.path.relpath(dsc_path, self.WORKSPACE)
        rel_fdf = os.path.relpath(fdf_path, self.WORKSPACE)
        cmd = (
            f'build -p {rel_dsc} -f {rel_fdf}'
            f' -a X64 -b DEBUG -t {self.TOOLCHAIN} --quiet'
        )

        proc = subprocess.Popen(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            text=True, bufsize=1, cwd=self.WORKSPACE, shell=True,
        )
        stdout_lines, stderr_lines = [], []
        verbose = '-v' in sys.argv or '--verbose' in sys.argv

        def reader(pipe, sink, stream):
            for line in pipe:
                if stream:
                    stream.write(line)
                    stream.flush()
                sink.append(line)

        threads = [
            threading.Thread(target=reader,
                             args=(proc.stdout, stdout_lines,
                                   sys.stdout if verbose else None)),
            threading.Thread(target=reader,
                             args=(proc.stderr, stderr_lines,
                                   sys.stderr if verbose else None)),
        ]
        for t in threads:
            t.start()
        for t in threads:
            t.join(timeout=300)
        proc.stdout.close()
        proc.stderr.close()
        proc.wait(timeout=300)
        return proc.returncode, ''.join(stdout_lines), ''.join(stderr_lines)

    # --- Verification helpers ---

    def _fv_output_path(self, filename: str) -> Path:
        """Return the path to a file in the FV output directory.

        Args:
            filename: Name of the file (e.g. 'TESTFV1.Fv', 'TESTFV1.inf').

        Returns:
            Full path to the file under Build/TestXipRebase/DEBUG_<TOOLCHAIN>/FV/.
        """
        return Path(
            self.WORKSPACE, 'Build', 'TestXipRebase',
            f'DEBUG_{self.TOOLCHAIN}', 'FV', filename
        )

    def _read_fv_file(self, filename: str) -> str | None:
        """Read a generated FV output file as text, or None if missing.

        Args:
            filename: Name of the file in the FV output directory.

        Returns:
            File contents as a string, or None if the file does not exist.
        """
        path = self._fv_output_path(filename)
        return path.read_text() if path.is_file() else None

    def _check_module_rebased(self, map_content: str, module_name: str,
                              expect_rebased: bool) -> None:
        """Assert a module's rebase status in the FV map file.

        A rebased module has '(Fixed Flash Address, BaseAddress=0x...' in
        its map entry. A non-rebased module lacks this marker.

        Args:
            map_content: Text content of the FV .map file.
            module_name: Module base name to search for (e.g. 'TestPeim').
            expect_rebased: True if the module should have been rebased.
        """
        self.assertIsNotNone(map_content, "FV map file not found")
        found = bool(re.search(
            rf'{re.escape(module_name)}.*\(Fixed Flash Address',
            map_content, re.IGNORECASE
        ))
        verb = "to be" if expect_rebased else "NOT to be"
        self.assertEqual(
            found, expect_rebased,
            f"Expected {module_name} {verb} rebased.\n"
            f"Map excerpt: {map_content[:500]}"
        )

    def _get_pe_image_bases(self, fv_name: str) -> list[tuple[int, int]] | None:
        """Extract (fv_offset, image_base) for each PE/COFF image in the FV.

        Walks the FV binary using ctypes structures:
        EFI_FIRMWARE_VOLUME_HEADER -> EFI_FFS_FILE_HEADER ->
        EFI_COMMON_SECTION_HEADER -> EFI_IMAGE_DOS_HEADER ->
        EFI_IMAGE_OPTIONAL_HEADER32 / EFI_IMAGE_OPTIONAL_HEADER64.

        Args:
            fv_name: Firmware volume name (e.g. 'TESTFV1').

        Returns:
            Sorted list of (fv_offset, image_base) tuples, or None if the
            FV file does not exist.
        """
        fv_path = self._fv_output_path(f'{fv_name}.Fv')
        if not fv_path.is_file():
            return None

        fv_data = fv_path.read_bytes()
        fv_hdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer_copy(fv_data)
        ffs_offset = fv_hdr.HeaderLength
        results = []

        # Walk FFS files within the FV
        while ffs_offset + ctypes.sizeof(EFI_FFS_FILE_HEADER) <= len(fv_data):
            ffs_offset = (ffs_offset + 7) & ~7  # FFS 8-byte alignment
            if ffs_offset + ctypes.sizeof(EFI_FFS_FILE_HEADER) > len(fv_data):
                break

            ffs_hdr = EFI_FFS_FILE_HEADER.from_buffer_copy(fv_data, ffs_offset)
            file_size = ffs_hdr.FFS_FILE_SIZE
            if file_size in (0, 0xFFFFFF):
                break  # End of FFS files or pad

            file_end = ffs_offset + file_size
            sect_offset = ffs_offset + ffs_hdr.HeaderLength

            # Walk sections within this FFS file
            while sect_offset + ctypes.sizeof(EFI_COMMON_SECTION_HEADER) <= file_end:
                sect_offset = (sect_offset + 3) & ~3  # Section 4-byte alignment
                if sect_offset + ctypes.sizeof(EFI_COMMON_SECTION_HEADER) > file_end:
                    break

                sect_hdr = EFI_COMMON_SECTION_HEADER.from_buffer_copy(
                    fv_data, sect_offset)
                sect_size = sect_hdr.SECTION_SIZE
                if sect_size == 0:
                    break

                if sect_hdr.Type == EFI_SECTION_PE32:
                    pe_offset = sect_offset + sect_hdr.Common_Header_Size()
                    image_base = self._parse_pe_image_base(
                        fv_data, pe_offset)
                    if image_base is not None:
                        results.append((pe_offset, image_base))

                sect_offset += sect_size

            ffs_offset += file_size

        results.sort(key=lambda x: x[0])
        return results

    @staticmethod
    def _parse_pe_image_base(data: bytes, offset: int) -> int | None:
        """Parse ImageBase from a PE/COFF image at the given offset.

        Uses EFI_IMAGE_DOS_HEADER to locate the PE signature, then reads
        EFI_IMAGE_NT_HEADERS32 or EFI_IMAGE_NT_HEADERS64 to extract ImageBase.

        Args:
            data: Raw bytes of the FV binary.
            offset: Byte offset where the PE/COFF image starts.

        Returns:
            ImageBase value (int), or None if the image cannot be parsed.
        """
        if offset + ctypes.sizeof(EFI_IMAGE_DOS_HEADER) > len(data):
            return None
        dos_hdr = EFI_IMAGE_DOS_HEADER.from_buffer_copy(data, offset)
        if dos_hdr.e_magic != EFI_IMAGE_DOS_SIGNATURE:
            return None

        nt_offset = offset + dos_hdr.e_lfanew

        # Read as NT_HEADERS32 first (smaller); check magic to decide format
        if nt_offset + ctypes.sizeof(EFI_IMAGE_NT_HEADERS32) > len(data):
            return None
        nt32 = EFI_IMAGE_NT_HEADERS32.from_buffer_copy(data, nt_offset)
        if nt32.Signature != EFI_IMAGE_NT_SIGNATURE:
            return None

        if nt32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:
            # PE32+: re-read with the larger NT_HEADERS64 structure
            if nt_offset + ctypes.sizeof(EFI_IMAGE_NT_HEADERS64) > len(data):
                return None
            nt64 = EFI_IMAGE_NT_HEADERS64.from_buffer_copy(data, nt_offset)
            return nt64.OptionalHeader.ImageBase
        return nt32.OptionalHeader.ImageBase

    def _check_pe_image_base(self, fv_name: str, base_address: str | None,
                             file_index: int, expect_rebased: bool) -> None:
        """Assert that a PE/COFF image in the FV has the correct ImageBase.

        A rebased image has ImageBase = FvBaseAddress + fv_offset.
        A non-rebased image retains its link-time ImageBase of 0.

        Args:
            fv_name: Firmware volume name (e.g. 'TESTFV1').
            base_address: FvBaseAddress hex string or None.
            file_index: Zero-based index of the PE image in FV file order.
            expect_rebased: True if the image should have been rebased.
        """
        pe_images = self._get_pe_image_bases(fv_name)
        self.assertIsNotNone(pe_images, f"Could not read FV for {fv_name}")
        self.assertGreater(
            len(pe_images), file_index,
            f"FV {fv_name} has {len(pe_images)} PE images, need >= {file_index + 1}")

        fv_offset, image_base = pe_images[file_index]
        fv_base = int(base_address, 16) if isinstance(base_address, str) else (base_address or 0)
        expected = (fv_base + fv_offset) if expect_rebased else 0

        self.assertEqual(
            image_base, expected,
            f"File #{file_index} @ FV+0x{fv_offset:X}: "
            f"ImageBase=0x{image_base:X}, expected 0x{expected:X}"
            f"{'' if expect_rebased else ' (not rebased)'}"
        )

    def _build_and_verify(self, fv_name: str, base_address: str | None,
                          force_rebase: str | None, peim1_xip: str | None,
                          peim2_xip: str | None, dxe_xip: str | None,
                          expect_rebase: tuple[bool, bool, bool]) -> None:
        """Build an FV with the given configuration and verify all outputs.

        Args:
            fv_name: Firmware volume name.
            base_address: FvBaseAddress hex string or None.
            force_rebase: FvForceRebase setting ('TRUE', 'FALSE', or None).
            peim1_xip: Xip= keyword for TestPeim ('TRUE', 'FALSE', or None).
            peim2_xip: Xip= keyword for TestPeim2 ('TRUE', 'FALSE', or None).
            dxe_xip: Xip= keyword for TestDxeDriver ('TRUE', 'FALSE', or None).
            expect_rebase: Tuple of 3 bools (peim1, peim2, dxe) indicating
                whether each module should be rebased.
        """
        pkg_dir = self._create_test_package()
        dsc_path = Path(pkg_dir, 'TestXipRebase.dsc')
        dsc_path.write_text(self.DSC_CONTENT)
        fdf_path = self._generate_fdf(
            pkg_dir, fv_name, base_address, force_rebase,
            peim1_xip, peim2_xip, dxe_xip)

        rc, stdout, stderr = self._run_build(dsc_path, fdf_path)
        self.assertEqual(rc, 0,
                         f"Build failed (rc={rc}).\nstdout:\n{stdout}\nstderr:\n{stderr}")

        # Verify ,XIP suffix count in FV INF file
        # (,XIP suffix is present when the FDF rule has Xip=TRUE)
        inf_content = self._read_fv_file(f'{fv_name}.inf')
        self.assertIsNotNone(inf_content, f"FV INF file not found for {fv_name}")
        efi_lines = [l for l in inf_content.splitlines() if 'EFI_FILE_NAME' in l]
        xip_count = sum(1 for l in efi_lines if l.rstrip().endswith(',XIP'))
        expected_xip = sum(x == 'TRUE' for x in (peim1_xip, peim2_xip, dxe_xip))
        self.assertEqual(xip_count, expected_xip,
                         f"Expected {expected_xip} ,XIP lines, got {xip_count}.\n"
                         f"INF content:\n{inf_content}")

        # Verify rebase status in map file and PE/COFF ImageBase in FV binary
        map_content = self._read_fv_file(f'{fv_name}.Fv.map')
        self.assertIsNotNone(map_content, f"FV map file not found for {fv_name}")

        for idx, (name, rebased) in enumerate(
                zip(self._MODULE_NAMES, expect_rebase)):
            self._check_module_rebased(map_content, name, rebased)
            self._check_pe_image_base(fv_name, base_address, idx, rebased)

    # ===================================================================
    # Test case table (matches behavior matrix from test plan header)
    # ===================================================================

    # (fv_name, base_address, force_rebase,
    #  peim1_xip, peim2_xip, dxe_xip,
    #  (expect_peim1_rebase, expect_peim2_rebase, expect_dxe_rebase),
    #  description)
    TEST_CASES = [
        # TC1: ForceRebase not specified, BaseAddress defaults to 0.
        # Early return path: (BaseAddress==0 && ForceRebase==-1).
        # No files are rebased. PEIMs have ,XIP suffix (Xip=TRUE in rule).
        ('TESTFV1', None,         None,    'TRUE', 'TRUE', None,
         (False, False, False), 'TC1: ForceRebase=unset, Base=0 -> no rebase'),
        # TC2: ForceRebase not specified, BaseAddress!=0.
        # Legacy path: (BaseAddress!=0 && ForceRebase==-1).
        # ALL files are rebased regardless of XIP status.
        ('TESTFV2', '0x00800000', None,    'TRUE', 'TRUE', None,
         (True,  True,  True),  'TC2: ForceRebase=unset, Base!=0 -> rebase all (legacy)'),
        # TC3: ForceRebase=FALSE with BaseAddress!=0.
        # Early return path: (ForceRebase==0).
        # No files are rebased even though all have Xip=TRUE.
        ('TESTFV3', '0x00800000', 'FALSE', 'TRUE', 'TRUE', 'TRUE',
         (False, False, False), 'TC3: ForceRebase=FALSE -> no rebase'),
        # TC4: ForceRebase=TRUE, all three files have Xip=TRUE.
        # All files match (ForceRebase==1 && XipFile[i]==TRUE) and are rebased.
        ('TESTFV4', '0x00800000', 'TRUE',  'TRUE', 'TRUE', 'TRUE',
         (True,  True,  True),  'TC4: ForceRebase=TRUE, all Xip=TRUE -> rebase all'),
        # TC5: ForceRebase=TRUE, PEIMs have Xip=TRUE, DXE has no Xip.
        # Selective rebase: PEIMs rebased, DXE skipped.
        ('TESTFV5', '0x00800000', 'TRUE',  'TRUE', 'TRUE', None,
         (True,  True,  False), 'TC5: ForceRebase=TRUE, selective Xip -> rebase Xip only'),
        # TC6: ForceRebase=TRUE, no files have Xip keyword.
        # XipFileCount==0, so legacy behavior is preserved: rebase all files.
        ('TESTFV6', '0x00800000', 'TRUE',  None,   None,   None,
         (True,  True,  True),  'TC6: ForceRebase=TRUE, no Xip -> rebase all (legacy compat)'),
        # TC7: ForceRebase=TRUE, PEIM1 has Xip=TRUE, PEIM2 has Xip=FALSE.
        # Mixed XIP within same module type via RuleOverride.
        # Only PEIM1 is rebased; PEIM2 and DXE are skipped.
        ('TESTFV7', '0x00800000', 'TRUE',  'TRUE', 'FALSE', None,
         (True,  False, False), 'TC7: ForceRebase=TRUE, mixed Xip -> rebase Xip=TRUE only'),
        # TC8: ForceRebase=TRUE, BaseAddress=0, PEIMs have Xip=TRUE.
        # ForceRebase=TRUE overrides the (BaseAddress==0) early return.
        # PEIMs are rebased to offset 0+fv_offset; DXE is skipped (no Xip).
        ('TESTFV8', '0x0',        'TRUE',  'TRUE', 'TRUE', None,
         (True,  True,  False), 'TC8: ForceRebase=TRUE, Base=0, Xip -> rebase (force overrides)'),
    ]

    def test_xip_rebase_behavior(self) -> None:
        """Parameterized test covering all ForceRebase/BaseAddress/Xip combos."""
        for (fv_name, base_address, force_rebase,
             peim1_xip, peim2_xip, dxe_xip,
             expect_rebase, description) in self.TEST_CASES:
            with self.subTest(description):
                self._build_and_verify(
                    fv_name, base_address, force_rebase,
                    peim1_xip, peim2_xip, dxe_xip, expect_rebase)


class TestFdfParserPe32KeywordOrder(unittest.TestCase):
    """Test that the FDF parser accepts PE32 section keywords in any order.

    The keywords Align, Xip, and RELOCS_STRIPPED/RELOCS_RETAINED should be
    accepted in any permutation within a PE32 section statement in a [Rule].
    """

    @classmethod
    def setUpClass(cls):
        """Set up environment for FdfParser imports."""
        import tempfile
        cls._tmpdir = tempfile.mkdtemp(prefix='fdf_parser_test_')
        # Set WORKSPACE so the parser doesn't crash
        os.environ.setdefault('WORKSPACE', cls._tmpdir)
        from GenFds.GenFdsGlobalVariable import GenFdsGlobalVariable
        GenFdsGlobalVariable.WorkSpaceDir = cls._tmpdir
        from Common import GlobalData
        GlobalData.gFdfParser = None
        GlobalData.gWorkspace = cls._tmpdir

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(cls._tmpdir, ignore_errors=True)

    def _parse_rule(self, pe32_section_line):
        """Parse a [Rule] with the given PE32 section line and return the EfiSection."""
        import tempfile
        from GenFds.FdfParser import FdfParser
        from Common import GlobalData

        fdf_content = (
            "[Rule.Common.PEIM]\n"
            "  FILE PEIM = $(NAMED_GUID) {\n"
            "    " + pe32_section_line + "\n"
            "  }\n"
        )
        fdf_path = os.path.join(self._tmpdir, 'test_order.fdf')
        with open(fdf_path, 'w') as f:
            f.write(fdf_content)

        parser = FdfParser(fdf_path)
        # Manually set up parser state for rule parsing
        parser.CurrentLineNumber = 3
        parser.CurrentOffsetWithinLine = 4
        # Re-read the profile to refresh file lines
        parser.Profile.FileLinesList = fdf_content.splitlines(True)

        # Create a RuleComplexFile as the container object
        from GenFds.RuleComplexFile import RuleComplexFile
        obj = RuleComplexFile()
        obj.FvFileType = 'PEIM'
        obj.KeepReloc = None
        obj.SectionList = []

        result = parser._GetEfiSection(obj)
        self.assertTrue(result, f"Parser failed to parse: {pe32_section_line}")
        self.assertEqual(len(obj.SectionList), 1)
        return obj.SectionList[0]

    # (pe32_line, expected_alignment, expected_xip, expected_keep_reloc, description)
    TEST_CASES = [
        # Align before Xip (original supported order)
        ('PE32 PE32 Align=8 Xip=TRUE',
         '8', 'TRUE', None,
         'Align then Xip'),
        # Xip before Align (previously caused stack trace)
        ('PE32 PE32 Xip=TRUE Align=8',
         '8', 'TRUE', None,
         'Xip then Align'),
        # Align before RELOCS_STRIPPED
        ('PE32 PE32 Align=16 RELOCS_STRIPPED',
         '16', None, False,
         'Align then RELOCS_STRIPPED'),
        # RELOCS_STRIPPED before Align
        ('PE32 PE32 RELOCS_STRIPPED Align=16',
         '16', None, False,
         'RELOCS_STRIPPED then Align'),
        # Xip before RELOCS_STRIPPED
        ('PE32 PE32 Xip=TRUE RELOCS_STRIPPED',
         None, 'TRUE', False,
         'Xip then RELOCS_STRIPPED'),
        # RELOCS_STRIPPED before Xip
        ('PE32 PE32 RELOCS_STRIPPED Xip=TRUE',
         None, 'TRUE', False,
         'RELOCS_STRIPPED then Xip'),
        # All three: Align, Xip, RELOCS_STRIPPED
        ('PE32 PE32 Align=16 Xip=TRUE RELOCS_STRIPPED',
         '16', 'TRUE', False,
         'Align then Xip then RELOCS_STRIPPED'),
        # All three: Xip, Align, RELOCS_STRIPPED
        ('PE32 PE32 Xip=TRUE Align=16 RELOCS_STRIPPED',
         '16', 'TRUE', False,
         'Xip then Align then RELOCS_STRIPPED'),
        # All three: RELOCS_STRIPPED, Align, Xip
        ('PE32 PE32 RELOCS_STRIPPED Align=16 Xip=TRUE',
         '16', 'TRUE', False,
         'RELOCS_STRIPPED then Align then Xip'),
        # All three: RELOCS_STRIPPED, Xip, Align
        ('PE32 PE32 RELOCS_STRIPPED Xip=TRUE Align=16',
         '16', 'TRUE', False,
         'RELOCS_STRIPPED then Xip then Align'),
        # All three: Xip, RELOCS_STRIPPED, Align
        ('PE32 PE32 Xip=TRUE RELOCS_STRIPPED Align=16',
         '16', 'TRUE', False,
         'Xip then RELOCS_STRIPPED then Align'),
        # All three: Align, RELOCS_STRIPPED, Xip
        ('PE32 PE32 Align=16 RELOCS_STRIPPED Xip=TRUE',
         '16', 'TRUE', False,
         'Align then RELOCS_STRIPPED then Xip'),
        # Xip=FALSE
        ('PE32 PE32 Xip=FALSE Align=8',
         '8', 'FALSE', None,
         'Xip=FALSE then Align'),
        # RELOCS_RETAINED variant
        ('PE32 PE32 Xip=TRUE RELOCS_RETAINED Align=8',
         '8', 'TRUE', True,
         'Xip then RELOCS_RETAINED then Align'),
        # Only Xip (no Align, no Reloc)
        ('PE32 PE32 Xip=TRUE',
         None, 'TRUE', None,
         'Xip only'),
        # Only Align (no Xip, no Reloc)
        ('PE32 PE32 Align=32',
         '32', None, None,
         'Align only'),
        # Only RELOCS_STRIPPED (no Align, no Xip)
        ('PE32 PE32 RELOCS_STRIPPED',
         None, None, False,
         'RELOCS_STRIPPED only'),
    ]

    def test_pe32_keyword_order(self) -> None:
        """Parameterized test verifying PE32 section keywords in any order."""
        for (pe32_line, exp_align, exp_xip, exp_keep_reloc, desc) in self.TEST_CASES:
            with self.subTest(desc):
                section = self._parse_rule(pe32_line)
                self.assertEqual(section.SectionType, 'PE32')
                if exp_align is not None:
                    self.assertEqual(section.Alignment, exp_align)
                else:
                    self.assertIn(section.Alignment, (None, ''))
                if exp_xip is not None:
                    self.assertEqual(section.Xip, exp_xip)
                else:
                    self.assertFalse(
                        hasattr(section, 'Xip') and section.Xip,
                        f"Expected no Xip but got {getattr(section, 'Xip', None)}"
                    )
                if exp_keep_reloc is not None:
                    self.assertEqual(section.KeepReloc, exp_keep_reloc)
                else:
                    self.assertIsNone(
                        getattr(section, 'KeepReloc', None),
                        f"Expected no KeepReloc but got {section.KeepReloc}"
                    )


class TestFdfParserFvKeywordOrder(unittest.TestCase):
    """Test that the FDF parser accepts [FV] keywords in any order.

    FvForceRebase, FvBaseAddress, FvAlignment, and FV attributes like
    ERASE_POLARITY, MEMORY_MAPPED should be accepted in any order.
    Previously, FvForceRebase between two FV attributes (e.g. between
    ERASE_POLARITY and MEMORY_MAPPED) caused a Python stack trace.
    """

    @classmethod
    def setUpClass(cls):
        """Set up environment for FdfParser imports."""
        import tempfile
        cls._tmpdir = tempfile.mkdtemp(prefix='fdf_fv_parser_test_')
        os.environ.setdefault('WORKSPACE', cls._tmpdir)
        from GenFds.GenFdsGlobalVariable import GenFdsGlobalVariable
        GenFdsGlobalVariable.WorkSpaceDir = cls._tmpdir
        from Common import GlobalData
        GlobalData.gFdfParser = None
        GlobalData.gWorkspace = cls._tmpdir

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(cls._tmpdir, ignore_errors=True)

    def _parse_fv_section(self, fv_body):
        """Parse an [FV] section and return the FV object."""
        from GenFds.FdfParser import FdfParser
        from Common import GlobalData

        fdf_content = (
            "[FV.TESTFV]\n"
            + fv_body + "\n"
        )
        fdf_path = os.path.join(self._tmpdir, 'test_fv_order.fdf')
        with open(fdf_path, 'w') as f:
            f.write(fdf_content)

        parser = FdfParser(fdf_path)
        parser.Profile.FileLinesList = fdf_content.splitlines(True)
        # Position parser at start of FV body (line 2, offset 0)
        parser.CurrentLineNumber = 2
        parser.CurrentOffsetWithinLine = 0

        # Create FV object and parse the attributes/keywords
        from GenFds.Fv import FV
        fv_obj = FV(Name='TESTFV')

        # Use the same while loop the real parser uses
        while True:
            parser._GetSetStatements(fv_obj)
            if not (parser._GetBlockStatement(fv_obj) or
                    parser._GetFvBaseAddress(fv_obj) or
                    parser._GetFvForceRebase(fv_obj) or
                    parser._GetFvAlignment(fv_obj) or
                    parser._GetFvAttributes(fv_obj) or
                    parser._GetFvNameGuid(fv_obj) or
                    parser._GetFvExtEntryStatement(fv_obj) or
                    parser._GetFvNameString(fv_obj)):
                break

        return fv_obj

    # (fv_body, expected_attrs, expected_force_rebase, description)
    TEST_CASES = [
        # FvForceRebase after all attributes (original working order)
        ("ERASE_POLARITY = 1\nMEMORY_MAPPED = TRUE\nFvForceRebase = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, True,
         'FvForceRebase after all attributes'),
        # FvForceRebase before all attributes
        ("FvForceRebase = TRUE\nERASE_POLARITY = 1\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, True,
         'FvForceRebase before all attributes'),
        # FvForceRebase between ERASE_POLARITY and MEMORY_MAPPED
        ("ERASE_POLARITY = 1\nFvForceRebase = TRUE\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, True,
         'FvForceRebase between attributes (previously crashed)'),
        # FvForceRebase=FALSE between attributes
        ("ERASE_POLARITY = 1\nFvForceRebase = FALSE\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, False,
         'FvForceRebase=FALSE between attributes'),
        # Multiple attributes, FvForceRebase in the middle
        ("ERASE_POLARITY = 1\nSTICKY_WRITE = TRUE\nFvForceRebase = TRUE\n"
         "MEMORY_MAPPED = TRUE\nLOCK_CAP = TRUE\n",
         {'ERASE_POLARITY': '1', 'STICKY_WRITE': 'TRUE',
          'MEMORY_MAPPED': 'TRUE', 'LOCK_CAP': 'TRUE'}, True,
         'FvForceRebase in middle of many attributes'),
        # FvBaseAddress between attributes
        ("ERASE_POLARITY = 1\nFvBaseAddress = 0x00800000\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, None,
         'FvBaseAddress between attributes'),
        # FvAlignment between attributes
        ("ERASE_POLARITY = 1\nFvAlignment = 16\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'MEMORY_MAPPED': 'TRUE'}, None,
         'FvAlignment between attributes'),
        # All interleaved: attr, FvForceRebase, attr, FvBaseAddress, attr
        ("ERASE_POLARITY = 1\nFvForceRebase = TRUE\nSTICKY_WRITE = TRUE\n"
         "FvBaseAddress = 0x00800000\nMEMORY_MAPPED = TRUE\n",
         {'ERASE_POLARITY': '1', 'STICKY_WRITE': 'TRUE', 'MEMORY_MAPPED': 'TRUE'}, True,
         'Multiple keywords interleaved with attributes'),
    ]

    def test_fv_keyword_order(self) -> None:
        """Parameterized test verifying FV keywords accepted in any order."""
        for (fv_body, exp_attrs, exp_force_rebase, desc) in self.TEST_CASES:
            with self.subTest(desc):
                fv_obj = self._parse_fv_section(fv_body)
                for attr_name, attr_val in exp_attrs.items():
                    self.assertIn(attr_name, fv_obj.FvAttributeDict,
                                  f"Missing attribute {attr_name}")
                    self.assertEqual(fv_obj.FvAttributeDict[attr_name], attr_val)
                if exp_force_rebase is not None:
                    self.assertEqual(fv_obj.FvForceRebase, exp_force_rebase)


if __name__ == '__main__':
    unittest.main()
