Haiquan Li

33 papers A* 2Misc 8Journal 19Unranked 3
YearRankTypeTitle / Venue / Authors
2023 J jnl
Remote. Sens.
Madeline Melichar, Kamel Didan, Armando Barreto-Muñoz, Jennifer N. Duberstein, Eduardo Jiménez Hernández, Theresa Crimmins, Haiquan Li, Myles Traphagen, Kathryn A. Thomas, Pamela L. Nagler
2022 J jnl
Simul.
Haiquan Li, Yan Wang, Juncheng Jiang, Ru Zhou
2021 J jnl
Frontiers Robotics AI
Haiquan Li, Qingqing Wei, Jianxun Liang, Weiyan Ren, Zixin Tang, Delun Li
2019 Misc conf
AMIA
Qike Li, Samir Rachid Zaim, Dillon Aberasturi, Joanne Berghout, Haiquan Li, Francesca Vitali, Colleen Kenost, Hao Helen Zhang, Yves A. Lussier
2019 Misc conf
PSB
Francesca Vitali, Joanne Berghout, Jung-Wei Fan, Jianrong Li, Qike Li, Haiquan Li, Yves A. Lussier
2019 Misc conf
PSB
Yves A. Lussier, Atul J. Butte, Haiquan Li, Rong Chen, Jason H. Moore
2018 Misc conf
PSB
Jiali Han, Jianrong Li, Ikbel Achour, Lorenzo L. Pesce, Ian T. Foster, Haiquan Li, Yves A. Lussier
2017 J jnl
J. Am. Medical Informatics Assoc.
Vincent Gardeux, Joanne Berghout, Ikbel Achour, A. Grant Schissler, Qike Li, Colleen Kenost, Jianrong Li, Yuan Shang, Anthony Bosco, Donald Saner, Marilyn J. Halonen, Daniel Jackson, Haiquan Li, Fernando D. Martinez, Yves A. Lussier
2017 J jnl
J. Biomed. Informatics
Qike Li, A. Grant Schissler, Vincent Gardeux, Joanne Berghout, Ikbel Achour, Colleen Kenost, Haiquan Li, Hao Helen Zhang, Yves A. Lussier
2016 J jnl
Bioinform.
A. Grant Schissler, Qike Li, James L. Chen, Colleen Kenost, Ikbel Achour, Dean Billheimer, Haiquan Li, Walter W. Piegorsch, Yves A. Lussier
2015 J jnl
Bioinform.
A. Grant Schissler, Vincent Gardeux, Qike Li, Ikbel Achour, Haiquan Li, Walter W. Piegorsch, Yves A. Lussier
2015 J jnl
J. Biomed. Informatics
Haiquan Li, Nima Pouladi, Ikbel Achour, Vincent Gardeux, Jianrong Li, Qike Li, Hao Helen Zhang, Fernando D. Martinez, Joe G. N. 'Skip' Garcia, Yves A. Lussier
2014 J jnl
J. Am. Medical Informatics Assoc.
Vincent Gardeux, Ikbel Achour, Jianrong Li, Mark Maienschein-Cline, Haiquan Li, Lorenzo L. Pesce, Gurunadh Parinandi, Neil Bahroos, Robert Winn, Ian T. Foster, Joe G. N. Garcia, Yves A. Lussier
2014 Misc conf
AMIA
Young Ji Lee, Andrew D. Boyd, Jianrong Li, Vincent Gardeux, Colleen Kenost, Donald Saner, Haiquan Li, Ivo L. Abraham, Jerry A. Krishnan, Yves A. Lussier
2013 Misc conf
Pacific Symposium on Biocomputing
Alan Perez-Rathke, Haiquan Li, Yves A. Lussier
2013 J jnl
J. Am. Medical Informatics Assoc.
Younghee Lee, Haiquan Li, Jianrong Li, Ellen Rebman, Ikbel Achour, Kelly Regan, Eric R. Gamazon, James L. Chen, Xinan Holly Yang, Nancy J. Cox, Yves A. Lussier
2012 J jnl
J. Biomed. Informatics
Yves A. Lussier, Haiquan Li
2012 J jnl
J. Am. Medical Informatics Assoc.
Haiquan Li, Younghee Lee, James L. Chen, Ellen Rebman, Jianrong Li, Yves A. Lussier
2012 Misc conf
AMIA
Xinan Yang, Haiquan Li, Kelly Regan, Jianrong Li, Yong Huang, H. Rosie Xing, Yves A. Lussier
2012 J jnl
J. Am. Medical Informatics Assoc.
Kelly Regan, Kanix Wang, Emily Doughty, Haiquan Li, Jianrong Li, Younghee Lee, Maricel G. Kann, Yves A. Lussier
2009 ch.
Encyclopedia of Data Warehousing and Mining
Haiquan Li, Jinyan Li, Xuechun Zhao
2009 J jnl
BMC Bioinform.
Haiquan Li, Vagner A. Benedito, Michael K. Udvardi, Patrick Xuechun Zhao
2008 J jnl
Bioinform.
Haiquan Li, Xinbin Dai, Xuechun Zhao
2008 conf
IIH-MSP
Dening Zhang, Shuguang Zhang, Xuesong Suo, Man Cheng, Hong Juan Kou, Xiang Ling Shi, Su Zhang, Haiquan Li
2007 J jnl
IEEE Trans. Knowl. Data Eng.
Jinyan Li, Guimei Liu, Haiquan Li, Limsoon Wong
2006 J jnl
Bioinform.
Haiquan Li, Jinyan Li, Limsoon Wong
2006 A* conf
AAAI
Jinyan Li, Haiquan Li, Limsoon Wong, Jian Pei, Guozhu Dong
2005 conf
PKDD
Jinyan Li, Haiquan Li, Donny Soh, Limsoon Wong
2005 J jnl
Bioinform.
Haiquan Li, Jinyan Li
2005 A* conf
PODS
Haiquan Li, Jinyan Li, Limsoon Wong, Mengling Feng, Yap-Peng Tan
2005 conf
CIS (1)
Gang Li, Linyan Sun, Ping Ji, Haiquan Li
2005 J jnl
IEEE Trans. Knowl. Data Eng.
Jinyan Li, Haiquan Li
2004 Misc conf
Pacific Symposium on Biocomputing
Haiquan Li, Jinyan Li, Soon-Heng Tan, See-Kiong Ng
tests/integration/test_base_extractor.py
← Index tests/integration/test_base_extractor.py python
"""
Integration tests for the base Extractor class.
"""
import pytest
import hashlib
import math
from unittest.mock import Mock, patch, MagicMock
from collections import Counter

