Wanyuan Wang

52 papers A* 5A 7B 2C 2Misc 1Journal 30Unranked 5
YearRankTypeTitle / Venue / Authors
2026 A* conf
AAAI
Jianbo Yu, Yixuan Li, Hai Xu, Kang Xu, Junjielong Xu, Zhijing Li, Pinjia He, Wanyuan Wang
2026 J jnl
CoRR
Jianbo Yu, Yixuan Li, Hai Xu, Kang Xu, Junjielong Xu, Zhijing Li, Pinjia He, Wanyuan Wang
2026 J jnl
IEEE Trans Autom. Sci. Eng.
Wanyuan Wang, Qian Che, Chunyu Liu, Youzhi Zhang, Jiuchuan Jiang, Bo An
2025 J jnl
IEEE Trans. Mob. Comput.
Xiang Liu, Weiwei Wu, Minming Li, Wanyuan Wang, Yifan Qin, Yingchao Zhao, Junzhou Luo
2025 A conf
AAMAS
Haotong Zhang, Wanyuan Wang
2025 A* conf
AAAI
Yixuan Li, Can Chen, Jiajun Li, Jiahui Duan, Xiongwei Han, Tao Zhong, Vincent Chau, Weiwei Wu, Wanyuan Wang
2025 J jnl
CoRR
Yixuan Li, Can Chen, Jiajun Li, Jiahui Duan, Xiongwei Han, Tao Zhong, Vincent Chau, Weiwei Wu, Wanyuan Wang
2025 J jnl
IEEE Trans. Intell. Transp. Syst.
Haipeng Zhang, Zhiwen Wang, Jilin Yu, Ruonan Zhang, Caoqing Jiang, Gongkun Luo, Weiwei Wu, Wanyuan Wang
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Che, Wanyuan Wang, Guiyi Liu, Wenyuan Zhang, Jiuchuan Jiang, Yichuan Jiang
2024 A conf
AAMAS
Yixuan Li, Wanyuan Wang, Weiyi Xu, Yanchen Deng, Weiwei Wu
2024 C conf
PDCAT
Yixuan Li, Yi Huang, Junlan Feng, Chao Deng, Chunyu Liu, Vincent Chau, Wanyuan Wang
2024 J jnl
Auton. Agents Multi Agent Syst.
Wanyuan Wang, Qian Che, Yifeng Zhou, Weiwei Wu, Bo An, Yichuan Jiang
2024 J jnl
IEEE Trans. Intell. Transp. Syst.
Wanyuan Wang, Haipeng Zhang, Tianchi Qiao, Jinming Ma, Jiahui Jin, Zhibin Li, Weiwei Wu, Yichuan Jiang
2024 A* conf
AAAI
Haoyang Chen, Peiyan Sun, Qiyuan Song, Wanyuan Wang, Weiwei Wu, Wencan Zhang, Guanyu Gao, Yan Lyu
2024 J jnl
CoRR
Haoyang Chen, Peiyan Sun, Qiyuan Song, Wanyuan Wang, Weiwei Wu, Wencan Zhang, Guanyu Gao, Yan Lyu
2023 conf
ChineseCSCW (2)
Yixuan Li, Qian Che, Fengchen Wang, Huiying Zhang, Wanyuan Wang, Yichuan Jiang
2023 J jnl
IEEE Trans. Mob. Comput.
Xiang Liu, Chenchen Fu, Weiwei Wu, Minming Li, Wanyuan Wang, Vincent Chau, Junzhou Luo
2023 J jnl
Theor. Comput. Sci.
Xiang Liu, Weiwei Wu, Wanyuan Wang, Yuhang Xu, Xiumin Wang, Helei Cui
2023 conf
MSN
Qian Che, Yixuan Li, Ziyao Peng, Wanyuan Wang, Yichuan Jiang
2023 conf
ChineseCSCW (2)
Yixuan Li, Qian Che, Yifeng Zhou, Wanyuan Wang, Yichuan Jiang
2023 J jnl
CoRR
Wanyuan Wang, Tianchi Qiao, Jinming Ma, Jiahui Jin, Zhibin Li, Weiwei Wu, Yichuan Jiang
2023 A conf
AAMAS
Qian Che, Wanyuan Wang, Fengchen Wang, Tianchi Qiao, Xiang Liu, Jiuchuan Jiang, Bo An, Yichuan Jiang
2022 Misc conf
FAW
Xiang Liu, Weiwei Wu, Wanyuan Wang, Yuhang Xu, Xiumin Wang, Helei Cui
2022 J jnl
IEEE Trans. Intell. Transp. Syst.
Wanyuan Wang, Hansi Tao, Yichuan Jiang
2022 conf
NCAA (2)
Bo Ling, Xiang Liu, Jin Jiang, Weiwei Wu, Wanyuan Wang, Yan Lyu, Xueyong Xu
2022 J jnl
IEEE Trans. Intell. Transp. Syst.
Yuhang Xu, Wanyuan Wang, Guangwei Xiong, Xiang Liu, Weiwei Wu, Kai Liu
2022 A conf
AAMAS
Wanyuan Wang, Gerong Wu, Weiwei Wu, Yichuan Jiang, Bo An
2021 A* conf
AAAI
Xiang Liu, Weiwei Wu, Minming Li, Wanyuan Wang
2021 J jnl
IEEE Trans. Serv. Comput.
Weiwei Wu, Wanyuan Wang, Xiaolin Fang, Junzhou Luo, Athanasios V. Vasilakos
2021 J jnl
IEEE Intell. Syst.
Bing Ai, Wanyuan Wang, Minghui Hua, Yichuan Jiang, Jiuchuan Jiang, Yifeng Zhou
2021 J jnl
IEEE Trans. Intell. Transp. Syst.
Wanyuan Wang, Zichen Dong, Bo An, Yichuan Jiang
2020 J jnl
IEEE Trans. Comput. Soc. Syst.
Wanyuan Wang, Bo An, Yichuan Jiang
2020 C conf
GPC
Yu Xia, Xueyong Xu, Wanyuan Wang, Xiujun He, Weiwei Wu, Xiaolin Fang
2020 conf
CBD
Tianxiang Zhang, Yuxin Bian, Qianchun Lu, Jin Qi, Kai Zhang, Hong Ji, Wanyuan Wang, Weiwei Wu
2020 A conf
AAMAS
Xiang Liu, Weiwei Wu, Minming Li, Wanyuan Wang
2019 J jnl
Knowl. Based Syst.
Peng Shi, Manyu Zhao, Wanyuan Wang, Yifeng Zhou, Jiuchuan Jiang, Jinyu Zhang, Yichuan Jiang, Zhifeng Hao
2019 A conf
AAMAS
Wanyuan Wang, Zichen Dong, Bo An, Yichuan Jiang
2019 J jnl
J. Intell. Robotic Syst.
Kai Di, Shaofu Yang, Wanyuan Wang, Fuhan Yan, Haokun Xing, Jiuchuan Jiang, Yichuan Jiang
2019 J jnl
Enterp. Inf. Syst.
Peng Shi, Wanyuan Wang, Yifeng Zhou, Jiuchuan Jiang, Yichuan Jiang, Zhifeng Hao, Jianyong Yu
2019 J jnl
IEEE Trans. Mob. Comput.
Wanyuan Wang, Zhanpeng He, Peng Shi, Weiwei Wu, Yichuan Jiang, Bo An, Zhifeng Hao, Bing Chen
2019 J jnl
IEEE Access
Yao Lu, Xinjun Mao, Tao Wang, Gang Yin, Zude Li, Wanyuan Wang
2018 A* conf
AAAI
Wanyuan Wang, Bo An, Yichuan Jiang
2017 J jnl
IEEE J. Sel. Areas Commun.
Weiwei Wu, Wanyuan Wang, Minming Li, Jianping Wang, Xiaolin Fang, Yichuan Jiang, Junzhou Luo
2017 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Wanyuan Wang, Yichuan Jiang, Weiwei Wu
2017 J jnl
IEEE Trans. Cybern.
Wanyuan Wang, Jiuchuan Jiang, Bo An, Yichuan Jiang, Bing Chen
2016 J jnl
J. Inf. Sci. Eng.
Yifeng Zhou, Fei Chao, Wanyuan Wang
2016 A conf
AAMAS
Wanyuan Wang, Zhanpeng He, Peng Shi, Weiwei Wu, Yichuan Jiang
2015 J jnl
IEEE Trans. Emerg. Top. Comput.
Wanyuan Wang, Yichuan Jiang
2014 B conf
ICTAI
Wanyuan Wang, Yichuan Jiang
2014 J jnl
IEEE Trans. Cybern.
Wanyuan Wang, Yichuan Jiang
2013 B conf
ICTAI
Wanyuan Wang, Yichuan Jiang
2013 J jnl
IEEE Trans. Parallel Distributed Syst.
Yichuan Jiang, Yifeng Zhou, Wanyuan Wang
tests/unit/test_database_exporters.py
← Index tests/unit/test_database_exporters.py python
"""
Unit tests for database exporters.
"""
import pytest
import json
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.unit, pytest.mark.exporters]


