Wanting Yang

64 papers B 3Journal 53Unranked 8
YearRankTypeTitle / Venue / Authors
2026 J jnl
Swarm Evol. Comput.
Tianzi Zheng, Jianchang Liu, Yaochu Jin, Yuanchao Liu, Wanting Yang
2026 J jnl
IEEE Trans. Cogn. Commun. Netw.
Wanting Yang, Zehui Xiong, Qianqian Yang, Ping Zhang, Mérouane Debbah, Rahim Tafazolli
2026 J jnl
IEEE Wirel. Commun.
Binquan Guo, Wanting Yang, Zehui Xiong, Zhou Zhang, Baosheng Li, Zhu Han, Rahim Tafazolli, Tony Q. S. Quek
2026 J jnl
IEEE Trans. Netw. Sci. Eng.
Yiru Wang, Wanting Yang, Fangli Mou, Zehui Xiong, Zide Fan, Shiwen Mao, Tony Q. S. Quek
2026 J jnl
Oper. Res. Lett.
Wanting Yang, Lixiang Li, Wei Yang, Lianmin Zhang
2025 B conf
TrustCom
Danhuai Zhao, Chen Tian, Zhenyu Ju, Yi Rong, Xiaoming He, Wanting Yang
2025 J jnl
IEEE Trans. Instrum. Meas.
Chuang Yang, Jianchang Liu, Zhe Gao, Dandan Song, Wanting Yang, Honghai Wang
2025 J jnl
CoRR
Siyuan Sun, Yongping Zhang, Hongcheng Zeng, Yamin Wang, Wei Yang, Wanting Yang, Jie Chen
2025 J jnl
Swarm Evol. Comput.
Wanting Yang, Jianchang Liu, Yuanchao Liu, Tianzi Zheng
2025 J jnl
Biomed. Signal Process. Control.
Wanting Yang, Jie Yuan, Juanjuan Zhao, Wei Wu, Yan Qiang
2025 J jnl
IEEE Trans. Wirel. Commun.
Wanting Yang, Zehui Xiong, Yanli Yuan, Wenchao Jiang, Tony Q. S. Quek, Mérouane Debbah
2025 J jnl
CoRR
Wanting Yang, Zehui Xiong, Qianqian Yang, Ping Zhang, Mérouane Debbah, Rahim Tafazolli
2025 J jnl
CoRR
Nan Li, Wanting Yang, Marie Siew, Zehui Xiong, Binbin Chen, Shiwen Mao, Kwok-Yan Lam
2025 J jnl
IEEE Trans. Mob. Comput.
Wanting Yang, Zehui Xiong, Song Guo, Shiwen Mao, Dong In Kim, Mérouane Debbah
2025 J jnl
CoRR
Binquan Guo, Wanting Yang, Zehui Xiong, Zhou Zhang, Baosheng Li, Zhu Han, Rahim Tafazolli, Tony Q. S. Quek
2025 J jnl
IEEE Veh. Technol. Mag.
Jiayi Lu, Wanting Yang, Zehui Xiong, Chengwen Xing, Rahim Tafazolli, Tony Q. S. Quek, Mérouane Debbah
2025 B conf
TrustCom
Kesong Wu, Maowei Li, Peng Yang, Wanting Yang, Jiangtian Nie, Xianbin Cao
2025 J jnl
Ecol. Informatics
Wanting Yang, Daniel Ortiz-Gonzalo, Xiaoye Tong, Dimitri Gominski, Rasmus Fensholt
2025 J jnl
CoRR
Jiayi Lu, Wanting Yang, Zehui Xiong, Rahim Tafazolli, Tony Q. S. Quek, Mérouane Debbah, Dong In Kim
2025 J jnl
IEEE Wirel. Commun.
Wanting Yang, Zehui Xiong, Shiwen Mao, Tony Q. S. Quek, Ping Zhang, Mérouane Debbah, Rahim Tafazolli
2024 J jnl
ACM Trans. Multim. Comput. Commun. Appl.
Qinnan Zhang, Zehui Xiong, Jianming Zhu, Sheng Gao, Wanting Yang
2024 J jnl
Inf. Sci.
Wei Zhang, Jianchang Liu, Wanting Yang, Shubin Tan
2024 J jnl
CoRR
Wanting Yang, Zehui Xiong, Yanli Yuan, Wenchao Jiang, Tony Q. S. Quek, Mérouane Debbah
2024 J jnl
Sensors
Fares Bougourzi, Cosimo Distante, Fadi Dornaika, Abdelmalik Taleb-Ahmed, Abdenour Hadid, Suman Chaudhary, Wanting Yang, Yan Qiang, Talha Anwar, Mihaela Elena Breaban, Chih-Chung Hsu, Shen-Chieh Tai, Shao-Ning Chen, Davide Tricarico, Hafiza Ayesha Hoor Chaudhry, Attilio Fiandrotti, Marco Grangetto, Maria Ausilia Napoli Spatafora, Alessandro Ortis, Sebastiano Battiato
2024 J jnl
Briefings Bioinform.
Fang Yang, Chaoqun Li, Wanting Yang, Yumei He, Liping Wu, Kui Jiang, Chao Sun
2024 J jnl
CoRR
Wanting Yang, Zehui Xiong, Song Guo, Shiwen Mao, Dong In Kim, Mérouane Debbah
2024 J jnl
IEEE Trans. Veh. Technol.
Hangyu Yan, Xuefen Chi, Wanting Yang, Zhu Han
2024 conf
VTC Spring
Xiangda Lin, Helin Yang, Kailong Lin, Liang Xiao, Zhaoyuan Shi, Wanting Yang, Zehui Xiong
2024 J jnl
Appl. Intell.
Wanting Yang, Jianchang Liu, Shubin Tan, Wei Zhang, Yuanchao Liu
2024 J jnl
CoRR
Jiayi Lu, Wanting Yang, Zehui Xiong, Chengwen Xing, Rahim Tafazolli, Tony Q. S. Quek, Mérouane Debbah
2024 J jnl
IEEE Netw.
Yiru Wang, Wanting Yang, Zehui Xiong, Yuping Zhao, Tony Q. S. Quek, Zhu Han
2024 conf
VTC Spring
Shihao Chen, Helin Yang, Liang Xiao, Changyuan Xu, Xianzhong Xie, Wanting Yang, Zehui Xiong
2024 J jnl
IEEE Internet Things J.
Hangyu Yan, Xuefen Chi, Wanting Yang, Zehui Xiong, Zhu Han
2024 J jnl
IEEE Wirel. Commun. Lett.
Binquan Guo, Zheng Chang, Zhu Han, Wanting Yang, Zehui Xiong
2024 J jnl
CoRR
Wanting Yang, Zehui Xiong, Shiwen Mao, Tony Q. S. Quek, Ping Zhang, Mérouane Debbah, Rahim Tafazolli
2024 J jnl
IEEE Trans. Veh. Technol.
Yiru Wang, Wanting Yang, Pengxin Guan, Yuping Zhao, Zehui Xiong
2024 B conf
WCNC
Wanting Yang, Zehui Xiong, Hongyang Du, Yanli Yuan, Tony Q. S. Quek
2024 J jnl
CoRR
Wanting Yang, Zehui Xiong, Tony Q. S. Quek, Xuemin Shen
2024 J jnl
IEEE Netw.
Wanting Yang, Zehui Xiong, Tony Q. S. Quek, Xuemin Shen
2024 conf
VTC Fall
Yiru Wang, Wanting Yang, Zehui Xiong, Yuping Zhao
2023 J jnl
Soft Comput.
Wanting Yang, Jianchang Liu, Wei Zhang, Xinnan Zhang
2023 J jnl
Comput. Biol. Chem.
Wanting Yang, Yan Qiang, Wei Wu, Jialong Xin
2023 conf
VTC2023-Spring
Linlin Zhao, Shaodan Ma, Guanghua Yang, Xuefen Chi, Wanting Yang
2023 conf
MetaCom
Qinnan Zhang, Zehui Xiong, Jianming Zhu, Sheng Gao, Wanting Yang, Dusit Niyato
2023 J jnl
Comput. Biol. Medicine
Wanting Yang, Wei Wu, Long Wang, Shuming Zhang, Juanjuan Zhao, Yan Qiang
2023 J jnl
CoRR
Wanting Yang, Zehui Xiong, Yanli Yuan, Tony Q. S. Quek
2023 J jnl
IEEE Commun. Surv. Tutorials
Wanting Yang, Hongyang Du, Zi Qin Liew, Wei Yang Bryan Lim, Zehui Xiong, Dusit Niyato, Xuefen Chi, Xuemin Shen, Chunyan Miao
2023 J jnl
IEEE Trans. Commun.
Wanting Yang, Xuefen Chi, Linlin Zhao, Zehui Xiong, Wenchao Jiang
2023 J jnl
CoRR
Wanting Yang, Xuefen Chi, Linlin Zhao, Zehui Xiong, Wenchao Jiang
2022 J jnl
Int. J. Comput. Assist. Radiol. Surg.
Jiahao Han, Ning Xiao, Wanting Yang, Shichao Luo, Jun Zhao, Yan Qiang, Suman Chaudhary, Juanjuan Zhao
2022 J jnl
CoRR
Wanting Yang, Zi Qin Liew, Wei Yang Bryan Lim, Zehui Xiong, Dusit Niyato, Xuefen Chi, Xianbin Cao, Khaled B. Letaief
2022 J jnl
IEEE Wirel. Commun.
Wanting Yang, Zi Qin Liew, Wei Yang Bryan Lim, Zehui Xiong, Dusit Niyato, Xuefen Chi, Xianbin Cao, Khaled B. Letaief
2022 J jnl
CoRR
Wanting Yang, Hongyang Du, Zi Qin Liew, Wei Yang Bryan Lim, Zehui Xiong, Dusit Niyato, Xuefen Chi, Xuemin Sherman Shen, Chunyan Miao
2022 J jnl
Comput. Biol. Medicine
Hexi Wang, Ning Xiao, Jina Zhang, Wanting Yang, Yulan Ma, Yao Suo, Juanjuan Zhao, Yan Qiang, Jianhong Lian, Qianqian Yang
2022 conf
ICIAP Workshops
Suman Chaudhary, Wanting Yang, Yan Qiang
2021 J jnl
J. Intell. Fuzzy Syst.
Yangxu Wu, Wanting Yang, Jinxiao Pan, Ping Chen
2021 conf
EITCE
Wanting Yang, Dongqing Hu, Xintian Zhou, Xinyu Li, Xingyu Fang, Kai Zhao
2021 J jnl
IEEE Trans. Veh. Technol.
Wanting Yang, Xuefen Chi, Linlin Zhao, Ruizhe Qi
2021 J jnl
IEEE Wirel. Commun. Lett.
Wanting Yang, Xuefen Chi, Linlin Zhao, Zehui Xiong
2021 J jnl
Remote. Sens.
Wanting Yang, Xianfeng Zhang, Peng Luo
2020 J jnl
IEEE Access
Ruizhe Qi, Xuefen Chi, Linlin Zhao, Wanting Yang
2020 J jnl
Comput. Electr. Eng.
Chao Ding, Hailang He, Weiwei Wang, Wanting Yang, Yuanyuan Zheng
2020 conf
ICC
Wanting Yang, Xuefen Chi, Linlin Zhao
2020 J jnl
Multim. Tools Appl.
Chao Ding, Weiwei Wang, Hailang He, Wanting Yang
tests/integration/test_pe_extractors.py
← Index tests/integration/test_pe_extractors.py python
"""
Integration tests for PE-specific extractors.
"""
import pytest
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.integration, pytest.mark.pe]


