Rahat Iqbal

142 papers B 8C 32Misc 2Journal 58Unranked 41
YearRankTypeTitle / Venue / Authors
2025 J jnl
IEEE Trans. Intell. Transp. Syst.
Eleni Aloupogianni, Faiyaz Doctor, Charalampos Karyotis, Raymond Tang, Rahat Iqbal
2025 B conf
PIMRC
Akshay Mohan Nair, Shahid Mumtaz, Charalampos C. Tsimenidis, Faiyaz Doctor, Charalampos Karyotis, Rahat Iqbal
2024 conf
ANT/EDI40
Eleni Aloupogianni, Charalampos Karyotis, Tomasz Maniak, Rahat Iqbal, Nikos I. Passas, Faiyaz Doctor, Zoran Vujicic
2024 conf
ICECET
Eleni Aloupogianni, Faiyaz Doctor, Charalampos Karyotis, Tomasz Maniak, Raymond Tang, Rahat Iqbal
2024 J jnl
IEEE Trans. Netw. Serv. Manag.
Nisarg P. Patel, Raj Parekh, Saad Ali Amin, Rajesh Gupta, Sudeep Tanwar, Neeraj Kumar, Rahat Iqbal, Ravi Sharma
2024 conf
CCGridW
Eleni Aloupogianni, Charalampos Karyotis, Tomasz Maniak, Rahat Iqbal, Nikos I. Passas, Zoran Vujicic, Faiyaz Doctor
2023 J jnl
IEEE Trans. Intell. Transp. Syst.
Mohammad Hijji, Rahat Iqbal, Anup Kumar Pandey, Faiyaz Doctor, Charalampos Karyotis, Wahid Rajeh, Ali Alshehri, Fahad Aradah
2023 J jnl
J. Signal Process. Syst.
Saad Ali Amin, Hanan Al Shanabari, Rahat Iqbal, Charalampos Karyotis
2023 J jnl
IEEE Commun. Stand. Mag.
Nilesh Kumar Jadav, Tejal Rathod, Rajesh Gupta, Sudeep Tanwar, Neeraj Kumar, Rahat Iqbal, Shadi Atalla, Mohammad Hijji, Saba Al-Rubaye
2023 J jnl
Artif. Intell. Rev.
Deepika Sirohi, Neeraj Kumar, Prashant Singh Rana, Sudeep Tanwar, Rahat Iqbal, Mohammad Hijji
2022 J jnl
Comput. Electr. Eng.
Anup Kumar Pandey, Rahat Iqbal, Tomasz Maniak, Charalampos Karyotis, Stephen Akuma, Vasile Palade
2022 conf
ICSPIS
Tomasz Maniak, Rahat Iqbal, Zoran Vujicic, Charalampos Karyotis, Nikos I. Passas, Faiyaz Doctor
2022 J jnl
IEEE Trans. Intell. Transp. Syst.
Mohammed Lawal Ahmed, Rahat Iqbal, Charalampos Karyotis, Vasile Palade, Saad Ali Amin
2021 conf
ICSPIS
Anup Kumar Pandey, Rahat Iqbal, Saad Ali Amin, Tomasz Maniak, Vasile Palade, Charalampos Karyotis
2021 J jnl
IEEE Trans. Ind. Informatics
Victor Chang, Mohamed Abdel-Basset, Rahat Iqbal, Gary B. Wills
2021 J jnl
IEEE Trans. Intell. Transp. Syst.
Tomasz Maniak, Rahat Iqbal, Faiyaz Doctor
2020 J jnl
Future Gener. Comput. Syst.
Rahat Iqbal, Faiyaz Doctor, Brian More, Shahid Mahmud, Usman Yousuf
2020 conf
CAMAD
Zoran Vujicic, Jonathan Rodriguez, Nikos I. Passas, Rahat Iqbal, Tomasz Maniak, Eftychia G. Datsika, John S. Vardakas, Charalampos Karyotis, Sherif Adeshina Busari, Christos V. Verikoukis
2019 conf
DG.O
Diogo Alves, Faiyaz Doctor, Rahat Iqbal, Ahmed Kattan
2019 J jnl
Future Gener. Comput. Syst.
Muna Alsallal, Rahat Iqbal, Vasile Palade, Saad Ali Amin, Victor Chang
2019 J jnl
Concurr. Comput. Pract. Exp.
Ayesha Siddiqa, Faisal Fayyaz Qureshi, Munam Ali Shah, Rahat Iqbal, Abdul Wahid, Victor Chang
2019 conf
IDEAL (1)
Muhammad Bello Aliyu, Rahat Iqbal, Anne E. James, Dianabasi Nkantah
2019 J jnl
Future Gener. Comput. Syst.
Javier Navarro, Faiyaz Doctor, Víctor Zamudio, Rahat Iqbal, Arun Kumar Sangaiah, Carlos Lino
2019 C conf
ICMLA
Charalampos Karyotis, Tomasz Maniak, Faiyaz Doctor, Rahat Iqbal, Vasile Palade, Raymond Tang
2019 J jnl
IEEE Trans. Ind. Informatics
Rahat Iqbal, Tomasz Maniak, Faiyaz Doctor, Charalampos Karyotis
2019 J jnl
Clust. Comput.
Saad Ali Amin, Mohammad Hijji, Rahat Iqbal, Wayne Harrop, Victor Chang
2019 J jnl
IEEE Netw.
Rahat Iqbal, Tomasz Maniak, Charalampos Karyotis
2018 C conf
CD-MAKE
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2018 J jnl
CoRR
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2018 J jnl
Int. J. Mob. Blended Learn.
John Marco Pima, Michael O. Odetayo, Rahat Iqbal, Eliamani Sedoyeka
2018 J jnl
Inf. Sci.
Charalampos Karyotis, Faiyaz Doctor, Rahat Iqbal, Anne E. James, Victor I. Chang
2018 J jnl
Future Gener. Comput. Syst.
Ruhul Amin, Neeraj Kumar, G. P. Biswas, Rahat Iqbal, Victor I. Chang
2018 J jnl
Comput. Ind.
Lech Birek, Adam Grzywaczewski, Rahat Iqbal, Faiyaz Doctor, Victor I. Chang
2018 J jnl
IEEE Trans. Emerg. Top. Comput.
Neeraj Kumar, Rahat Iqbal, Sudip Misra, Joel J. P. C. Rodrigues, Mohammad S. Obaidat
2018 J jnl
Future Gener. Comput. Syst.
Abdul Wahid, Munam Ali Shah, Faisal Fayyaz Qureshi, Hafsa Maryam, Rahat Iqbal, Victor I. Chang
2018 J jnl
Future Gener. Comput. Syst.
Zhihan Lv, Rahat Iqbal, Victor I. Chang
2018 conf
ICACCI
Thoufeeq Ahmed Syed, Vasile Palade, Rahat Iqbal, Smitha Sunil Kumaran Nair
2018 J jnl
Future Gener. Comput. Syst.
Javier Navarro, Faiyaz Doctor, Víctor Zamudio, Rahat Iqbal, Arun Kumar Sangaiah, Carlos Lino
2018 J jnl
Future Gener. Comput. Syst.
Javier Navarro, Faiyaz Doctor, Víctor Zamudio, Rahat Iqbal, Arun Kumar Sangaiah, Carlos Lino
2018 conf
ASAR
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2018 J jnl
CoRR
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2018 conf
SNAMS
Muhammad Bello Aliyu, Rahat Iqbal, Anne E. James
2017 conf
KDIR
Thoufeeq Ahmed Syed, Vasile Palade, Rahat Iqbal, Smitha Sunil Kumaran Nair
2017 ch.
State of the Art in AI Applied to Ambient Intelligence
Charalampos Karyotis, Faiyaz Doctor, Rahat Iqbal, Anne E. James
2017 J jnl
CoRR
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2017 conf
ASAR
Abdulaziz M. Alayba, Vasile Palade, Matthew England, Rahat Iqbal
2017 conf
ACIIDS (2)
Pen-Choug Sun, Chao-Fu Hong, Tsu-Feng Kuo, Rahat Iqbal
2017 C conf
CSCWD
Antonios G. Nanos, Anne E. James, Rahat Iqbal, Yih-Ling Hedley
2017 J jnl
Enterp. Inf. Syst.
Rahat Iqbal, Adam Grzywaczewski, John Halloran, Faiyaz Doctor, Kashif Iqbal
2017 J jnl
J. Netw. Comput. Appl.
Faisal Fayyaz Qureshi, Rahat Iqbal, Muhammad Nabeel Asghar
2017 J jnl
Inf. Sci.
Obada Alhabashneh, Rahat Iqbal, Faiyaz Doctor, Anne E. James
2017 C conf
IoTBDS
Dongcheng Zhao, Gang Sun, Dan Liao, Rahat Iqbal, Victor Chang
2017 C conf
ICMLA
Andrei Pavel, Vasile Palade, Rahat Iqbal, Diana Hintea
2016 conf
IoTBD
Charalampos Karyotis, Faiyaz Doctor, Rahat Iqbal, Anne E. James, Victor Chang
2016 C conf
DeSE
Muna Alsallal, Rahat Iqbal, Saad Ali Amin, Anne E. James, Vasile Palade
2016 C conf
DeSE
Mohammad Hijji, Rahat Iqbal, Saad Ali Amin, Wayne Harrop
2016 J jnl
Neurocomputing
Kashif Iqbal, Michael O. Odetayo, Anne E. James, Rahat Iqbal, Neeraj Kumar, Shovan Barma
2016 J jnl
Peer-to-Peer Netw. Appl.
Neeraj Kumar, Kuljeet Kaur, Subhas C. Misra, Rahat Iqbal
2016 conf
SSCI
Faiyaz Doctor, Charalampos Karyotis, Rahat Iqbal, Anne E. James
2016 J jnl
Future Gener. Comput. Syst.
Shahid Mahmud, Rahat Iqbal, Faiyaz Doctor
2016 J jnl
Comput. Hum. Behav.
Stephen Akuma, Rahat Iqbal, Chrisina Jayne, Faiyaz Doctor
2016 conf
BCS HCI
Omar Mubin, Mauricio Novoa, Joshua Forrester, Rahat Iqbal
2016 J jnl
Appl. Soft Comput.
Faiyaz Doctor, Chih-Hao Syue, Yan-Xin Liu, Jiann-Shing Shieh, Rahat Iqbal
2015 B conf
FUZZ-IEEE
Obada Alhabashneh, Rahat Iqbal, Faiyaz Doctor, Saad Ali Amin
2015 J jnl
J. Comput. Syst. Sci.
Neeraj Kumar, Rahat Iqbal, Sudip Misra, Joel J. P. C. Rodrigues
2015 B conf
FUZZ-IEEE
Charalampos Karyotis, Faiyaz Doctor, Rahat Iqbal, Anne E. James
2015 J jnl
Inf. Sci.
Tomasz Maniak, Chrisina Jayne, Rahat Iqbal, Faiyaz Doctor
2015 J jnl
Future Gener. Comput. Syst.
Neeraj Kumar, Rahat Iqbal, Sudip Misra, Joel J. P. C. Rodrigues
2015 C conf
CSCWD
Neeraj Kumar, Rahat Iqbal, Anne E. James, Amit Dua
2015 C conf
EANN
Stephen Akuma, Chrisina Jayne, Rahat Iqbal, Faiyaz Doctor
2015 J jnl
J. Ambient Intell. Smart Environ.
Faiyaz Doctor, Rahat Iqbal, Víctor Zamudio
2015 J jnl
J. Supercomput.
Neeraj Kumar, Rasmeet S. Bali, Rahat Iqbal, Naveen K. Chilamkurti, Seungmin Rho
2015 conf
BICOD
Antonios G. Nanos, Anne E. James, Rahat Iqbal, Yih-Ling Hedley
2014 conf
ACIIDS (2)
Pen-Choug Sun, Rahat Iqbal, Shu-Huei Liu
2014 J jnl
J. Ambient Intell. Humaniz. Comput.
Faiyaz Doctor, Rahat Iqbal, Raouf N. Gorgui-Naguib
2014 J jnl
Int. J. Commun. Networks Distributed Syst.
Rahat Iqbal, Faiyaz Doctor, Nazaraf Shah, Xiang Fei
2014 Misc conf
AIAI
Stephen Akuma, Chrisina Jayne, Rahat Iqbal, Faiyaz Doctor
2014 J jnl
J. Ambient Intell. Humaniz. Comput.
Rahat Iqbal
2014 B conf
Intelligent Environments (Workshops)
Faiyaz Doctor, Víctor Zamudio, Rahat Iqbal
2014 C conf
CSCWD
Adeniyi Abdul, Rahat Iqbal, Anne E. James, Michael O. Odetayo, Nazaraf Shah
2013 C conf
DeSE
Mohammad Hijji, Saad Ali Amin, Rahat Iqbal, Wayne Harrop
2013 C conf
CSCWD
Rahat Iqbal, Faiyaz Doctor, Margarida Romero, Anne E. James
2013 B conf
SMC
Tomasz Maniak, Rahat Iqbal, Faiyaz Doctor, Chrisina Jayne
2013 C conf
CSCWD
Abdulaziz Al-Raisi, Saad Ali Amin, Rahat Iqbal, Phil Thompson
2013 J jnl
J. Netw. Comput. Appl.
Rahat Iqbal, Nazaraf Shah, Anne E. James, Tomasz Cichowicz
2013 C conf
DeSE
Muna Alsallal, Rahat Iqbal, Saad Ali Amin, Anne E. James
2013 conf
ICEBE
Neeraj Kumar, Rahat Iqbal, Anne E. James, Amit Dua
2013 C conf
CSCWD
Adam Grzywaczewski, Rahat Iqbal, Anne E. James, John Halloran
2012 conf
CyberC
Pen-Choug Sun, Michael O. Odetayo, Rahat Iqbal, Anne E. James
2012 conf
ICEBE
Pen-Choug Sun, Michael O. Odetayo, Rahat Iqbal, Anne E. James
2012 C conf
EANN
Faiyaz Doctor, Chrisina Jayne, Rahat Iqbal
2012 B conf
FUZZ-IEEE
Faiyaz Doctor, Rahat Iqbal
2012 J jnl
Future Gener. Comput. Syst.
Neeraj Kumar, Rahat Iqbal, Naveen K. Chilamkurti
2012 J jnl
J. Comput. Syst. Sci.
Rahat Iqbal, Nazaraf Shah
2012 C conf
CSCWD
Rahat Iqbal, Nazaraf Shah, Faiyaz Doctor, Anne E. James, Tomasz Cichowicz
2012 C conf
CSCWD
Rahat Iqbal, Adam Grzywaczewski, Anne E. James, Faiyaz Doctor, John Halloran
2012 J jnl
J. Comput. Syst. Sci.
Adam Grzywaczewski, Rahat Iqbal
2011 C conf
DeSE
Faiyaz Doctor, Raouf N. Gorgui-Naguib, Rahat Iqbal
2011 C conf
CSCWD
Rose T. Neugebauer, Anne E. James, Rahat Iqbal
2011 J jnl
Expert Syst. Appl.
Rahat Iqbal, Nazaraf Shah, Anne E. James, Jacob Duursma
2011 C conf
CSCWD
Phil Thompson, Anne E. James, Rahat Iqbal
2011 J jnl
Simul. Model. Pract. Theory
Neeraj Kumar, Rahat Iqbal, Naveen K. Chilamkurti, Anne E. James
2011 C conf
CSCWD
Robert Bird, Rahat Iqbal, Margarida Romero, Anne E. James
2011 C conf
CSCWD
Rahat Iqbal, R. Rider, Nazaraf Shah, Anne E. James
2011 J jnl
Future Gener. Comput. Syst.
Rose Tshoganetso Khachana, Anne E. James, Rahat Iqbal
2011 J jnl
Int. J. Knowl. Web Intell.
Adam Grzywaczewski, Rahat Iqbal
2011 Misc conf
ICCS
Obada Alhabashneh, Rahat Iqbal, Nazaraf Shah, Saad Ali Amin, Anne E. James
2010 C conf
CSCWD
Rahat Iqbal, Anne E. James, Witold Poreda, John Black
2010 conf
ICEBE
Adam Grzywaczewski, Rahat Iqbal, Nazaraf Shah, Anne E. James
2010 B conf
SMC
Rahat Iqbal, John Halloran, Nazaraf Shah, Anne E. James
2009 J jnl
J. Univers. Comput. Sci.
Nazaraf Shah, Rahat Iqbal, Kashif Iqbal, Anne E. James
2009 C conf
CSCWD
Tshoganetso Khachana, Anne E. James, Rahat Iqbal
2009 J jnl
Int. J. Adv. Pervasive Ubiquitous Comput.
Adam Grzywaczewski, Rahat Iqbal, Anne E. James, John Halloran
2009 conf
BNCOD
John Halloran, Rahat Iqbal, Dzmitry Aliakseyeu, Martinez Fernando, Richard Cooper, Adam Grzywaczewski, Ratvinder Grewal, Anne E. James, Chris Greenhalgh
2009 J jnl
Inf. Sci.
Nazaraf Shah, Rahat Iqbal, Anne E. James, Kashif Iqbal
2009 C conf
CSCWD
Phil Thompson, Rahat Iqbal, Anne E. James
2009 C conf
CSCWD
Rahat Iqbal, Nazaraf Shah, Anne E. James, Jacob Duursma
2008 C conf
CSCWD
Nazaraf Shah, Rahat Iqbal, Anne E. James, Kashif Iqbal
2008 conf
ITNG
Rahat Iqbal, Kashif Iqbal, Nazaraf Shah, Jawed I. A. Siddiqi, Anne E. James
2008 B conf
ICALT
Rahat Iqbal, Anne E. James
2008 conf
ICEBE
Rahat Iqbal, Nazaraf Shah, Kuo-Ming Chao, Konstantian Karatsivi
2007 conf
BCS HCI (2)
Rahat Iqbal, Jacques M. B. Terken
2007 conf
CSCWD (Selected Papers)
Phil Thompson, Rahat Iqbal, Anne E. James
2007 C conf
CSCWD
Nazaraf Shah, Rahat Iqbal, Anne E. James, Jawed I. A. Siddiqi, Babak Akhgar
2007 C conf
CSCWD
Phil Thompson, Rahat Iqbal, Anne E. James
2006 C conf
CSCWD
Rahat Iqbal, Nazaraf Hussain Shah, Anne E. James, Muhammad Younas, Kuo-Ming Chao
2006 conf
ICEBE
Rahat Iqbal, Nazaraf Hussain Shah, Kuo-Ming Chao, Anne E. James
2006 conf
CSCWD (Selected Papers)
Rahat Iqbal, Nazaraf Shah, Anne E. James, Babak Akhgar, Muhammad Younas, Kuo-Ming Chao
2005 conf
SIGDOC
Rahat Iqbal, Richard A. Gatward, Anne E. James
2005 J jnl
Adv. Eng. Informatics
Rahat Iqbal, Anne E. James, Richard A. Gatward
2005 conf
MLMI
Janienke Sturm, Rahat Iqbal, Jacques M. B. Terken
2005 conf
SIGITE Conference
Rahat Iqbal, Peter Every
2005 conf
SIGDOC
Rahat Iqbal, Janienke Sturm, Olga A. Kulyk, Jimmy Wang, Jacques M. B. Terken
2004 conf
BCS HCI
Rahat Iqbal, Anne E. James
2003 J jnl
Int. J. Comput.
Rahat Iqbal, Anne E. James, Richard A. Gatward
2003 conf
EFIS
Rahat Iqbal, Anne E. James, Richard A. Gatward
2003 conf
NDDL/VVEIS
Rahat Iqbal, Anne E. James, Richard A. Gatward
2003 conf
BNCOD Posters
Rahat Iqbal, Anne E. James, Richard A. Gatward
2003 conf
DEXA Workshops
Rahat Iqbal, Anne E. James, Richard A. Gatward
2003 conf
European Across Grids Conference
Norlaily Yaacob, Rahat Iqbal
2003 conf
ICEIS (3)
Rahat Iqbal, Anne E. James, Richard A. Gatward
2002 C conf
CSCWD
Rahat Iqbal, Anne E. James, Richard A. Gatward
tests/integration/test_hashes.py
← Index tests/integration/test_hashes.py python
"""
Integration tests for the HashExtractor class.
"""
import pytest
import hashlib
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.integration]