# ============================================================================
# Sample Dataclass for Testing
# ============================================================================

@dataclass
class SampleData:
    """Sample dataclass for export testing."""
    sha256: str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    name: str = "test_sample"
    value: int = 42
    _id: str = "test_id"


# ============================================================================
# PrintExporter Tests
# ============================================================================

class TestPrintExporter:
    """Tests for PrintExporter class."""

    def test_initialization(self, mock_logger):
        """Test PrintExporter initialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger

    def test_export_dataclass(self, mock_logger, capsys):
        """Test exporting a dataclass."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        sample = SampleData()

        result = exporter.export(sample)

        assert result is True
        captured = capsys.readouterr()
        assert "test_sample" in captured.out

    def test_export_list_of_dataclasses(self, mock_logger, capsys):
        """Test exporting a list of dataclasses."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        samples = [SampleData(name="sample1"), SampleData(name="sample2")]

        result = exporter.export(samples)

        assert result is True
        captured = capsys.readouterr()
        assert "sample1" in captured.out
        assert "sample2" in captured.out

    def test_export_dict(self, mock_logger, capsys):
        """Test exporting a dictionary."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {"key": "value", "number": 42}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "key" in captured.out
        assert "value" in captured.out

    def test_export_none(self, mock_logger):
        """Test exporting None."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export(None)

        assert result is True

    def test_export_empty_list(self, mock_logger):
        """Test exporting empty list."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export([])

        assert result is True


