Makoto Ando

88 papers A* 1Misc 2Journal 77Unranked 8
YearRankTypeTitle / Venue / Authors
2021 J jnl
IEEE Access
Miao Zhang, Masahiro Wakasa, Koji Toyosaki, Kiyomichi Araki, Jiro Hirokawa, Makoto Ando
2020 J jnl
IEICE Trans. Commun.
Tuchjuta Ruckkwaen, Takashi Tomura, Kiyomichi Araki, Jiro Hirokawa, Makoto Ando
2019 J jnl
IEICE Trans. Electron.
Takayoshi Hirasawa, Shigeyuki Akiba, Jiro Hirokawa, Makoto Ando
2018 J jnl
Int. J. Distributed Sens. Networks
Yumi Takaki, Makoto Ando, Keisuke Maesako, Keisuke Fujita, Tomio Kamada, Chikara Ohta, Hisashi Tamaki
2018 J jnl
IEICE Trans. Electron.
Dong-Hun Kim, Jiro Hirokawa, Makoto Ando
2017 J jnl
IEICE Trans. Commun.
Kotoko Furuya, Takayoshi Hirasawa, Masayuki Oishi, Shigeyuki Akiba, Jiro Hirokawa, Makoto Ando
2017 J jnl
IEICE Trans. Electron.
Dong-Hun Kim, Jiro Hirokawa, Makoto Ando
2017 J jnl
IEICE Trans. Commun.
Xin Xu, Jiro Hirokawa, Makoto Ando
2016 J jnl
IEICE Trans. Commun.
Satoshi Ito, Miao Zhang, Jiro Hirokawa, Makoto Ando
2016 J jnl
IEICE Trans. Commun.
Naoya Oikawa, Jiro Hirokawa, Hiroshi Nakano, Yasutake Hirachi, Hiroshi Isono, Atsushi Ishii, Makoto Ando
2016 conf
HiPC Workshops
Shashank Jaiswal, Rajesh Reddy, Raja Banerjee, Shingo Sato, Daisuke Komagata, Makoto Ando, Jun Okada
2016 J jnl
IEICE Trans. Commun.
Maifuz Ali, Makoto Ando
2015 J jnl
IEICE Trans. Commun.
Tung Nguyen, Jiro Hirokawa, Makoto Ando, Manuel Sierra-Castañer
2015 J jnl
IEICE Trans. Commun.
Maifuz Ali, Makoto Ando
2015 J jnl
IEICE Trans. Commun.
Hung V. Le, Carlo Capsoni, Roberto Nebuloni, Lorenzo Luini, Takuichi Hirano, Toru Taniguchi, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Electron.
Yusuke Uemichi, Ryouhei Hosono, Ning Guan, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Takashi Tomura, Jiro Hirokawa, Takuichi Hirano, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Hung V. Le, Hasan Md. Mohibul, Takuichi Hirano, Toru Taniguchi, Akira Yamaguchi, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Masayuki Oishi, Yoshihiro Nishikawa, Kosuke Nishimura, Keiji Tanaka, Shigeyuki Akiba, Jiro Hirokawa, Makoto Ando
2014 conf
OFC
Shigeyuki Akiba, Masayuki Oishi, Yoshihiro Nishikawa, Kyo Minoguchi, Jiro Hirokawa, Makoto Ando
2014 J jnl
IEICE Trans. Electron.
Takayuki Kohama, Makoto Ando
2014 J jnl
IEICE Trans. Commun.
Tung Nguyen, Rushanthi Jayawardene, Kimio Sakurai, Jiro Hirokawa, Makoto Ando, Manuel Sierra-Castañer, Osamu Amano, Shuichi Koreeda, Takaomi Matsuzaki, Yukio Kamata
2013 J jnl
IEICE Trans. Commun.
Tung Nguyen, Rushanthi Jayawardene, Yasutomo Takano, Kimio Sakurai, Jiro Hirokawa, Makoto Ando, Osamu Amano, Shuichi Koreeda, Takaomi Matsuzaki, Yukio Kamata
2013 J jnl
IEICE Trans. Commun.
Dongjin Kim, Jiro Hirokawa, Kimio Sakurai, Makoto Ando, Takuma Takada, Tadao Nagatsuma, Jun Takeuchi, Akihiko Hirata
2013 J jnl
IEICE Trans. Commun.
Jun Asano, Jiro Hirokawa, Hiroshi Nakano, Yasutake Hirachi, Hiroshi Isono, Atsushi Ishii, Makoto Ando
2012 J jnl
IEICE Trans. Electron.
Ryosuke Hasaba, Makoto Ando
2012 J jnl
IEICE Trans. Electron.
Yuanfeng She, Jiro Hirokawa, Makoto Ando, Daisuke Hanatani, Masahiro Fujimoto
2012 J jnl
IEICE Trans. Electron.
Takayuki Kohama, Makoto Ando
2011 J jnl
IEICE Trans. Commun.
Jae-Ho Lee, Jiro Hirokawa, Makoto Ando
2011 J jnl
IEICE Trans. Electron.
Yohei Miura, Jiro Hirokawa, Makoto Ando, Kazufumi Igarashi, Goro Yoshida
2011 conf
HCI (14)
Takafumi Watanabe, Kenji Inose, Makoto Ando, Takashi Kajinami, Takuji Narumi, Tomohiro Tanikawa, Michitaka Hirose
2011 J jnl
IEICE Trans. Electron.
Yuya Ono, Takuichi Hirano, Kenichi Okada, Jiro Hirokawa, Makoto Ando
2011 J jnl
IEICE Trans. Electron.
Keita Ito, Tetsu Shijo, Makoto Ando
2011 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2011 J jnl
IEICE Trans. Electron.
Yuanfeng She, Thi Huong Tran, Koh Hashimoto, Jiro Hirokawa, Makoto Ando
2011 J jnl
IEICE Trans. Commun.
Jae-Ho Lee, Takuichi Hirano, Jiro Hirokawa, Makoto Ando
2011 J jnl
NeuroImage
Eric D. Hostetler, Sandra M. Sanabria-Bohórquez, Hong Fan, Zhizhen Zeng, Liza Gantert, Mangay Williams, Patricia Miller, Stacey O'Malley, Minoru Kameda, Makoto Ando, Nagaaki Sato, Satoshi Ozaki, Shigeru Tokita, Hisashi Ohta, David Williams, Cyrille Sur, Jacquelynn J. Cook, H. Donald Burns, Richard Hargreaves
2010 J jnl
IEICE Trans. Commun.
Hideki Ueda, Jiro Hirokawa, Makoto Ando, Matteo Albani
2010 J jnl
IEICE Trans. Electron.
Koh Hashimoto, Jiro Hirokawa, Makoto Ando
2010 J jnl
NeuroImage
Eric D. Hostetler, Sandra M. Sanabria-Bohórquez, Hong Fan, Minoru Kameda, Makoto Ando, Zhizhen Zeng, Stacey O'Malley, Patricia Miller, Liza Gantert, David Williams, Shigeru Tokita, Nagaaki Sato, Satoshi Ozaki, Hisashi Ohta, Jacquelynn J. Cook, H. Donald Burns, Richard Hargreaves
2010 J jnl
IEICE Trans. Electron.
Jae-Ho Lee, Kimio Sakurai, Jiro Hirokawa, Makoto Ando
2010 J jnl
IEICE Trans. Commun.
Miroslav Samardzija, Jiro Hirokawa, Makoto Ando
2010 J jnl
IEICE Trans. Commun.
Koh Hashimoto, Jiro Hirokawa, Makoto Ando
2010 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2010 J jnl
IEICE Trans. Commun.
Makoto Ando
2009 J jnl
IEICE Trans. Commun.
Takehito Suzuki, Jiro Hirokawa, Makoto Ando
2009 J jnl
IEICE Trans. Commun.
Takehito Suzuki, Jiro Hirokawa, Makoto Ando
2009 J jnl
IEICE Trans. Electron.
JungAun Lee, Jiro Hirokawa, Makoto Ando
2009 J jnl
IEICE Trans. Electron.
Thi Huong Tran, Yuanfeng She, Jiro Hirokawa, Kimio Sakurai, Yoshinori Kogami, Makoto Ando
2009 J jnl
IEICE Trans. Electron.
Nobutaka Omaki, Tetsu Shijo, Makoto Ando
2008 J jnl
IEICE Trans. Commun.
Hideki Ueda, Jiro Hirokawa, Makoto Ando, Osamu Amano, Yukio Kamata
2008 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2008 J jnl
IEICE Trans. Electron.
JungAun Lee, Jiro Hirokawa, Makoto Ando
2008 J jnl
IEICE Trans. Commun.
Yasuhiro Tsunemitsu, Goro Yoshida, Naohisa Goto, Jiro Hirokawa, Makoto Ando
2007 J jnl
IEICE Trans. Electron.
Takafumi Kai, Jiro Hirokawa, Makoto Ando, Hiroshi Nakano, Yasutake Hirachi
2007 J jnl
IEICE Trans. Electron.
Luis Rodriguez, Makoto Ando
2007 J jnl
IEICE Trans. Commun.
Takafumi Kai, Jiro Hirokawa, Makoto Ando
2007 J jnl
IEICE Trans. Electron.
Tsuneki Yamasaki, Makoto Ando
2006 J jnl
IEICE Trans. Commun.
Takafumi Kai, Yusuke Katou, Jiro Hirokawa, Makoto Ando, Hiroshi Nakano, Yasutake Hirachi
2006 J jnl
IEICE Trans. Electron.
Shin-ichi Yamamoto, Jiro Hirokawa, Makoto Ando
2006 J jnl
IEICE Electron. Express
Kei Sato, Jiro Hirokawa, Kaoru Sudo, Makoto Ando
2006 J jnl
IEICE Trans. Commun.
Takuichi Hirano, Kimio Sakurai, Jiro Hirokawa, Makoto Ando, Tetsuya Ide, Atsushi Sasaki, Kazufumi Azuma, Yukihiko Nakata
2006 J jnl
IEICE Electron. Express
Toshinori Kondo, Jiro Hirokawa, Kimio Sakurai, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Takuichi Hirano, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Electron.
Shin-ichi Yamamoto, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Shin-ichi Yamamoto, Nozomu Hikino, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Miao Zhang, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Electron.
M. G. Sorwar Hossain, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Electron.
Yuichi Kimura, Masanari Takahashi, Jiro Hirokawa, Makoto Ando, Misao Haneishi
2005 J jnl
IEICE Trans. Electron.
Luis Rodriguez, Ken-ichi Sakina, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Takafumi Kai, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
M. G. Sorwar Hossain, Jiro Hirokawa, Makoto Ando
2005 J jnl
IEICE Trans. Electron.
Tetsu Shijo, Takuichi Hirano, Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Makoto Ando
2005 J jnl
IEICE Trans. Commun.
Yasuhiro Tsunemitsu, Sehyun Park, Jiro Hirokawa, Makoto Ando, Yohei Miura, Yasuhiro Kazama, Naohisa Goto
2005 J jnl
IEICE Trans. Electron.
Makoto Ando
2004 A* conf
VR
Tomohiro Tanikawa, Makoto Ando, Yankang Wang, Kazuhiro Yoshida, Jun Yamashita, Hideaki Kuzuoka, Michitaka Hirose
2004 J jnl
IEICE Electron. Express
Hisahiro Kai, Jiro Hirokawa, Makoto Ando
2000 Misc conf
PDPTA
Makoto Ando, Yutaka Akiyama, Hideo Matsuda
2000 J jnl
Bioinform.
Tamotsu Noguchi, Kentaro Onizuka, Makoto Ando, Hideo Matsuda, Yutaka Akiyama
1999 conf
ISHPC
Yutaka Akiyama, Kentaro Onizuka, Tamotsu Noguchi, Makoto Ando
1999 Misc conf
PDPTA
Makoto Ando, Yutaka Akiyama, Kentaro Onizuka, Tamotsu Noguchi
1998 conf
IPPS/SPDP Workshops
Yoshio Tanaka, Motohiko Matsuda, Makoto Ando, Kazuto Kubota, Mitsuhisa Sato
1997 conf
ISHPC
Yutaka Akiyama, Kiyotaka Misoo, Yoshiharu Omura, Hiroshi Matsumoto, Minoru Saito, Tamotsu Noguchi, Kentaro Onizuka, Makoto Ando
1995 conf
ICSC
Makoto Ando, Shigeo Morishima
1988 conf
COMPCON
Yoshihiko Imai, Makoto Ando, Masaaki Kobayashi, Yoshiaki Kushiki, Ken Sakamura
tests/integration/test_basicproperties.py
← Index tests/integration/test_basicproperties.py python
"""
Integration tests for the BasicPropertiesExtractor class.
"""
import pytest
import os
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.integration]