# ============================================================================
# PEFeaturesExtractor Tests
# ============================================================================

class TestPEFeaturesExtractor:
    """Tests for PEFeaturesExtractor class."""

    def test_extract_valid_pe(self, pe_binary_path, mock_logger):
        """Test extracting features from valid PE file."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.models.dataclasses import PE

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, PE)

    def test_extract_pe_type(self, pe_binary_path, mock_logger):
        """Test PE type detection (DLL, EXE, DRIVER)."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result.type in ["DLL", "EXE", "DRIVER"]

    def test_extract_architecture(self, pe_binary_path, mock_logger):
        """Test architecture detection."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Architecture should be detected
            assert result.architecture is not None

    def test_extract_entry_point(self, pe_binary_path, mock_logger):
        """Test entry point extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Entry point should be a hex string
            assert result.entry_point.startswith("0x")

    def test_extract_compilation_time(self, pe_binary_path, mock_logger):
        """Test compilation time extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Compilation time should be an integer timestamp
            assert isinstance(result.compilation_time, int)
            assert result.compilation_time_utc is not None

    def test_extract_dotnet_detection(self, pe_binary_path, mock_logger):
        """Test .NET detection."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Should be True for the test .NET binary
            assert isinstance(result.is_dotnet, bool)
            assert result.is_dotnet is True  # Test file is .NET

    def test_extract_headers(self, pe_binary_path, mock_logger):
        """Test header extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result.dos_header is not None
            assert result.nt_header is not None
            assert result.file_header is not None
            assert result.optional_header is not None

    def test_extract_counts(self, pe_binary_path, mock_logger):
        """Test section/import/export counts."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert isinstance(result.number_of_sections, int)
            assert isinstance(result.number_of_imports, int)
            assert isinstance(result.number_of_exports, int)
            assert isinstance(result.number_of_resources, int)

    def test_extract_rich_header(self, pe_binary_path, mock_logger):
        """Test Rich header extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Rich header may or may not be present
            # If present, should be JSON string
            if result.rich_header_dump is not None:
                assert isinstance(result.rich_header_dump, str)

    def test_extract_version_info(self, pe_binary_path, mock_logger):
        """Test version info extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Version info may or may not be present
            if result.version_info is not None:
                assert isinstance(result.version_info, list)