class TestHashExtractorInitialization:
    """Tests for HashExtractor initialization."""

    def test_initialization_elf(self, elf_binary_path, mock_logger):
        """Test initialization with ELF file."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            assert extractor.filepath == elf_binary_path
            assert extractor.hashes is None
            assert extractor.filetype == "elf"
            assert extractor.macho is None

    def test_initialization_with_macho_object(self, elf_binary_path, mock_logger):
        """Test initialization with pre-parsed macho object."""
        from redb.extractors.hashes import HashExtractor

        mock_macho = MagicMock()
        mock_macho.get_architectures.return_value = ["x86_64"]

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger, macho=mock_macho)

            assert extractor.macho is mock_macho

    def test_initialization_pe(self, pe_binary_path, mock_logger):
        """Test initialization with PE file."""
        from redb.extractors.hashes import HashExtractor

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

            assert extractor.filepath == pe_binary_path
            assert extractor.filetype == "pebin"
            # PE object should be created
            assert extractor.pe is not None

    def test_elastic_index_suffix(self, elf_binary_path, mock_logger):
        """Test that elastic_index has correct suffix."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            assert "-hashes" in extractor.elastic_index


class TestHashExtractorTag:
    """Tests for tag method."""

    def test_tag_value(self, elf_binary_path, mock_logger):
        """Test that tag returns correct value."""
        from redb.extractors.hashes import HashExtractor
        from redb.extractors.enum import Tag

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            assert extractor.tag() == Tag.HASH.value
            assert extractor.tag() == "hash"


