Kaiming Shen

119 papers A* 2A 1B 11Misc 11Journal 81Unranked 13
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Jianhang Zhu, Tsung-Hui Chang, Liyao Xiang, Kaiming Shen
2026 J jnl
IEEE Trans. Commun.
Jianhang Zhu, Tsung-Hui Chang, Liyao Xiang, Kaiming Shen
2026 J jnl
CoRR
Minhao Zhu, Kaiming Shen
2026 J jnl
IEEE Trans. Commun.
Wenhai Lai, Kaiming Shen, Rui Zhang
2026 J jnl
IEEE Trans. Signal Process.
Wenyu Wang, Kaiming Shen
2025 J jnl
CoRR
Mingxiao Li, Kaiming Shen, Shuguang Cui
2025 J jnl
IEEE Internet Things J.
Mingxiao Li, Kaiming Shen, Shuguang Cui
2025 J jnl
IEEE Trans. Mob. Comput.
Wenhai Lai, Wenyu Wang, Fan Xu, Xin Li, Shaobo Niu, Kaiming Shen
2025 J jnl
CoRR
Wenhai Lai, Jiawei Yao, Kaiming Shen
2025 J jnl
IEEE Wirel. Commun. Lett.
Wenhai Lai, Jiawei Yao, Kaiming Shen
2025 J jnl
IEEE Wirel. Commun. Lett.
Xiaomei Luo, Yineng Liu, Fan Xu, Xiaoyang Li, Guangxu Zhu, Kaiming Shen
2025 conf
SPAWC
Jianhang Zhu, Tsung-Hui Chang, Liyao Xiang, Kaiming Shen
2025 J jnl
Trans. Recomm. Syst.
Youru Li, Zhenfeng Zhu, Shaohu Chen, Kaiming Shen, Xingxing Zhang, Wenliang Zhong, Yao Zhao
2025 J jnl
CoRR
Wenhai Lai, Kaiming Shen, Zhi-Quan Luo
2025 J jnl
IEEE Trans. Wirel. Commun.
Yannan Chen, Yi Feng, Xiaoyang Li, Licheng Zhao, Kaiming Shen
2025 J jnl
CoRR
Yi Feng, Kaiming Shen
2025 J jnl
CoRR
Wenhai Lai, Kaiming Shen, Rui Zhang
2025 J jnl
CoRR
Wenyu Wang, Kaiming Shen
2025 J jnl
CoRR
Fan Xu, Wenhai Lai, Kaiming Shen
2025 J jnl
IEEE Wirel. Commun. Lett.
Fan Xu, Wenhai Lai, Kaiming Shen
2025 J jnl
CoRR
Kaiming Shen, Wei Yu
2025 J jnl
IEEE Signal Process. Mag.
Kaiming Shen, Wei Yu
2025 J jnl
CoRR
Fupei Chen, Liyao Xiang, Haoxiang Sun, Hei Victor Cheng, Kaiming Shen
2025 J jnl
IEEE Trans. Inf. Forensics Secur.
Fupei Chen, Liyao Xiang, Haoxiang Sun, Hei Victor Cheng, Kaiming Shen
2025 conf
SPAWC
Wenhai Lai, Kaiming Shen, Zhi-Quan Luo
2024 B conf
ISIT
Kaiming Shen, Ziping Zhao, Yannan Chen, Zepeng Zhang, Hei Victor Cheng
2024 J jnl
IEEE J. Sel. Areas Commun.
Kaiming Shen, Ziping Zhao, Yannan Chen, Zepeng Zhang, Hei Victor Cheng
2024 Misc conf
ICASSP
Shuyi Ren, Beichen Huang, Xiaoyang Li, Kaiming Shen
2024 J jnl
CoRR
Wenhai Lai, Zheyu Wu, Yi Feng, Kaiming Shen, Ya-Feng Liu
2024 J jnl
IEEE Signal Process. Lett.
Wenhai Lai, Zheyu Wu, Yi Feng, Kaiming Shen, Ya-Feng Liu
2024 J jnl
IEEE Trans. Wirel. Commun.
Fan Xu, Jiawei Yao, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2024 J jnl
CoRR
Fan Xu, Jiawei Yao, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2024 Misc conf
ICASSP
Wenhai Lai, Kaiming Shen
2024 Misc conf
ICASSP
Mingxiao Li, Rui Jin, Liyao Xiang, Kaiming Shen, Shuguang Cui
2024 J jnl
IEEE Trans. Signal Process.
Fan Xu, Jiawei Yao, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2024 J jnl
CoRR
Sicong Xie, Qunwei Li, Weidi Xu, Kaiming Shen, Shaohu Chen, Wenliang Zhong
2024 conf
WCSP
Yannan Chen, Yi Feng, Xiaoyang Li, Licheng Zhao, Kaiming Shen
2024 J jnl
CoRR
Yannan Chen, Yi Feng, Xiaoyang Li, Licheng Zhao, Kaiming Shen
2024 J jnl
Proc. IEEE
Qingqing Wu, Beixiong Zheng, Changsheng You, Lipeng Zhu, Kaiming Shen, Xiaodan Shao, Weidong Mei, Boya Di, Hongliang Zhang, Ertugrul Basar, Lingyang Song, Marco Di Renzo, Zhi-Quan Luo, Rui Zhang
2024 J jnl
IEEE Trans. Signal Process.
Yannan Chen, Licheng Zhao, Kaiming Shen
2024 A* conf
NeurIPS
Yannan Chen, Beichen Huang, Licheng Zhao, Kaiming Shen
2024 J jnl
CoRR
Wenyu Wang, Minhao Zhu, Kaiming Shen, Zhaorui Wang, Shuguang Cui
2024 J jnl
IEEE Commun. Lett.
Wenyu Wang, Minhao Zhu, Kaiming Shen, Zhaorui Wang, Shuguang Cui
2024 J jnl
CoRR
Kaiming Shen, Xichen Ding, Zixiang Zheng, Yuqi Gong, Qianqian Li, Zhongyi Liu, Guannan Zhang
2024 J jnl
IEEE Wirel. Commun. Lett.
Xiaomei Luo, Zhuochen Jiang, Fan Xu, Xiaoyang Li, Guangxu Zhu, Kaiming Shen
2023 J jnl
IEEE Wirel. Commun. Lett.
Shuyi Ren, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2023 B conf
PIMRC
Wenyu Wang, Wenhai Lai, Shuyi Ren, Liyao Xiang, Xin Li, Shaobo Niu, Kaiming Shen
2023 A conf
CIKM
Yuqi Gong, Xichen Ding, Yehui Su, Kaiming Shen, Zhongyi Liu, Guannan Zhang
2023 J jnl
CoRR
Yuqi Gong, Xichen Ding, Yehui Su, Kaiming Shen, Zhongyi Liu, Guannan Zhang
2023 J jnl
CoRR
Wenhai Lai, Wenyu Wang, Fan Xu, Xin Li, Shaobo Niu, Kaiming Shen
2023 conf
ICC
Jiawei Yao, Fan Xu, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2023 conf
SPAWC
Fan Xu, Jiawei Yao, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2023 J jnl
IEEE Trans. Wirel. Commun.
Shuyi Ren, Kaiming Shen, Yaowen Zhang, Xin Li, Xin Chen, Zhi-Quan Luo
2023 J jnl
CoRR
Fan Xu, Jiawei Yao, Wenhai Lai, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2023 J jnl
CoRR
Mingxiao Li, Rui Jin, Liyao Xiang, Kaiming Shen, Shuguang Cui
2023 B conf
GLOBECOM
Fupei Chen, Liyao Xiang, Hei Victor Cheng, Kaiming Shen
2023 J jnl
CoRR
Zepeng Zhang, Ziping Zhao, Kaiming Shen, Daniel P. Palomar, Wei Yu
2023 J jnl
IEEE Trans. Wirel. Commun.
Xiaoyang Li, Guangxu Zhu, Kaiming Shen, Kaifeng Han, Kaibin Huang, Yi Gong
2023 Misc conf
ICASSP
Zepeng Zhang, Ziping Zhao, Kaiming Shen
2023 J jnl
CoRR
Qingqing Wu, Beixiong Zheng, Changsheng You, Lipeng Zhu, Kaiming Shen, Xiaodan Shao, Weidong Mei, Boya Di, Hongliang Zhang, Ertugrul Basar, Lingyang Song, Marco Di Renzo, Zhi-Quan Luo, Rui Zhang
2023 Misc conf
ICASSP
Yannan Chen, Licheng Zhao, Yaowen Zhang, Kaiming Shen
2023 conf
SPAWC
Yannan Chen, Licheng Zhao, Kaiming Shen
2023 J jnl
CoRR
Yannan Chen, Licheng Zhao, Kaiming Shen
2023 J jnl
CoRR
Kaiming Shen, Ziping Zhao, Yannan Chen, Zepeng Zhang, Hei Victor Cheng
2022 J jnl
CoRR
Dmitry Rybin, Shuyi Ren, Kaiming Shen, Xin Li, Xin Chen, Zhi-Quan Luo
2022 conf
SPAWC
Wenyu Wang, Kaiming Shen
2022 J jnl
IEEE J. Sel. Top. Signal Process.
Yaowen Zhang, Kaiming Shen, Shuyi Ren, Xin Li, Xin Chen, Zhi-Quan Luo
2022 A* conf
SIGIR
Sicong Xie, Qunwei Li, Weidi Xu, Kaiming Shen, Shaohu Chen, Wenliang Zhong
2022 J jnl
CoRR
Kaiming Shen, Wei Yu, Xihan Chen, Saeed R. Khosravirad
2022 J jnl
IEEE Trans. Wirel. Commun.
Kaiming Shen, Wei Yu, Xihan Chen, Saeed R. Khosravirad
2022 J jnl
CoRR
Wei Guo, Ran Li, Chuan Huang, Xiaoqi Qin, Kaiming Shen, Wei Zhang
2022 J jnl
IEEE J. Sel. Areas Commun.
Wei Guo, Ran Li, Chuan Huang, Xiaoqi Qin, Kaiming Shen, Wei Zhang
2022 B conf
GLOBECOM
Wei Guo, Ran Li, Chuan Huang, Xiaoqi Qin, Kaiming Shen, Wei Zhang
2021 J jnl
IEEE Trans. Inf. Theory
Kaiming Shen, Reza Khosravi-Farsani, Wei Yu
2021 J jnl
CoRR
Shuyi Ren, Kaiming Shen, Yaowen Zhang, Xin Li, Xin Chen, Zhi-Quan Luo
2021 J jnl
CoRR
Yaowen Zhang, Kaiming Shen, Shuyi Ren, Xin Li, Xin Chen, Zhi-Quan Luo
2021 J jnl
Frontiers Commun. Networks
Hayssam Dahrouj, Ahmed Douik, Mohammed El-Hajjar, Megumi Kaneko, Yonghui Li, Duy T. Ngo, Mohamed Saad, Kaiming Shen, Jun Zhang
2021 B conf
GLOBECOM
Yaowen Zhang, Shuyi Ren, Kaiming Shen, Zhi-Quan Luo
2021 conf
ICC Workshops
Kaiming Shen, Xihan Chen, Wei Yu, Saeed R. Khosravirad
2020 Misc conf
ICASSP
Wei Cui, Kaiming Shen, Wei Yu
2020 B conf
WCNC
Hualian Sheng, Xihan Chen, Kaiming Shen, Xiongfei Zhai, An Liu, Min-Jian Zhao
2020 J jnl
IEEE Trans. Commun.
Kaiming Shen, Hei Victor Cheng, Xihan Chen, Yonina C. Eldar, Wei Yu
2020 J jnl
IEEE Trans. Wirel. Commun.
Xiaoyang Li, Guangxu Zhu, Kaiming Shen, Wei Yu, Yi Gong, Kaibin Huang
2020 J jnl
IEEE Wirel. Commun. Lett.
Xihan Chen, Hei Victor Cheng, An Liu, Kaiming Shen, Min-Jian Zhao
2020 J jnl
IEEE Commun. Lett.
Xihan Chen, Kaiming Shen, Hei Victor Cheng, An Liu, Wei Yu, Min-Jian Zhao
2020 Misc conf
ICASSP
Xiaoyang Li, Guangxu Zhu, Kaiming Shen, Yi Gong, Kaibin Huang
2020 J jnl
CoRR
Xihan Chen, Hei Victor Cheng, Kaiming Shen, An Liu, Min-Jian Zhao
2020 J jnl
IEEE Internet Things J.
Xihan Chen, Hei Victor Cheng, Kaiming Shen, An Liu, Min-Jian Zhao
2019 B conf
ISIT
Kaiming Shen, Reza Khosravi-Farsani, Wei Yu
2019 J jnl
CoRR
Kaiming Shen, Reza Khosravi-Farsani, Wei Yu
2019 J jnl
CoRR
Kaiming Shen, Hei Victor Cheng, Yonina C. Eldar, Wei Yu
2019 Misc conf
ICASSP
Kaiming Shen, Yonina C. Eldar, Wei Yu
2019 B conf
GLOBECOM
Xihan Chen, An Liu, Wei Yu, Hei Victor Cheng, Kaiming Shen, Min-Jian Zhao
2019 J jnl
CoRR
Xiaoyang Li, Guangxu Zhu, Kaiming Shen, Wei Yu, Yi Gong, Kaibin Huang
2019 J jnl
CoRR
Xihan Chen, Hei Victor Cheng, An Liu, Kaiming Shen, Min-Jian Zhao
2019 J jnl
IEEE/ACM Trans. Netw.
Kaiming Shen, Wei Yu, Licheng Zhao, Daniel P. Palomar
2019 J jnl
CoRR
Xihan Chen, Kaiming Shen, Hei Victor Cheng, An Liu, Wei Yu, Min-Jian Zhao
2019 conf
SPAWC
Alaa Alameer Ahmad, Jaber Kakar, Hayssam Dahrouj, Anas Chaaban, Kaiming Shen, Aydin Sezgin, Tareq Y. Al-Naffouri, Mohamed-Slim Alouini
2019 J jnl
IEEE J. Sel. Areas Commun.
Wei Cui, Kaiming Shen, Wei Yu
2019 conf
GLOBECOM Workshops
Kaiming Shen, Saeed R. Khosravirad, Wei Yu
2019 conf
SPAWC
Kaiming Shen, Wei Yu, Saeed R. Khosravirad
2018 B conf
ITW
Kaiming Shen, Reza Khosravi-Farsani, Wei Yu
2018 J jnl
CoRR
Kaiming Shen, Wei Yu, Licheng Zhao, Daniel P. Palomar
2018 J jnl
IEEE Trans. Signal Process.
Kaiming Shen, Wei Yu
2018 J jnl
IEEE Trans. Signal Process.
Kaiming Shen, Wei Yu
2018 J jnl
CoRR
Kaiming Shen, Wei Yu
2018 J jnl
CoRR
Kaiming Shen, Wei Yu
2018 conf
VTC Spring
Kaiming Shen, Wei Yu
2018 B conf
GLOBECOM
Wei Cui, Kaiming Shen, Wei Yu
2018 J jnl
CoRR
Wei Cui, Kaiming Shen, Wei Yu
2017 B conf
ISIT
Kaiming Shen, Wei Yu
2017 J jnl
CoRR
Kaiming Shen, Ya-Feng Liu, David Yiwei Ding, Wei Yu
2017 J jnl
IEEE Signal Process. Lett.
Kaiming Shen, Ya-Feng Liu, David Yiwei Ding, Wei Yu
2016 Misc conf
ICASSP
Kaiming Shen, Wei Yu
2016 conf
SPAWC
Kaiming Shen, Wei Yu
2015 Misc conf
ACSSC
Kaiming Shen, Wei Yu
2014 J jnl
CoRR
Kaiming Shen, Wei Yu
2014 J jnl
IEEE J. Sel. Areas Commun.
Kaiming Shen, Wei Yu
2013 Misc conf
ICASSP
Kaiming Shen, Wei Yu
tests/unit/test_apk_cfg_features.py
← Index tests/unit/test_apk_cfg_features.py python
"""
Unit tests for APK CFG feature parity with the Binary Ninja pipeline.

Tests advanced CFG features computed from smali (topology hash, MD-index,
WL-MinHash, prime product, packed adjacency, block features export) and
the slimmed similarity table.

All tests use mocked smali input — no JADX/apktool/Java required.
"""
import pytest