# ============================================================================
# PEImportExtractor Tests
# ============================================================================

class TestPEImportExtractor:
    """Tests for PEImportExtractor class."""

    def test_extract_imports(self, pe_binary_path, mock_logger):
        """Test import extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor
        from redb.models.dataclasses import PEImport

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None:
                assert isinstance(result, PEImport)
                assert isinstance(result.pe_imports_total, int)

    def test_extract_import_libraries(self, pe_binary_path, mock_logger):
        """Test import library extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and result.pe_import_libraryName is not None:
                assert isinstance(result.pe_import_libraryName, list)

    def test_extract_import_functions(self, pe_binary_path, mock_logger):
        """Test import function extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and result.pe_import_functions is not None:
                assert isinstance(result.pe_import_functions, list)

    def test_prepare_export_clickhouse(self, pe_binary_path, mock_logger):
        """Test ClickHouse export preparation."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.prepare_export_data("ClickHouseExporter")

            if result is not None:
                data, column_names, column_type_names = result
                assert 'library_name' in column_names
                assert 'function_name' in column_names


# ============================================================================
# PESectionExtractor Tests
# ============================================================================

class TestPESectionExtractor:
    """Tests for PESectionExtractor class."""

    def test_extract_sections(self, pe_binary_path, mock_logger):
        """Test section extraction."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor
        from redb.models.dataclasses import PESection

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, list)
            assert len(result) > 0
            assert isinstance(result[0], PESection)

    def test_section_properties(self, pe_binary_path, mock_logger):
        """Test section property extraction."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and len(result) > 0:
                section = result[0]
                assert section.section_name is not None
                assert section.section_entropy >= 0
                assert section.section_sha256 is not None
                assert section.section_md5 is not None
                assert section.section_size >= 0

    def test_section_entropy_range(self, pe_binary_path, mock_logger):
        """Test that section entropy is in valid range."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None:
                for section in result:
                    assert 0 <= section.section_entropy <= 8

    def test_prepare_export_clickhouse(self, pe_binary_path, mock_logger):
        """Test ClickHouse export preparation."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.prepare_export_data("ClickHouseExporter")

            if result is not None:
                data, column_names, column_type_names = result
                assert 'section_name' in column_names
                assert 'section_entropy' in column_names
                assert 'section_sha256' in column_names