class TestHashExtractorBasicHashes:
    """Tests for basic hash extraction."""

    def test_extract_md5(self, elf_binary_path, mock_logger, known_hashes):
        """Test MD5 hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            assert result.md5 == known_hashes['md5']

    def test_extract_sha1(self, elf_binary_path, mock_logger, known_hashes):
        """Test SHA1 hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            assert result.sha1 == known_hashes['sha1']

    def test_extract_sha256(self, elf_binary_path, mock_logger, known_hashes):
        """Test SHA256 hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            assert result.sha256 == known_hashes['sha256']

    def test_extract_ssdeep(self, elf_binary_path, mock_logger):
        """Test ssdeep hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # ssdeep should be a string
            assert isinstance(result.ssdeep_hash, str)

    def test_extract_tlsh(self, elf_binary_path, mock_logger):
        """Test TLSH hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # TLSH should be a string
            assert isinstance(result.tlsh_hash, str)


class TestHashExtractorPEHashes:
    """Tests for PE-specific hash extraction."""

    def test_extract_imphash(self, pe_binary_path, mock_logger):
        """Test imphash extraction for PE file."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            # Imphash should be set for PE files
            if extractor.pe is not None:
                assert result.imphash is not None or result.imphash is None  # May or may not have imports

    def test_extract_authentihash(self, pe_binary_path, mock_logger):
        """Test authentihash extraction for PE file."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            # Authentihash should be set for PE files
            if extractor.pe is not None:
                assert result.authentihash is not None

    def test_pe_hashes_not_set_for_elf(self, elf_binary_path, mock_logger):
        """Test that PE-specific hashes are not set for ELF files."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # PE-specific hashes should be None for ELF
            assert result.imphash is None
            assert result.authentihash is None
            assert result.richhash is None