# ============================================================================
# ElasticsearchExporter Tests
# ============================================================================

class TestElasticsearchExporter:
    """Tests for ElasticsearchExporter class."""

    def test_initialization(self, mock_logger):
        """Test ElasticsearchExporter initialization."""
        with patch('redb.settings.get_elasticsearch_client') as mock_client:
            mock_client.return_value = Mock()
            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")

            assert exporter.index_prefix == "test_index"
            assert exporter.log is mock_logger
            assert exporter.client is not None

    def test_export_dataclass(self, mock_logger):
        """Test exporting a dataclass to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True
            mock_client.index.assert_called()

    def test_export_list(self, mock_logger):
        """Test exporting a list to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            samples = [SampleData(name="sample1"), SampleData(name="sample2")]

            result = exporter.export(
                samples,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": "test_hash"}
            )

            assert result is True
            # Should be called twice (once per sample)
            assert mock_client.index.call_count == 2

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_client.index.side_effect = Exception("Connection failed")
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is False
            mock_logger.error.assert_called()

    def test_export_with_custom_id(self, mock_logger):
        """Test exporting with custom _id field."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData(_id="custom_id")

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True


# ============================================================================
# ClickHouseExporter Tests
# ============================================================================

class TestClickHouseExporter:
    """Tests for ClickHouseExporter class."""

    def test_initialization(self, mock_logger):
        """Test ClickHouseExporter initialization."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger
        assert exporter.client is mock_client

    def test_export_tuple_data(self, mock_logger):
        """Test exporting tuple data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is True

    def test_export_multi_table(self, mock_logger):
        """Test exporting multi-table data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table1',
                    'data': [["hash123", "sample.exe"]],
                    'column_names': ["sha256", "name"],
                    'column_type_names': ["String", "String"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.side_effect = Exception("Connection failed")
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is False

    def test_export_missing_table(self, mock_logger):
        """Test export without table name raises error."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names)
                # Missing table parameter
            )

            assert result is False

    def test_get_client(self, mock_logger):
        """Test get_client method."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        result = exporter.get_client()

        assert result is mock_client

    def test_get_client_creates_new(self, mock_logger):
        """Test get_client creates new client if none exists."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_new_client = Mock()
            mock_create.return_value = mock_new_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            result = exporter.get_client()

            assert result is mock_new_client


# ============================================================================
# DatabaseExporter Abstract Base Class Tests
# ============================================================================

class TestDatabaseExporter:
    """Tests for DatabaseExporter abstract base class."""

    def test_cannot_instantiate_abstract(self):
        """Test that DatabaseExporter cannot be instantiated directly."""
        from redb.extractors.database_exporters import DatabaseExporter

        with pytest.raises(TypeError):
            DatabaseExporter()

    def test_subclass_must_implement_export(self):
        """Test that subclasses must implement export method."""
        from redb.extractors.database_exporters import DatabaseExporter

        # Define incomplete subclass
        class IncompleteExporter(DatabaseExporter):
            pass

        with pytest.raises(TypeError):
            IncompleteExporter()


# ============================================================================
# Null/Edge Case Tests
# ============================================================================

class TestExporterEdgeCases:
    """Tests for edge cases in exporters."""

    def test_print_exporter_with_complex_nested_data(self, mock_logger, capsys):
        """Test PrintExporter with complex nested data."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {
            "level1": {
                "level2": {
                    "level3": [1, 2, 3]
                }
            },
            "array": [{"a": 1}, {"b": 2}]
        }

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "level1" in captured.out

    def test_clickhouse_null_handling(self, mock_logger):
        """Test ClickHouse exporter handles null values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            # Multi-table data with null values
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [[None, "sample.exe", None]],
                    'column_names': ["sha256", "name", "size"],
                    'column_type_names': ["Nullable(String)", "String", "Nullable(UInt64)"]
                }
            }

            result = exporter.export(data)

            # Should handle nulls appropriately
            assert result is True

    def test_clickhouse_array_handling(self, mock_logger):
        """Test ClickHouse exporter handles array types."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", ["tag1", "tag2"]]],
                    'column_names': ["sha256", "tags"],
                    'column_type_names': ["String", "Array(String)"]
                }
            }

            result = exporter.export(data)

            assert result is True