pytestmark = [pytest.mark.integration]


class TestExtractorStaticMethods:
    """Tests for static methods in Extractor class."""

    def test_process_binary_string_printable(self):
        """Test processing a printable binary string."""
        from redb.extractors.extractor import Extractor

        # Test with printable ASCII characters
        input_bytes = b"Hello World\x00\x00\x00"
        result = Extractor.process_binary_string(input_bytes)
        assert result == "Hello World"

    def test_process_binary_string_non_printable(self):
        """Test processing a string with non-printable characters."""
        from redb.extractors.extractor import Extractor

        # Test with non-printable characters
        input_bytes = b"\x01\x02Hello\x00"
        result = Extractor.process_binary_string(input_bytes)
        assert "\\x01" in result
        assert "\\x02" in result
        assert "Hello" in result

    def test_process_binary_string_empty(self):
        """Test processing an empty binary string."""
        from redb.extractors.extractor import Extractor

        input_bytes = b"\x00\x00\x00"
        result = Extractor.process_binary_string(input_bytes)
        assert result == ""

    def test_process_binary_string_all_printable(self):
        """Test processing a fully printable string."""
        from redb.extractors.extractor import Extractor

        input_bytes = b"TestString123"
        result = Extractor.process_binary_string(input_bytes)
        assert result == "TestString123"

    def test_remove_non_utf8_valid(self):
        """Test removing non-UTF8 characters from valid UTF8 string."""
        from redb.extractors.extractor import Extractor

        input_bytes = b"Hello World"
        result = Extractor.remove_non_utf8(input_bytes)
        assert result == b"Hello World"

    def test_remove_non_utf8_with_invalid(self):
        """Test removing non-UTF8 characters from mixed string."""
        from redb.extractors.extractor import Extractor

        # Mix of valid UTF8 and invalid bytes
        input_bytes = b"Hello\xff\xfeWorld"
        result = Extractor.remove_non_utf8(input_bytes)
        # Should remove the invalid bytes
        assert b"\xff" not in result
        assert b"\xfe" not in result
        assert b"Hello" in result
        assert b"World" in result

    def test_remove_non_utf8_empty(self):
        """Test removing non-UTF8 from empty string."""
        from redb.extractors.extractor import Extractor

        result = Extractor.remove_non_utf8(b"")
        assert result == b""