class TestHashExtractorRichHeaderHashes:
    """Tests for Rich header hash extraction."""

    def test_compute_richhash(self, pe_binary_path, mock_logger):
        """Test Rich header hash computation."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            # Rich hash may or may not be present depending on the PE
            if result.richhash is not None:
                assert isinstance(result.richhash, str)
                assert len(result.richhash) == 32  # MD5 hex length

    def test_compute_richpe_hash(self, pe_binary_path, mock_logger):
        """Test RichPE hash computation."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            # RichPE hash may or may not be present
            if result.richpe_hash is not None:
                assert isinstance(result.richpe_hash, str)
                assert len(result.richpe_hash) == 32  # MD5 hex length

    def test_compute_richpv_hash(self, pe_binary_path, mock_logger):
        """Test RichPV hash computation."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            # RichPV hashes may or may not be present
            if result.richpv_hash is not None:
                assert isinstance(result.richpv_hash, str)
            if result.richpv_hash_sorted is not None:
                assert isinstance(result.richpv_hash_sorted, str)


class TestHashExtractorELFHashes:
    """Tests for ELF-specific hash extraction."""

    def test_extract_elf_import_hash(self, elf_binary_path, mock_logger):
        """Test ELF import hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Import hash may or may not be present
            if result.import_hash is not None:
                assert isinstance(result.import_hash, str)
                assert len(result.import_hash) == 32

    def test_extract_elf_export_hash(self, elf_binary_path, mock_logger):
        """Test ELF export hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Export hash may or may not be present
            if result.export_hash is not None:
                assert isinstance(result.export_hash, str)

    def test_extract_elf_section_hash(self, elf_binary_path, mock_logger):
        """Test ELF section hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Section hash should be present for valid ELF
            if result.section_hash is not None:
                assert isinstance(result.section_hash, str)

    def test_extract_elf_symbol_hash(self, elf_binary_path, mock_logger):
        """Test ELF symbol hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Symbol hash (symhash) may or may not be present
            if result.symbol_hash is not None:
                assert isinstance(result.symbol_hash, str)

    def test_extract_elf_dynamic_hash(self, elf_binary_path, mock_logger):
        """Test ELF dynamic hash extraction."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Dynamic hash may or may not be present
            if result.dynamic_hash is not None:
                assert isinstance(result.dynamic_hash, str)