# ============================================================================
# Type Conversion Tests
# ============================================================================

class TestExporterTypeConversions:
    """Tests for type conversions in exporters."""

    def test_clickhouse_datetime_handling(self, mock_logger):
        """Test ClickHouse exporter handles datetime values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            now = datetime.now(timezone.utc)
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", now]],
                    'column_names': ["sha256", "timestamp"],
                    'column_type_names': ["String", "DateTime64(3, 'UTC')"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_print_exporter_datetime_serialization(self, mock_logger, capsys):
        """Test PrintExporter handles datetime serialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        now = datetime.now(timezone.utc)
        data = {"timestamp": now, "name": "test"}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "timestamp" in captured.out


# ============================================================================
# Connection Context Manager Tests
# ============================================================================

class TestClickHouseConnectionManager:
    """Tests for ClickHouse connection context manager."""

    def test_clickhouse_connection_context(self, mock_logger):
        """Test clickhouse_connection context manager."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            with exporter.clickhouse_connection() as client:
                assert client is mock_client

            # Client should be closed after context exits
            mock_client.close.assert_called()

    def test_clickhouse_connection_close_on_error(self, mock_logger):
        """Test client is closed even if operation fails."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            try:
                with exporter.clickhouse_connection() as client:
                    raise ValueError("Test error")
            except ValueError:
                pass

            # Client should still be closed
            mock_client.close.assert_called()