# ============================================================================
# PEResourceExtractor Tests
# ============================================================================

class TestPEResourceExtractor:
    """Tests for PEResourceExtractor class."""

    def test_extract_resources(self, pe_binary_path, mock_logger):
        """Test resource extraction."""
        from redb.extractors.pe_extractors.pe_resources import PEResourceExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEResourceExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if no resources
            if result is not None:
                assert isinstance(result, list)

    def test_resource_properties(self, pe_binary_path, mock_logger):
        """Test resource property extraction."""
        from redb.extractors.pe_extractors.pe_resources import PEResourceExtractor
        from redb.models.dataclasses import PEResource

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEResourceExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and len(result) > 0:
                resource = result[0]
                assert isinstance(resource, PEResource)
                assert resource.resource_type is not None


# ============================================================================
# PEOverlayExtractor Tests
# ============================================================================

class TestPEOverlayExtractor:
    """Tests for PEOverlayExtractor class."""

    def test_extract_overlay(self, pe_binary_path, mock_logger):
        """Test overlay extraction."""
        from redb.extractors.pe_extractors.pe_overlay import PEOverlayExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEOverlayExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if no overlay
            # If present, should have overlay properties
            if result is not None:
                assert hasattr(result, 'overlay_size')

    def test_has_overlay_check(self, pe_binary_path, mock_logger):
        """Test overlay detection."""
        from redb.extractors.pe_extractors.pe_overlay import PEOverlayExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEOverlayExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            has_overlay = extractor._has_overlay()
            assert isinstance(has_overlay, bool)