class TestBasicPropertiesExtractorInitialization:
    """Tests for BasicPropertiesExtractor initialization."""

    def test_initialization(self, elf_binary_path, mock_logger):
        """Test basic initialization."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.filepath == elf_binary_path
            assert extractor.basic_properties is None
            assert extractor.is_packed is None
            assert extractor.is_fat is None
            assert extractor.parent_sha256 is None
            assert extractor.child_sha256 is None
            assert extractor.child_architecture is None
            assert extractor.child_filetype is None

    def test_initialization_with_fat_params(self, elf_binary_path, mock_logger):
        """Test initialization with FAT Mach-O parameters."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            child_hashes = ["abc123", "def456"]
            child_archs = ["x86_64", "arm64"]
            child_types = ["macho", "macho"]

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                is_fat=True,
                child_sha256=child_hashes,
                child_architecture=child_archs,
                child_filetype=child_types
            )

            assert extractor.is_fat is True
            assert extractor.child_sha256 == child_hashes
            assert extractor.child_architecture == child_archs
            assert extractor.child_filetype == child_types

    def test_initialization_with_parent_sha256(self, elf_binary_path, mock_logger):
        """Test initialization with parent_sha256 for slice binaries."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            parent_hash = "parent_sha256_hash_here"

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                parent_sha256=parent_hash
            )

            assert extractor.parent_sha256 == parent_hash

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

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

            assert "-basic_properties" in extractor.elastic_index


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

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

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

            assert extractor.tag() == Tag.BASIC_PROPERTIES.value
            assert extractor.tag() == "basic_properties"


class TestBasicPropertiesExtract:
    """Tests for extract method."""

    def test_extract_elf_binary(self, elf_binary_path, mock_logger):
        """Test extracting properties from ELF binary."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor
        from redb.models.dataclasses import BasicProperties

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

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, BasicProperties)
            assert result.sample_name == os.path.basename(elf_binary_path)
            assert result.filesize > 0
            assert result.file_entropy >= 0
            assert result.filetype is not None
            assert result.filetype_mime is not None
            assert result.filetype_magika is not None

    def test_extract_pe_binary(self, pe_binary_path, mock_logger):
        """Test extracting properties from PE binary."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor
        from redb.models.dataclasses import BasicProperties

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

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, BasicProperties)
            assert result.filesize > 0
            # PE file should be detected
            assert "PE" in result.filetype or "executable" in result.filetype.lower()

    def test_extract_text_file(self, temp_text_file, mock_logger):
        """Test extracting properties from text file."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(temp_text_file, mock_logger)

            result = extractor.extract()

            assert result is not None
            assert "text" in result.filetype.lower() or "ASCII" in result.filetype
            assert result.file_entropy >= 0

    def test_extract_stores_in_basic_properties(self, elf_binary_path, mock_logger):
        """Test that extract stores result in basic_properties attribute."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.basic_properties is None
            result = extractor.extract()
            assert extractor.basic_properties is result


class TestBasicPropertiesFiletype:
    """Tests for file type detection."""

    def test_elf_filetype(self, elf_binary_path, mock_logger):
        """Test ELF file type detection."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            # Should detect as ELF
            assert "ELF" in result.filetype

    def test_pe_filetype_mime(self, pe_binary_path, mock_logger):
        """Test PE file type MIME detection."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            # PE MIME types (varies by libmagic version)
            assert "dosexec" in result.filetype_mime or "x-msdownload" in result.filetype_mime or "portable-executable" in result.filetype_mime

    def test_text_filetype_mime(self, temp_text_file, mock_logger):
        """Test text file type MIME detection."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(temp_text_file, mock_logger)

            result = extractor.extract()

            assert result is not None
            # Text MIME types
            assert "text" in result.filetype_mime


