Carlos Maltzahn

107 papers A* 3A 14B 7C 1Misc 7Journal 26Unranked 46
YearRankTypeTitle / Venue / Authors
2024 J jnl
CoRR
Jayjeet Chakraborty, Matthieu Dorier, Philip H. Carns, Robert Ross, Carlos Maltzahn, Heiner Litz
2023 conf
IPDPS Workshops
Craig D. Ulmer, Jianshen Liu, Carlos Maltzahn, Matthew L. Curry
2023 conf
HPEC
Jianshen Liu, Carlos Maltzahn, Craig D. Ulmer
2023 J jnl
Comput. Softw. Big Sci.
Wahid Bhimji, Dale W. Carder, Eli Dart, Javier M. Duarte, Ian Fisk, Robert W. Gardner, Chin Guok, Bo Jayatilaka, Tom Lehman, M. Lin, Carlos Maltzahn, Shawn McKee, Mark S. Neubauer, O. Rind, Oksana Shadura, N. V. Tran, P. van Gemmeren, Gordon Watts, B. A. Weaver, Frank Würthwein
2022 J jnl
CoRR
Aldrin Montana, Yuanqing Xue, Jeff LeFevre, Carlos Maltzahn, Josh Stuart, Philip Kufeldt, Peter Alvaro
2022 J jnl
IEEE Trans. Parallel Distributed Syst.
Stephen Lien Harrell, Scott Michael, Carlos Maltzahn
2022 J jnl
CoRR
Esmaeil Mirvakili, Samuel Just, Carlos Maltzahn
2022 A conf
SC
Farid Zakaria, Thomas R. W. Scogland, Todd Gamblin, Carlos Maltzahn
2022 J jnl
CoRR
Farid Zakaria, Thomas R. W. Scogland, Todd Gamblin, Carlos Maltzahn
2022 A conf
HPDC
Jay F. Lofstead, Carlos Maltzahn, Ivo Jimenez
2022 conf
HPEC
Jianshen Liu, Carlos Maltzahn, Matthew L. Curry, Craig D. Ulmer
2022 J jnl
CoRR
Jianshen Liu, Carlos Maltzahn, Matthew L. Curry, Craig D. Ulmer
2022 B conf
CCGRID
Jayjeet Chakraborty, Ivo Jimenez, Sebastiaan Alvarez Rodriguez, Alexandru Uta, Jeff LeFevre, Carlos Maltzahn
2022 J jnl
CoRR
Jayjeet Chakraborty, Ivo Jimenez, Sebastiaan Alvarez Rodriguez, Alexandru Uta, Jeff LeFevre, Carlos Maltzahn
2022 J jnl
CoRR
W. Bhimij, Dale W. Carder, Eli Dart, Javier M. Duarte, Ian Fisk, Robert W. Gardner, Chin Guok, Bo Jayatilaka, Tom Lehman, M. Lin, Carlos Maltzahn, Shawn McKee, Mark S. Neubauer, O. Rind, Oksana Shadura, N. V. Tran, P. van Gemmeren, Gordon Watts, B. A. Weaver, Frank Würthwein
2021 J jnl
CoRR
Jianshen Liu, Carlos Maltzahn, Craig D. Ulmer, Matthew Leon Curry
2021 J jnl
CoRR
Jayjeet Chakraborty, Ivo Jimenez, Sebastiaan Alvarez Rodriguez, Alexandru Uta, Jeff LeFevre, Carlos Maltzahn
2021 conf
IEEE BigData
Sebastiaan Alvarez Rodriguez, Jayjeet Chakraborty, Aaron Chu, Ivo Jimenez, Jeff LeFevre, Carlos Maltzahn, Alexandru Uta
2021 J jnl
CoRR
Sebastiaan Alvarez Rodriguez, Jayjeet Chakraborty, Aaron Chu, Ivo Jimenez, Jeff LeFevre, Carlos Maltzahn, Alexandru Uta
2020 conf
CANOPIE-HPC@SC
Jayjeet Chakraborty, Carlos Maltzahn, Ivo Jimenez
2020 Misc conf
NSDI
Alexandru Uta, Alexandru Custura, Dmitry Duplyakin, Ivo Jimenez, Jan S. Rellermeyer, Carlos Maltzahn, Robert Ricci, Alexandru Iosup
2020 J jnl
CoRR
Xiaowei Chu, Jeff LeFevre, Aldrin Montana, Dana Robinson, Quincey Koziol, Peter Alvaro, Carlos Maltzahn
2020 ed.
P-RECS@HPDC
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead
2020 conf
HotEdge
Jianshen Liu, Matthew L. Curry, Carlos Maltzahn, Philip Kufeldt
2020 J jnl
login Usenix Mag.
Jeff LeFevre, Carlos Maltzahn
2020 J jnl
CoRR
Stephanie Lieggi, Ivo Jimenez, Jeff LeFevre, Carlos Maltzahn
2019 B conf
PPoPP
Ivo Jimenez, Jay F. Lofstead, Carlos Maltzahn
2019 J jnl
CoRR
Alexandru Uta, Alexandru Custura, Dmitry Duplyakin, Ivo Jimenez, Jan S. Rellermeyer, Carlos Maltzahn, Robert Ricci, Alexandru Iosup
2019 conf
ISC Workshops
Jianshen Liu, Philip Kufeldt, Carlos Maltzahn
2019 J jnl
CoRR
Jianshen Liu, Philip Kufeldt, Carlos Maltzahn
2019 ed.
P-RECS@HPDC
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead
2019 B ed.
SSDBM
Carlos Maltzahn, Tanu Malik
2019 conf
P-RECS@HPDC
Andrea David, Mariette Souppe, Ivo Jimenez, Katia Obraczka, Sam Mansfield, Kerry Veenstra, Carlos Maltzahn
2019 conf
PDSW@SC
Kathryn Dahlgren, Jeff LeFevre, Ashay Shirwadkar, Ken Iizawa, Aldrin Montana, Peter Alvaro, Carlos Maltzahn
2018 A conf
IPDPS
Michael A. Sevilla, Ivo Jimenez, Noah Watkins, Jeff LeFevre, Peter Alvaro, Shel Finkelstein, Patrick Donnelly, Carlos Maltzahn
2018 J jnl
login Usenix Mag.
Philip Kufeldt, Carlos Maltzahn, Tim Feldman, Christine Green, Grant Mackey, Shingo Tanaka
2018 B conf
CCGrid
Michael A. Sevilla, Carlos Maltzahn, Peter Alvaro, Reza Nasirigerdeh, Bradley W. Settlemyer, Danny Perez, David Rich, Galen M. Shipman
2018 A* conf
OSDI
Aleksander Maricq, Dmitry Duplyakin, Ivo Jimenez, Carlos Maltzahn, Ryan Stutsman, Robert Ricci, Ana Klimovic
2018 conf
HotStorage
Michael A. Sevilla, Reza Nasirigerdeh, Carlos Maltzahn, Jeff LeFevre, Noah Watkins, Peter Alvaro, Margaret Lawson, Jay F. Lofstead, Jim Pivarski
2017 conf
HotStorage
Noah Watkins, Michael A. Sevilla, Ivo Jimenez, Kathryn Dahlgren, Peter Alvaro, Shel Finkelstein, Carlos Maltzahn
2017 conf
INFOCOM Workshops
Ivo Jimenez, Sina Hamedian, Jay F. Lofstead, Carlos Maltzahn, Kathryn M. Mohror, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau, Robert Ricci
2017 Misc conf
HiPC
Zhihao Jia, Sean Treichler, Galen M. Shipman, Michael Bauer, Noah Watkins, Carlos Maltzahn, Patrick S. McCormick, Alex Aiken
2017 J jnl
ACM Trans. Storage
Carlos Maltzahn, Vasily Tarasov
2017 A conf
EuroSys
Michael A. Sevilla, Noah Watkins, Ivo Jimenez, Peter Alvaro, Shel Finkelstein, Jeff LeFevre, Carlos Maltzahn
2017 conf
PDSW-DISCS@SC
Latchesar Ionkov, Carlos Maltzahn, Michael Lang
2017 conf
INFOCOM Workshops
Ivo Jimenez, Andrea C. Arpaci-Dusseau, Remzi H. Arpaci-Dusseau, Jay F. Lofstead, Carlos Maltzahn, Kathryn M. Mohror, Robert Ricci
2017 conf
IPDPS Workshops
Ivo Jimenez, Michael Sevilla, Noah Watkins, Carlos Maltzahn, Jay F. Lofstead, Kathryn M. Mohror, Andrea C. Arpaci-Dusseau, Remzi H. Arpaci-Dusseau
2016 conf
IPDPS Workshops
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead, Adam Moody, Kathryn M. Mohror, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau
2016 A conf
SC
Jay F. Lofstead, Ivo Jimenez, Carlos Maltzahn, Quincey Koziol, John Bent, Eric Barton
2016 J jnl
Tiny Trans. Comput. Sci.
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead, Adam Moody, Kathryn M. Mohror, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau
2016 J jnl
login Usenix Mag.
Ivo Jimenez, Michael Sevilla, Noah Watkins, Carlos Maltzahn, Jay F. Lofstead, Kathryn M. Mohror, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau
2016 B conf
ICCCN
Andrew G. Shewmaker, Carlos Maltzahn, Katia Obraczka, Scott A. Brandt, John Bent
2016 conf
HotStorage
Adam Manzanares, Noah Watkins, Cyril Guyot, Damien Le Moal, Carlos Maltzahn, Zvonimir Bandic
2015 conf
PDSW@SC
Noah Watkins, Zhihao Jia, Galen M. Shipman, Carlos Maltzahn, Alex Aiken, Patrick S. McCormick
2015 A conf
SC
Michael A. Sevilla, Noah Watkins, Carlos Maltzahn, Ike Nassi, Scott A. Brandt, Sage A. Weil, Greg Farnum, Sam Fineberg
2015 conf
PDSW@SC
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead, Adam Moody, Kathryn M. Mohror, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau
2015 B conf
IC2E
Ivo Jimenez, Carlos Maltzahn, Adam Moody, Kathryn M. Mohror, Jay F. Lofstead, Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau
2014 C conf
CLUSTER
Jay F. Lofstead, Ivo Jimenez, Carlos Maltzahn, Quincey Koziol, John Bent, Eric Barton
2014 Misc conf
MSST
Adam Crume, Carlos Maltzahn, Lee Ward, Thomas M. Kroeger, Matthew L. Curry
2014 conf
ICPP Workshops
Jay F. Lofstead, Ivo Jimenez, Carlos Maltzahn
2014 J jnl
CoRR
Ivo Jimenez, Carlos Maltzahn, Jay F. Lofstead
2014 conf
DISCS@SC
Jay F. Lofstead, Jai Dayal, Ivo Jimenez, Carlos Maltzahn
2014 conf
INFLOW
Dimitris Skourtis, Dimitris Achlioptas, Noah Watkins, Carlos Maltzahn, Scott A. Brandt
2014 conf
USENIX ATC
Dimitris Skourtis, Dimitris Achlioptas, Noah Watkins, Carlos Maltzahn, Scott A. Brandt
2014 conf
GamifIR@ECIR
Carlos Maltzahn, Arnav Jhala, Michael Mateas, Jim Whitehead
2014 ed.
PFSW@HPDC
Carlos Maltzahn, Patrick S. McCormick
2014 conf
IPDPS Workshops
Michael Sevilla, Ike Nassi, Kleoni Ioannidou, Scott A. Brandt, Carlos Maltzahn
2013 conf
DISCS@SC
Michael Sevilla, Ike Nassi, Kleoni Ioannidou, Scott A. Brandt, Carlos Maltzahn
2013 Misc conf
MSST
Latchesar Ionkov, Michael Lang, Carlos Maltzahn
2013 conf
PDSW@SC
Jay F. Lofstead, Jai Dayal, Ivo Jimenez, Carlos Maltzahn
2013 conf
PDSW@SC
Adam Crume, Carlos Maltzahn, Lee Ward, Thomas M. Kroeger, Matthew L. Curry, Ron A. Oldfield
2013 conf
INFLOW@SOSP
Dimitris Skourtis, Dimitris Achlioptas, Carlos Maltzahn, Scott A. Brandt
2013 A conf
HPDC
Jun He, John Bent, Aaron Torres, Gary Grider, Garth A. Gibson, Carlos Maltzahn, Xian-He Sun
2013 conf
Euro-Par Workshops
Noah Watkins, Carlos Maltzahn, Scott A. Brandt, Ian Pye, Adam Manzanares
2013 J jnl
Int. J. Parallel Emergent Distributed Syst.
Sasha Ames, Maya B. Gokhale, Carlos Maltzahn
2013 A conf
SC
Joe B. Buck, Noah Watkins, Greg Levin, Adam Crume, Kleoni Ioannidou, Scott A. Brandt, Carlos Maltzahn, Neoklis Polyzotis, Aaron Torres
2012 conf
SC Companion
Adam Crume, Joe B. Buck, Carlos Maltzahn, Scott A. Brandt
2012 conf
SC Companion
Noah Watkins, Carlos Maltzahn, Scott A. Brandt, Adam Manzanares
2012 conf
SC Companion
Jun He, John Bent, Aaron Torres, Gary Grider, Garth A. Gibson, Carlos Maltzahn, Xian-He Sun
2012 conf
USENIX ATC
Shinpei Kato, Michael McThrow, Carlos Maltzahn, Scott A. Brandt
2012 Misc conf
MSST
Ning Liu, Jason Cope, Philip H. Carns, Christopher D. Carothers, Robert B. Ross, Gary Grider, Adam Crume, Carlos Maltzahn
2012 B conf
SERVICES
Varun Bhagwan, Tyrone Grandison, Carlos Maltzahn
2011 conf
PPAM (1)
Ning Liu, Christopher D. Carothers, Jason Cope, Philip H. Carns, Robert B. Ross, Adam Crume, Carlos Maltzahn
2011 conf
SC Companion
Adam Crume, Carlos Maltzahn, Jason Cope, Sam Lang, Robert B. Ross, Philip H. Carns, Christopher D. Carothers, Ning Liu, Curtis L. Janssen, John Bent, Stephan J. Eidenbenz, Meghan McClelland
2011 conf
NAS
Sasha Ames, Maya B. Gokhale, Carlos Maltzahn
2011 A conf
IEEE Real-Time and Embedded Technology and Applications Symposium
Roberto C. Pineiro, Kleoni Ioannidou, Scott A. Brandt, Carlos Maltzahn
2011 A conf
SC
Joe B. Buck, Noah Watkins, Jeff LeFevre, Kleoni Ioannidou, Carlos Maltzahn, Neoklis Polyzotis, Scott A. Brandt
2010 J jnl
login Usenix Mag.
Carlos Maltzahn, Esteban Molina-Estolano, Amandeep Khurana, Alex J. Nelson, Scott A. Brandt, Sage A. Weil
2009 conf
IEEE SCC
Varun Bhagwan, Carlos Maltzahn
2008 A conf
EuroSys
Anna Povzner, Tim Kaldewey, Scott A. Brandt, Richard A. Golding, Theodore M. Wong, Carlos Maltzahn
2008 A conf
IEEE Real-Time and Embedded Technology and Applications Symposium
Tim Kaldewey, Theodore M. Wong, Richard A. Golding, Anna Povzner, Scott A. Brandt, Carlos Maltzahn
2007 conf
PDSW
David O. Bigelow, Suresh Iyer, Tim Kaldewey, Roberto C. Pineiro, Anna Povzner, Scott A. Brandt, Richard A. Golding, Theodore M. Wong, Carlos Maltzahn
2007 conf
PDSW
Sage A. Weil, Andrew W. Leung, Scott A. Brandt, Carlos Maltzahn
2007 conf
PDSW
Jonathan Koren, Andrew W. Leung, Yi Zhang, Carlos Maltzahn, Sasha Ames, Ethan L. Miller
2007 Misc conf
MSST
Andrew W. Leung, Eric Lalonde, Jacob Telleen, James Davis, Carlos Maltzahn
2006 A* conf
OSDI
Sage A. Weil, Scott A. Brandt, Ethan L. Miller, Darrell D. E. Long, Carlos Maltzahn
2006 A conf
SC
Sage A. Weil, Scott A. Brandt, Ethan L. Miller, Carlos Maltzahn
2005 conf
IEEE Security in Storage Workshop
Kevin M. Greenan, Mark W. Storer, Ethan L. Miller, Carlos Maltzahn
2005 Misc conf
MSST
Alexander Ames, Carlos Maltzahn, Nikhil Bobb, Ethan L. Miller, Scott A. Brandt, Alisa Neeman, Adam Hiatt, Deepa Tuteja
1999 conf
USENIX ATC, General Track
Carlos Maltzahn, Kathy J. Richardson, Dirk Grunwald
1997 A* conf
SIGMETRICS
Carlos Maltzahn, Kathy J. Richardson, Dirk Grunwald
1997 conf
HICSS (4)
Clarence A. Ellis, Carlos Maltzahn
1995 conf
CHI 95 Conference Companion
Carlos Maltzahn
1992 A conf
CAiSE
Thomas Rose, Carlos Maltzahn, Matthias Jarke
1992 J jnl
Int. J. Cooperative Inf. Syst.
Matthias Jarke, Carlos Maltzahn, Thomas Rose
1991 J jnl
Softw. Eng. J.
Thomas Rose, Matthias Jarke, Michael Gocek, Carlos Maltzahn, Hans W. Nissen
1991 conf
Wissensbasierte Systeme
Carlos Maltzahn, Thomas Rose
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