class TestExtractorEntropyCalculation:
    """Tests for entropy calculation in Extractor class."""

    def test_calculate_entropy_empty_data(self, elf_binary_path, mock_logger):
        """Test entropy calculation with empty data."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            result = extractor.calculate_entropy(b"")
            assert result == 0.0

    def test_calculate_entropy_uniform_data(self, elf_binary_path, mock_logger):
        """Test entropy calculation with uniform (low entropy) data."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            # All same bytes = 0 entropy
            uniform_data = b"\x00" * 256
            result = extractor.calculate_entropy(uniform_data)
            assert result == 0.0

    def test_calculate_entropy_random_data(self, elf_binary_path, mock_logger, high_entropy_data):
        """Test entropy calculation with random (high entropy) data."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            result = extractor.calculate_entropy(high_entropy_data)
            # Random data should have entropy close to 8 (max for bytes)
            assert result > 7.0

    def test_calculate_entropy_binary_data(self, elf_binary_path, mock_logger):
        """Test entropy calculation with binary data."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            # Two equally distributed values = 1 bit entropy
            binary_data = b"\x00\x01" * 128
            result = extractor.calculate_entropy(binary_data)
            assert abs(result - 1.0) < 0.01

    def test_calculate_entropy_string_data(self, elf_binary_path, mock_logger):
        """Test entropy calculation with string data."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            # String with two equally distributed characters
            string_data = "ab" * 100
            result = extractor.calculate_entropy(string_data)
            assert abs(result - 1.0) < 0.01


class TestExtractorInitialization:
    """Tests for Extractor initialization."""

    def test_extractor_hashes_computed_on_init(self, elf_binary_path, mock_logger, known_hashes):
        """Test that hashes are computed during initialization."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.md5 == known_hashes['md5']
            assert extractor.sha1 == known_hashes['sha1']
            assert extractor.sha256 == known_hashes['sha256']

    def test_extractor_hash_dataclass_created(self, elf_binary_path, mock_logger, known_hashes):
        """Test that Hash dataclass is created during initialization."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.hash.md5 == known_hashes['md5']
            assert extractor.hash.sha1 == known_hashes['sha1']
            assert extractor.hash.sha256 == known_hashes['sha256']

    def test_extractor_binary_cached_property(self, elf_binary_path, mock_logger, elf_binary_content):
        """Test that binary content is loaded as cached property."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            # Access binary property
            binary = extractor.binary
            assert binary == elf_binary_content

            # Second access should return cached value (same id)
            assert extractor.binary is binary

    def test_extractor_with_exporters(self, elf_binary_path, mock_logger, mock_print_exporter):
        """Test extractor initialization with exporters."""
        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]
            )

            assert len(extractor.exporters) == 1
            assert extractor.exporters[0] is mock_print_exporter

    def test_extractor_with_index_prefix(self, elf_binary_path, mock_logger):
        """Test extractor initialization with custom index prefix."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert "custom_prefix" in extractor.elastic_index

    def test_extractor_known_benign_flag(self, elf_binary_path, mock_logger):
        """Test extractor with known_benign flag."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.known_benign is True
            assert extractor.known_malicious is False

    def test_extractor_known_malicious_flag(self, elf_binary_path, mock_logger):
        """Test extractor with known_malicious flag."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

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

            assert extractor.known_benign is False
            assert extractor.known_malicious is True


class TestExtractorExportData:
    """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()
            # Should succeed with PrintExporter
            assert result is True

    def test_export_data_no_exporters(self, elf_binary_path, mock_logger):
        """Test export_data with no exporters configured."""
        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 (nothing to export)
            assert result is True


class TestExtractorEdgeCases:
    """Tests for edge cases in Extractor class."""

    def test_extractor_with_nonexistent_file(self, mock_logger):
        """Test extractor with non-existent file."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            with pytest.raises(FileNotFoundError):
                BasicPropertiesExtractor("/nonexistent/file.bin", mock_logger)

    def test_entropy_none_data(self, elf_binary_path, mock_logger):
        """Test entropy calculation with None returns 0."""
        from redb.extractors.basicproperties import BasicPropertiesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = BasicPropertiesExtractor(elf_binary_path, mock_logger)
            result = extractor.calculate_entropy(None)
            assert result == 0.0

    def test_process_binary_string_high_bytes(self):
        """Test processing binary string with high byte values."""
        from redb.extractors.extractor import Extractor

        # Characters above 126 are non-printable
        input_bytes = b"\x7f\x80\x81\xff"
        result = Extractor.process_binary_string(input_bytes)
        assert "\\x7f" in result
        assert "\\x80" in result
        assert "\\xff" in result