from redb.extractors.decompiler.apk.smali_cfg import (
    SmaliCFGMetrics,
    compute_cfg_metrics,
)
from redb.extractors.decompiler.apk.method_extractor import (
    SMALI_OP_PRIMES,
    compute_prime_product_smali,
    count_call_instructions,
)

pytestmark = [pytest.mark.unit, pytest.mark.apk, pytest.mark.decompile]


# ===================================================================
# Sample smali bodies for testing
# ===================================================================

# Simple linear method: 3 instructions, 1 block
SMALI_LINEAR = """\
    const/4 v0, 0x0
    invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
    return-void
"""

# Diamond CFG: if-else with two paths merging
SMALI_DIAMOND = """\
    const/4 v0, 0x1
    if-eqz v0, :cond_0
    invoke-virtual {p0}, Lcom/Foo;->pathA()V
    goto :goto_0
    :cond_0
    invoke-virtual {p0}, Lcom/Foo;->pathB()V
    :goto_0
    return-void
"""

# Loop: a back edge from goto to a label before it
SMALI_LOOP = """\
    const/4 v0, 0x0
    :loop_start
    add-int/lit8 v0, v0, 0x1
    if-lt v0, v1, :loop_start
    return-void
"""

# Multi-block with several invoke calls
SMALI_MULTI_CALL = """\
    invoke-virtual {p0}, Lcom/Foo;->a()V
    invoke-static {v0}, Lcom/Bar;->b(I)V
    invoke-direct {p0, v1}, Lcom/Baz;-><init>(I)V
    const/4 v0, 0x0
    return-void
"""