class TestHashExtractorPrepareExportData:
    """Tests for prepare_export_data method."""

    def test_prepare_export_elasticsearch(self, elf_binary_path, mock_logger):
        """Test prepare_export_data for Elasticsearch."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)
            extractor.extract()

            result = extractor.prepare_export_data("ElasticsearchExporter")

            assert result is extractor.hashes

    def test_prepare_export_clickhouse(self, elf_binary_path, mock_logger):
        """Test prepare_export_data for ClickHouse."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)
            extractor.extract()

            result = extractor.prepare_export_data("ClickHouseExporter")

            # Should return tuple of (data, column_names, column_type_names)
            assert isinstance(result, tuple)
            assert len(result) == 3

            data, column_names, column_type_names = result

            assert isinstance(data, list)
            assert isinstance(column_names, list)
            assert isinstance(column_type_names, list)

            # Check expected columns
            assert 'sha256' in column_names
            assert 'md5' in column_names
            assert 'sha1' in column_names
            assert 'ssdeep_hash' in column_names
            assert 'tlsh_hash' in column_names

    def test_prepare_export_clickhouse_pe(self, pe_binary_path, mock_logger):
        """Test prepare_export_data for ClickHouse with PE file."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.prepare_export_data("ClickHouseExporter")

            data, column_names, column_type_names = result

            # PE-specific columns should be present
            assert 'authentihash' in column_names
            assert 'imphash' in column_names
            assert 'richhash' in column_names

    def test_prepare_export_clickhouse_has_macho_columns(self, elf_binary_path, mock_logger):
        """Test prepare_export_data for ClickHouse includes Mach-O hash columns."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)
            extractor.extract()

            result = extractor.prepare_export_data("ClickHouseExporter")

            data, column_names, column_type_names = result

            # Mach-O hash columns should be present
            assert 'macho_dylib_hash' in column_names
            assert 'macho_import_hash' in column_names
            assert 'macho_export_hash' in column_names
            assert 'macho_entitlement_hash' in column_names
            assert 'macho_symhash' in column_names