class TestBasicPropertiesEntropy:
    """Tests for entropy calculation in BasicPropertiesExtractor."""

    def test_entropy_reasonable_range(self, elf_binary_path, mock_logger):
        """Test that entropy is within reasonable range (0-8)."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            assert 0 <= result.file_entropy <= 8

    def test_entropy_rounded(self, elf_binary_path, mock_logger):
        """Test that entropy is rounded to 3 decimal places."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            # Check rounding to 3 decimal places
            entropy_str = str(result.file_entropy)
            if '.' in entropy_str:
                decimal_places = len(entropy_str.split('.')[1])
                assert decimal_places <= 3


class TestBasicPropertiesFilesize:
    """Tests for file size calculation."""

    def test_filesize_matches_actual(self, elf_binary_path, mock_logger):
        """Test that filesize matches actual file size."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            actual_size = os.path.getsize(elf_binary_path)
            assert result.filesize == actual_size

    def test_filesize_matches_binary_length(self, elf_binary_path, mock_logger, elf_binary_content):
        """Test that filesize matches binary content length."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result.filesize == len(elf_binary_content)


class TestBasicPropertiesPrepareExportData:
    """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.basicproperties import BasicPropertiesExtractor

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

            result = extractor.prepare_export_data("ElasticsearchExporter")

            assert result is extractor.basic_properties

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

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(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 len(data) == 1  # One row
            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 'filesize' in column_names
            assert 'file_entropy' in column_names
            assert 'filetype' in column_names
            assert 'filetype_mime' in column_names
            assert 'filetype_magika' in column_names
            # New FAT/child columns
            assert 'parent_sha256' in column_names
            assert 'child_sha256' in column_names
            assert 'child_architecture' in column_names
            assert 'child_filetype' in column_names
            assert 'is_fat' in column_names

    def test_prepare_export_clickhouse_data_types(self, elf_binary_path, mock_logger):
        """Test that ClickHouse export data has correct types."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            data, column_names, column_type_names = extractor.prepare_export_data("ClickHouseExporter")

            row = data[0]

            # Check that sha256 is a string with correct length
            sha256_idx = column_names.index('sha256')
            assert isinstance(row[sha256_idx], str)
            assert len(row[sha256_idx]) == 64

            # Check that filesize is an integer
            filesize_idx = column_names.index('filesize')
            assert isinstance(row[filesize_idx], int)

            # Check that file_entropy is a float
            entropy_idx = column_names.index('file_entropy')
            assert isinstance(row[entropy_idx], float)