# ===================================================================
# TestSmaliCFGMetricsAdvanced — new fields in SmaliCFGMetrics
# ===================================================================

class TestSmaliCFGMetricsAdvanced:
    """Test that advanced CFG fields are populated by compute_cfg_metrics."""

    def test_topology_hash_is_bytes(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert isinstance(m.cfg_topology_hash, bytes)
        assert len(m.cfg_topology_hash) == 16

    def test_topology_hash_nonzero_for_multiblock(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.cfg_topology_hash != b'\x00' * 16

    def test_topology_hash_zero_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.cfg_topology_hash == b'\x00' * 16

    def test_identical_cfg_same_topology_hash(self):
        """Two smali methods with the same CFG structure produce the same hash."""
        smali_a = """\
    const/4 v0, 0x1
    if-eqz v0, :cond_0
    const/4 v1, 0x2
    goto :goto_0
    :cond_0
    const/4 v1, 0x3
    :goto_0
    return-void
"""
        smali_b = """\
    const/4 v5, 0x9
    if-nez v5, :cond_0
    add-int v6, v5, v5
    goto :goto_0
    :cond_0
    sub-int v6, v5, v5
    :goto_0
    return-void
"""
        m_a = compute_cfg_metrics(smali_a)
        m_b = compute_cfg_metrics(smali_b)
        assert m_a.cfg_topology_hash == m_b.cfg_topology_hash

    def test_different_cfg_different_topology_hash(self):
        m_linear = compute_cfg_metrics(SMALI_LINEAR)
        m_diamond = compute_cfg_metrics(SMALI_DIAMOND)
        assert m_linear.cfg_topology_hash != m_diamond.cfg_topology_hash

    def test_md_index_topdown_nonzero(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.md_index_topdown != 0

    def test_md_index_bottomup_nonzero(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert m.md_index_bottomup != 0

    def test_md_index_zero_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.md_index_topdown == 0
        assert m.md_index_bottomup == 0

    def test_wl_minhash_length(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.wl_minhash) == 128

    def test_wl_minhash_sentinel_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.wl_minhash == [255] * 128

    def test_wl_minhash_values_are_uint8(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        for val in m.wl_minhash:
            assert 0 <= val <= 255

    def test_cfg_adjacency_nonempty_for_multiblock(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.cfg_adjacency) > 0

    def test_cfg_adjacency_empty_for_empty(self):
        m = compute_cfg_metrics("")
        assert m.cfg_adjacency == []

    def test_cfg_adjacency_packed_format(self):
        """Each entry should be (src << 16) | tgt."""
        m = compute_cfg_metrics(SMALI_DIAMOND)
        for edge in m.cfg_adjacency:
            assert isinstance(edge, int)
            src = edge >> 16
            tgt = edge & 0xFFFF
            assert src < m.block_count
            assert tgt < m.block_count

    def test_block_features_exported(self):
        m = compute_cfg_metrics(SMALI_DIAMOND)
        assert len(m.block_features) == m.block_count
        for bf in m.block_features:
            assert len(bf) == 8  # 7 categories + successor_count

    def test_cfg_feature_tlsh_none_for_small(self):
        """Small methods produce None (< 50 bytes of feature data)."""
        m = compute_cfg_metrics(SMALI_LINEAR)
        # Single-block linear method — too small for TLSH
        assert m.cfg_feature_tlsh is None

    def test_loop_count_with_back_edge(self):
        m = compute_cfg_metrics(SMALI_LOOP)
        assert m.loop_count >= 1


# ===================================================================
# TestPrimeProductSmali
# ===================================================================

class TestPrimeProductSmali:

    def test_empty_returns_zero(self):
        assert compute_prime_product_smali("") == 0

    def test_none_returns_zero(self):
        assert compute_prime_product_smali(None) == 0

    def test_known_computation(self):
        """Single invoke instruction → CALL category → prime 17."""
        smali = "    invoke-virtual {p0}, Lcom/Foo;->bar()V"
        assert compute_prime_product_smali(smali) == 17

    def test_two_instructions(self):
        """const (CONST→2) * invoke (CALL→17) = 34."""
        smali = """\
    const/4 v0, 0x0
    invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
"""
        assert compute_prime_product_smali(smali) == 2 * 17

    def test_skips_directives_and_labels(self):
        """Directives, labels, and comments should be skipped."""
        smali = """\
.registers 2
.line 10
    :label
    # comment
    const/4 v0, 0x0
"""
        # Only const/4 → CONST → prime 2
        assert compute_prime_product_smali(smali) == 2

    def test_position_independent(self):
        """Reordering instructions produces the same product (multiplication is commutative)."""
        smali_a = """\
    add-int v0, v1, v2
    invoke-virtual {p0}, Lcom/Foo;->bar()V
"""
        smali_b = """\
    invoke-virtual {p0}, Lcom/Foo;->bar()V
    add-int v0, v1, v2
"""
        assert compute_prime_product_smali(smali_a) == compute_prime_product_smali(smali_b)

    def test_all_categories_have_primes(self):
        """Every category in SMALI_OP_PRIMES is a positive integer."""
        for cat, prime in SMALI_OP_PRIMES.items():
            assert isinstance(prime, int)
            assert prime >= 1

    def test_mod_2_64(self):
        """Result should be mod 2^64 (doesn't overflow)."""
        # A very long method — product stays within uint64
        smali = "\n".join(["    mul-int v0, v1, v2"] * 1000)
        result = compute_prime_product_smali(smali)
        assert 0 <= result < 2**64


# ===================================================================
# TestCallCount
# ===================================================================

class TestCallCount:

    def test_empty(self):
        assert count_call_instructions("") == 0

    def test_none(self):
        assert count_call_instructions(None) == 0

    def test_single_invoke(self):
        smali = "    invoke-virtual {p0}, Lcom/Foo;->bar()V"
        assert count_call_instructions(smali) == 1

    def test_multiple_invoke_types(self):
        assert count_call_instructions(SMALI_MULTI_CALL) == 3

    def test_non_invoke_not_counted(self):
        smali = """\
    const/4 v0, 0x0
    add-int v1, v0, v0
    return-void
"""
        assert count_call_instructions(smali) == 0


# ===================================================================
# TestSimilarityTableSlimmed
# ===================================================================

class TestSimilarityTableSlimmed:
    """Verify the similarity table no longer contains moved fields."""

    def test_export_similarity_no_block_count(self):
        """block_count should not be in similarity export columns."""
        from redb.extractors.decompiler.DecompileAPK import DecompileAPK
        from unittest.mock import MagicMock

        extractor = DecompileAPK.__new__(DecompileAPK)
        extractor.log = MagicMock()
        extractor.sha256 = "a" * 64
        extractor.sha1 = "b" * 40
        extractor.md5 = "c" * 32
        extractor.analysis_results = {
            "sha256": "a" * 64,
            "sha1": "b" * 40,
            "md5": "c" * 32,
            "similarity_metrics": [{
                "smali_method_hash": "d" * 64,
                "cyclomatic_complexity": 3,
                "ssdeep_smali": None,
                "tlsh_smali": None,
                "minhash": [1, 2, 3],
            }],
        }

        export = extractor.prepare_export_data("ClickHouseExporter")
        sim_cols = export["method_similarity_metrics"]["column_names"]
        assert "block_count" not in sim_cols
        assert "edge_count" not in sim_cols
        assert "loop_count" not in sim_cols
        assert "max_depth" not in sim_cols
        assert "max_fan_out" not in sim_cols
        # These should still be there
        assert "smali_method_hash" in sim_cols
        assert "ssdeep_smali" in sim_cols
        assert "minhash" in sim_cols
        # cyclomatic_complexity moved to cfg table
        assert "cyclomatic_complexity" not in sim_cols


# ===================================================================
# TestCFGTableExport
# ===================================================================

class TestCFGTableExport:
    """Verify the new CFG table is exported correctly."""

    def test_export_cfg_table_present(self):
        from redb.extractors.decompiler.DecompileAPK import DecompileAPK
        from unittest.mock import MagicMock

        extractor = DecompileAPK.__new__(DecompileAPK)
        extractor.log = MagicMock()
        extractor.analysis_results = {
            "sha256": "a" * 64,
            "sha1": "b" * 40,
            "md5": "c" * 32,
            "cfg": [{
                "smali_method_hash": "d" * 64,
                "cfg_topology_hash": b'\x01' * 16,
                "block_count": 4,
                "edge_count": 5,
                "instructions_count": 20,
                "call_count": 3,
                "cyclomatic_complexity": 3,
                "loop_count": 1,
                "max_depth": 2,
                "max_fan_out": 2,
                "md_index_topdown": 12345,
                "md_index_bottomup": 67890,
                "prime_product_smali": 999,
                "cfg_feature_tlsh": None,
                "wl_minhash": [0] * 128,
                "bb_features": [[10, 1, 0, 2, 1, 0, 0, 2]] * 4,
                "cfg_adjacency": [0x00010000, 0x00010002],
            }],
        }

        export = extractor.prepare_export_data("ClickHouseExporter")
        assert "cfg_methods" in export
        cfg_export = export["cfg_methods"]
        assert cfg_export["table"] == "code_apk_cfg_methods"
        assert len(cfg_export["data"]) == 1
        assert "cfg_topology_hash" in cfg_export["column_names"]
        assert "prime_product_smali" in cfg_export["column_names"]
        assert "wl_minhash" in cfg_export["column_names"]
        assert "bb_features" in cfg_export["column_names"]
        assert "cfg_adjacency" in cfg_export["column_names"]
        # Verify column count matches data width
        assert len(cfg_export["column_names"]) == len(cfg_export["data"][0])
        assert len(cfg_export["column_type_names"]) == len(cfg_export["data"][0])