class TestHashExtractorClickHouseTable:
    """Tests for get_clickhouse_table method."""

    def test_clickhouse_table_name(self, elf_binary_path, mock_logger):
        """Test correct ClickHouse table name."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            assert extractor.get_clickhouse_table() == "redb_hashes"


@pytest.mark.unit
@pytest.mark.dataclass
class TestHashExtractorHashesDataclass:
    """Tests for Hashes dataclass structure."""

    def test_hashes_dataclass_structure(self, elf_binary_path, mock_logger):
        """Test that Hashes dataclass has expected structure."""
        from redb.extractors.hashes import HashExtractor
        from redb.models.dataclasses import Hashes

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert isinstance(result, Hashes)
            # Required fields
            assert hasattr(result, 'md5')
            assert hasattr(result, 'sha1')
            assert hasattr(result, 'sha256')
            assert hasattr(result, 'ssdeep_hash')
            assert hasattr(result, 'tlsh_hash')
            # Optional fields
            assert hasattr(result, 'authentihash')
            assert hasattr(result, 'imphash')
            assert hasattr(result, 'richhash')

    def test_hashes_dataclass_has_macho_fields(self):
        """Test that Hashes dataclass has Mach-O hash fields."""
        from redb.models.dataclasses import Hashes

        # Create instance with default values
        hashes = Hashes(
            md5="d41d8cd98f00b204e9800998ecf8427e",
            sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709",
            sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            ssdeep_hash="",
            tlsh_hash=""
        )

        # Verify Mach-O hash fields exist and default to None
        assert hasattr(hashes, 'macho_dylib_hash')
        assert hasattr(hashes, 'macho_import_hash')
        assert hasattr(hashes, 'macho_export_hash')
        assert hasattr(hashes, 'macho_entitlement_hash')
        assert hasattr(hashes, 'macho_symhash')

        assert hashes.macho_dylib_hash is None
        assert hashes.macho_import_hash is None
        assert hashes.macho_export_hash is None
        assert hashes.macho_entitlement_hash is None
        assert hashes.macho_symhash is None

    def test_hashes_dataclass_with_macho_values(self):
        """Test that Hashes dataclass can be created with Mach-O hash values."""
        from redb.models.dataclasses import Hashes

        hashes = Hashes(
            md5="d41d8cd98f00b204e9800998ecf8427e",
            sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709",
            sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            ssdeep_hash="",
            tlsh_hash="",
            macho_dylib_hash="abc123def456789012345678901234567",
            macho_import_hash="def456abc123789012345678901234567",
            macho_export_hash="789012abc123def456345678901234567",
            macho_entitlement_hash="345678abc123def456789012901234567",
            macho_symhash="901234abc123def456789012345678567"
        )

        assert hashes.macho_dylib_hash == "abc123def456789012345678901234567"
        assert hashes.macho_import_hash == "def456abc123789012345678901234567"
        assert hashes.macho_export_hash == "789012abc123def456345678901234567"
        assert hashes.macho_entitlement_hash == "345678abc123def456789012901234567"
        assert hashes.macho_symhash == "901234abc123def456789012345678567"


class TestHashExtractorErrorHandling:
    """Tests for error handling in HashExtractor."""

    def test_extract_handles_hash_errors(self, elf_binary_path, mock_logger):
        """Test that extract handles hash computation errors gracefully."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            # Even if some hashes fail, we should get a result
            result = extractor.extract()

            assert result is not None

    def test_extract_with_invalid_pe(self, elf_binary_path, mock_logger):
        """Test extraction when PE parsing fails."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            # Force filetype to be 'pebin' but use ELF file
            with patch.object(HashExtractor, '__init__', lambda self, *args, **kwargs: None):
                extractor = HashExtractor.__new__(HashExtractor)
                extractor.filepath = elf_binary_path
                extractor.log = mock_logger
                extractor.hashes = None
                extractor.pe = None
                extractor.filetype = 'pebin'

                with open(elf_binary_path, 'rb') as f:
                    extractor.binary = f.read()

                # Should not crash
                result = extractor._extract_hashes()
                assert result is not None


class TestHashExtractorMachoHashes:
    """Tests for Mach-O specific hash extraction."""

    def test_macho_hashes_not_set_for_elf(self, elf_binary_path, mock_logger):
        """Test that Mach-O hashes are not set for ELF files."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result is not None
            assert result.macho_dylib_hash is None
            assert result.macho_import_hash is None
            assert result.macho_export_hash is None
            assert result.macho_entitlement_hash is None
            assert result.macho_symhash is None

    def test_macho_hashes_not_set_for_pe(self, pe_binary_path, mock_logger):
        """Test that Mach-O hashes are not set for PE files."""
        from redb.extractors.hashes import HashExtractor

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

            result = extractor.extract()

            assert result is not None
            assert result.macho_dylib_hash is None
            assert result.macho_import_hash is None
            assert result.macho_export_hash is None
            assert result.macho_entitlement_hash is None
            assert result.macho_symhash is None

    def test_extract_macho_hashes_with_mock(self, elf_binary_path, mock_logger):
        """Test Mach-O hash extraction with mocked macho object."""
        from redb.extractors.hashes import HashExtractor

        # Create mock macho object
        mock_macho = MagicMock()
        mock_macho.get_architectures.return_value = ["x86_64"]
        mock_macho.get_similarity_hashes.return_value = {
            'dylib_hash': 'abc123def456789012345678901234ab',
            'import_hash': 'def456abc789012345678901234567cd',
            'export_hash': '789012abc456def345678901234567ef',
            'entitlement_hash': '345678abc123def789012901234567gh',
            'symhash': '901234abc123def456789012345678ij'
        }

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger, macho=mock_macho)
            # Override filetype to trigger macho hash extraction
            extractor.filetype = 'macho'

            result = extractor.extract()

            assert result is not None
            assert result.macho_dylib_hash == 'abc123def456789012345678901234ab'
            assert result.macho_import_hash == 'def456abc789012345678901234567cd'
            assert result.macho_export_hash == '789012abc456def345678901234567ef'
            assert result.macho_entitlement_hash == '345678abc123def789012901234567gh'
            assert result.macho_symhash == '901234abc123def456789012345678ij'

    def test_extract_macho_hashes_fat_binary_mock(self, elf_binary_path, mock_logger):
        """Test Mach-O hash extraction for FAT binary with mocked macho object."""
        from redb.extractors.hashes import HashExtractor

        # Create mock macho object for FAT binary
        mock_macho = MagicMock()
        mock_macho.get_architectures.return_value = ["x86_64", "arm64"]  # Multiple archs = FAT
        mock_macho.get_similarity_hashes.return_value = {
            'fat': {
                'dylib_hash': 'fat_dylib_hash_12345678901234567',
                'import_hash': 'fat_import_hash_12345678901234567',
            },
            'combined': {
                'dylib_hash': 'combined_dylib_hash_1234567890123',
            }
        }

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger, macho=mock_macho)
            extractor.filetype = 'macho'

            result = extractor.extract()

            assert result is not None
            # Should use 'fat' key for FAT binaries
            assert result.macho_dylib_hash == 'fat_dylib_hash_12345678901234567'
            assert result.macho_import_hash == 'fat_import_hash_12345678901234567'

    def test_extract_macho_hashes_handles_empty(self, elf_binary_path, mock_logger):
        """Test Mach-O hash extraction handles empty hash dict."""
        from redb.extractors.hashes import HashExtractor

        mock_macho = MagicMock()
        mock_macho.get_architectures.return_value = ["x86_64"]
        mock_macho.get_similarity_hashes.return_value = {}

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger, macho=mock_macho)
            extractor.filetype = 'macho'

            result = extractor.extract()

            # Should not crash, hashes should be None
            assert result is not None
            assert result.macho_dylib_hash is None

    def test_extract_macho_hashes_handles_none(self, elf_binary_path, mock_logger):
        """Test Mach-O hash extraction handles None return."""
        from redb.extractors.hashes import HashExtractor

        mock_macho = MagicMock()
        mock_macho.get_architectures.return_value = ["x86_64"]
        mock_macho.get_similarity_hashes.return_value = None

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger, macho=mock_macho)
            extractor.filetype = 'macho'

            result = extractor.extract()

            # Should not crash
            assert result is not None