class TestBasicPropertiesClickHouseTable:
    """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.basicproperties import BasicPropertiesExtractor

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

            assert extractor.get_clickhouse_table() == "redb_basic_properties"


class TestBasicPropertiesExportData:
    """Tests for export_data method."""

    def test_export_data_with_print_exporter(self, elf_binary_path, mock_logger, mock_print_exporter, capsys):
        """Test export_data with PrintExporter."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                exporters=[mock_print_exporter]
            )

            result = extractor.export_data()

            assert result is True

    def test_export_data_empty_exporters(self, elf_binary_path, mock_logger):
        """Test export_data with no exporters."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                exporters=[]
            )

            result = extractor.export_data()

            # Should succeed with no exporters
            assert result is True


class TestBasicPropertiesMagika:
    """Tests for Magika file type detection."""

    def test_magika_elf_detection(self, elf_binary_path, mock_logger):
        """Test Magika detection of ELF files."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            # Magika should detect ELF
            assert result.filetype_magika == "elf" or "elf" in result.filetype_magika.lower()

    def test_magika_pe_detection(self, pe_binary_path, mock_logger):
        """Test Magika detection of PE files."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            # Magika should detect PE
            assert "pe" in result.filetype_magika.lower() or "exe" in result.filetype_magika.lower()


class TestBasicPropertiesFATSupport:
    """Tests for FAT Mach-O and child file support."""

    def test_extract_with_fat_flag(self, elf_binary_path, mock_logger):
        """Test extraction with is_fat flag set."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            assert result.is_fat is True

    def test_extract_with_child_hashes(self, elf_binary_path, mock_logger):
        """Test extraction with child_sha256 provided."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            child_hashes = ["abc123def456", "789ghi012jkl"]

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                child_sha256=child_hashes
            )

            result = extractor.extract()

            assert result is not None
            assert result.child_sha256 == child_hashes

    def test_extract_with_child_architecture(self, elf_binary_path, mock_logger):
        """Test extraction with child_architecture provided."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            child_archs = ["x86_64", "arm64"]

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                child_architecture=child_archs
            )

            result = extractor.extract()

            assert result is not None
            assert result.child_architecture == child_archs

    def test_extract_with_child_filetype(self, elf_binary_path, mock_logger):
        """Test extraction with child_filetype provided."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            child_types = ["macho", "macho"]

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                child_filetype=child_types
            )

            result = extractor.extract()

            assert result is not None
            assert result.child_filetype == child_types

    def test_clickhouse_export_with_fat_data(self, elf_binary_path, mock_logger):
        """Test ClickHouse export includes FAT-related fields correctly."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            child_hashes = ["abc123", "def456"]
            child_archs = ["x86_64", "arm64"]
            child_types = ["macho", "macho"]

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                is_fat=True,
                child_sha256=child_hashes,
                child_architecture=child_archs,
                child_filetype=child_types,
                parent_sha256=None  # FAT container has no parent
            )
            extractor.extract()

            data, column_names, column_type_names = extractor.prepare_export_data("ClickHouseExporter")
            row = data[0]

            # Check FAT fields
            is_fat_idx = column_names.index('is_fat')
            assert row[is_fat_idx] is True

            child_sha256_idx = column_names.index('child_sha256')
            assert row[child_sha256_idx] == child_hashes

            child_arch_idx = column_names.index('child_architecture')
            assert row[child_arch_idx] == child_archs

            child_type_idx = column_names.index('child_filetype')
            assert row[child_type_idx] == child_types

    def test_clickhouse_export_for_slice(self, elf_binary_path, mock_logger):
        """Test ClickHouse export for a slice binary with parent_sha256."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            parent_hash = "parent_container_sha256_hash"

            extractor = BasicPropertiesExtractor(
                elf_binary_path,
                mock_logger,
                parent_sha256=parent_hash
            )
            extractor.extract()

            data, column_names, column_type_names = extractor.prepare_export_data("ClickHouseExporter")
            row = data[0]

            parent_idx = column_names.index('parent_sha256')
            assert row[parent_idx] == parent_hash

    def test_default_fat_fields_are_none_or_empty(self, elf_binary_path, mock_logger):
        """Test that FAT-related fields default to None/empty for non-FAT binaries."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            result = extractor.extract()

            assert result is not None
            assert result.is_fat is None
            assert result.child_sha256 is None
            assert result.child_architecture is None
            assert result.child_filetype is None