# ============================================================================
# PESignatureExtractor Tests
# ============================================================================

class TestPESignatureExtractor:
    """Tests for PESignatureExtractor class."""

    def test_extract_signature(self, pe_binary_path, mock_logger):
        """Test signature extraction."""
        from redb.extractors.pe_extractors.pe_signature import PESignatureExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESignatureExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if not signed
            # Result type depends on implementation

    def test_is_signed_check(self, pe_binary_path, mock_logger):
        """Test signature detection."""
        from redb.extractors.pe_extractors.pe_signature import PESignatureExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESignatureExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            is_signed = extractor._is_signed()
            assert isinstance(is_signed, bool)


# ============================================================================
# PEDotNetExtractor Tests
# ============================================================================

class TestPEDotNetExtractor:
    """Tests for PEDotNetExtractor class."""

    def test_extract_dotnet(self, pe_binary_path, mock_logger):
        """Test .NET metadata extraction."""
        from redb.extractors.pe_extractors.pe_dotnet import PEDotNetExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEDotNetExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # The test file is a .NET binary
            if extractor._check_dotnet():
                assert result is not None

    def test_check_dotnet(self, pe_binary_path, mock_logger):
        """Test .NET detection."""
        from redb.extractors.pe_extractors.pe_dotnet import PEDotNetExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEDotNetExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            is_dotnet = extractor._check_dotnet()
            assert isinstance(is_dotnet, bool)
            # Test file should be .NET
            assert is_dotnet is True


# ============================================================================
# PEInconsistencyTestsExtractor Tests
# ============================================================================

class TestPEInconsistencyTestsExtractor:
    """Tests for PEInconsistencyTestsExtractor class."""

    def test_extract_inconsistency_tests(self, pe_binary_path, mock_logger):
        """Test inconsistency tests extraction."""
        from redb.extractors.pe_extractors.pe_inconsistency_tests import PEInconstistencyTestsExtractor as PEInconsistencyTestsExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEInconsistencyTestsExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # extract() returns True if tests were performed, False otherwise
            # The actual test results are stored in extractor.pe_inconsistency_tests
            # and extractor.dotnet_inconsistency_tests
            assert result in (True, False)

            if result:
                # Check that test results were stored
                assert extractor.pe_inconsistency_tests is not None or extractor.dotnet_inconsistency_tests is not None


# ============================================================================
# PEExtraFindings Tests
# ============================================================================

class TestPEExtraFindings:
    """Tests for PEExtraFindings class."""

    def test_extract_extra_findings(self, pe_binary_path, mock_logger):
        """Test extra findings extraction."""
        from redb.extractors.pe_extractors.pe_extra_findings import PEExtraFindings

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEExtraFindings(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May return None or list of findings
            if result is not None:
                assert isinstance(result, list)


# ============================================================================
# Integration Tests
# ============================================================================

class TestPEExtractorIntegration:
    """Integration tests for PE extractors."""

    def test_all_extractors_same_pe_object(self, pe_binary_path, mock_logger, pe_object):
        """Test that extractors can share the same PE object."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            # Create extractors sharing the same PE object
            features_ext = PEFeaturesExtractor(pe_binary_path, mock_logger, pe=pe_object)
            imports_ext = PEImportExtractor(pe_binary_path, mock_logger, pe=pe_object)
            sections_ext = PESectionExtractor(pe_binary_path, mock_logger, pe=pe_object)

            # All should use the same PE object
            assert features_ext.pe is pe_object
            assert imports_ext.pe is pe_object
            assert sections_ext.pe is pe_object

            # All should extract successfully
            features_result = features_ext.extract()
            imports_result = imports_ext.extract()
            sections_result = sections_ext.extract()

            assert features_result is not None
            # imports and sections may be None if not present

    def test_hash_consistency_across_extractors(self, pe_binary_path, mock_logger):
        """Test that hashes are consistent across all extractors."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            features_ext = PEFeaturesExtractor(pe_binary_path, mock_logger)
            imports_ext = PEImportExtractor(pe_binary_path, mock_logger)

            # Hashes should be the same
            assert features_ext.sha256 == imports_ext.sha256
            assert features_ext.md5 == imports_ext.md5
            assert features_ext.sha1 == imports_ext.sha1