class TestHashExtractorConsistency:
    """Tests for hash consistency."""

    def test_hash_consistency_across_extractions(self, elf_binary_path, mock_logger):
        """Test that hashes are consistent across multiple extractions."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor1 = HashExtractor(elf_binary_path, mock_logger)
            result1 = extractor1.extract()

            extractor2 = HashExtractor(elf_binary_path, mock_logger)
            result2 = extractor2.extract()

            assert result1.md5 == result2.md5
            assert result1.sha1 == result2.sha1
            assert result1.sha256 == result2.sha256

    def test_hash_values_are_lowercase(self, elf_binary_path, mock_logger):
        """Test that hash values are lowercase hex strings."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert result.md5 == result.md5.lower()
            assert result.sha1 == result.sha1.lower()
            assert result.sha256 == result.sha256.lower()

    def test_hash_lengths_correct(self, elf_binary_path, mock_logger):
        """Test that hash lengths are correct."""
        from redb.extractors.hashes import HashExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = HashExtractor(elf_binary_path, mock_logger)

            result = extractor.extract()

            assert len(result.md5) == 32  # MD5 = 128 bits = 32 hex chars
            assert len(result.sha1) == 40  # SHA1 = 160 bits = 40 hex chars
            assert len(result.sha256) == 64  # SHA256 = 256 bits = 64 hex chars