@pytest.mark.unit
@pytest.mark.dataclass
class TestBasicPropertiesDataclass:
    """Tests for BasicProperties dataclass structure."""

    def test_dataclass_has_all_expected_fields(self):
        """Test that BasicProperties dataclass has all expected fields."""
        from redb.models.dataclasses import BasicProperties

        # Create a sample instance
        bp = BasicProperties(
            filename="test.exe",
            sample_name="test.exe",
            filesize=1024,
            filetype="PE32",
            filetype_mime="application/x-dosexec",
            filetype_magika="pebin",
            file_entropy=6.5
        )

        # Check required fields
        assert bp.filename == "test.exe"
        assert bp.sample_name == "test.exe"
        assert bp.filesize == 1024
        assert bp.filetype == "PE32"
        assert bp.filetype_mime == "application/x-dosexec"
        assert bp.filetype_magika == "pebin"
        assert bp.file_entropy == 6.5

        # Check optional fields default to None
        assert bp.is_packed is None
        assert bp.is_fat is None
        assert bp.child_sha256 is None
        assert bp.child_architecture is None
        assert bp.child_filetype is None

    def test_dataclass_with_optional_fat_fields(self):
        """Test BasicProperties dataclass with FAT-related optional fields."""
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="universal.app",
            sample_name="universal.app",
            filesize=2048,
            filetype="Mach-O universal",
            filetype_mime="application/x-mach-binary",
            filetype_magika="macho",
            file_entropy=7.2,
            is_fat=True,
            child_sha256=["hash1", "hash2"],
            child_architecture=["x86_64", "arm64"],
            child_filetype=["macho", "macho"]
        )

        assert bp.is_fat is True
        assert bp.child_sha256 == ["hash1", "hash2"]
        assert bp.child_architecture == ["x86_64", "arm64"]
        assert bp.child_filetype == ["macho", "macho"]