Omar Boussaid

134 papers A* 1A 2B 11C 20Misc 2Journal 44Unranked 50
YearRankTypeTitle / Venue / Authors
2025 J jnl
Computing
Ryma Messaouda Amara, Nacer Eddine Zarour, Omar Boussaid
2023 C conf
DOLAP
Redha Benhissen, Fadila Bentayeb, Omar Boussaid
2022 J jnl
Parallel Comput.
Yassine Ramdane, Omar Boussaid, Doulkifli Boukraâ, Nadia Kabachi, Fadila Bentayeb
2022 conf
EDA
Redha Benhissen, Fadila Bentayeb, Omar Boussaid
2021 J jnl
Int. J. Inf. Technol. Web Eng.
Kamel Ahsene Djaballah, Kamel Boukhalfa, Omar Boussaid, Yassine Ramdane
2021 conf
DEXA (1)
Mohamed Walid Zeghdaoui, Omar Boussaid, Fadila Bentayeb, Frederik Joly
2021 conf
EDA
Thinhinane Hamitouche, Omar Boussaid, Fadila Bentayeb
2020 J jnl
Int. J. Decis. Support Syst. Technol.
Khaled Dehdouh, Omar Boussaid, Fadila Bentayeb
2020 conf
ADBIS/TPDL/EDA Workshops
Ladjel Bellatreche, Fadila Bentayeb, Mária Bieliková, Omar Boussaid, Barbara Catania, Paolo Ceravolo, Elena Demidova, Mírian Halfeld Ferrari, María Teresa Gómez-López, Carmem S. Hara, Slavica Kordic, Ivan Lukovic, Andrea Mannocci, Paolo Manghi, Francesco Osborne, Christos Papatheodorou, Sonja Ristic, Dimitris Sacharidis, Oscar Romero, Angelo A. Salatino, Guilaine Talens, Maurice van Keulen, Thanasis Vergoulis, Maja Zumer
2020 J jnl
Clust. Comput.
Sami Belkacem, Kamel Boukhalfa, Omar Boussaid
2020 J jnl
Int. J. Inf. Technol. Decis. Mak.
Fatima Zohra Younsi, Ahmed Bounekkar, Djamila Hamdadou, Omar Boussaid
2020 conf
EGC
Sami Belkacem, Omar Boussaid, Kamel Boukhalfa
2020 J jnl
Int. J. Semantic Web Inf. Syst.
Saida Kichou, Omar Boussaid, Abdelkrim Meziane
2019 conf
EGC (best of volume)
Yassine Ramdane, Nadia Kabachi, Omar Boussaid, Fadila Bentayeb
2019 conf
EGC
Yassine Ramdane, Omar Boussaid, Nadia Kabachi, Fadila Bentayeb
2019 J jnl
Int. J. Data Warehous. Min.
Sandro Bimonte, Omar Boussaid, Michel Schneider, Fabien Ruelle
2019 conf
SNAMS
Zakia Challal, Wafaa Bala, Hanifa Mokeddem, Kamel Boukhalfa, Omar Boussaid, Elhadj Benkhelifa
2019 J jnl
Int. J. Inf. Technol. Decis. Mak.
Fatima Zohra Younsi, Ahmed Bounekkar, Djamila Hamdadou, Omar Boussaid
2019 B conf
DaWaK
Yassine Ramdane, Nadia Kabachi, Omar Boussaid, Fadila Bentayeb
2019 conf
EDA
Yassine Ramdane, Nadia Kabachi, Omar Boussaid, Fadila Bentayeb
2019 conf
SNAMS
Kamel Ahsene Djaballah, Kamel Boukhalfa, Omar Boussaid
2019 A conf
ER
Yassine Ramdane, Nadia Kabachi, Omar Boussaid, Fadila Bentayeb
2018 conf
EDA
Mohamed Boussahoua, Fadila Bentayeb, Omar Boussaid, Nadia Kabachi
2018 conf
EDA
Sami Belkacem, Kamel Boukhalfa, Omar Boussaid
2018 J jnl
Int. J. Data Warehous. Min.
Rado Ratsimbazafy, Omar Boussaid
2018 B conf
ICPADS
Yassine Ramdane, Omar Boussaid, Nadia Kabachi, Fadila Bentayeb
2018 conf
EDA
Mohamed Walid Zeghdaoui, Frederik Joly, Omar Boussaid, Fadila Bentayeb
2018 J jnl
Int. J. Math. Model. Numer. Optimisation
Sarah Attaf, Nadjia Benblidia, Omar Boussaid
2017 J jnl
Data Knowl. Eng.
Mahfoud Bala, Omar Boussaid, Zaia Alimazighi
2017 conf
DEXA (2)
Mohamed Boussahoua, Omar Boussaid, Fadila Bentayeb
2017 conf
DEXA (2)
Zakia Challal, Omar Boussaid, Kamel Boukhalfa
2017 conf
EGC
Mohamed Boussahoua, Omar Boussaid
2017 B conf
DaWaK
Rado Ratsimbazafy, Omar Boussaid, Fadila Bentayeb
2017 conf
EDA
Sami Belkacem, Kamel Boukhalfa, Omar Boussaid
2016 J jnl
Int. J. Inf. Comput. Secur.
Yasmina Ghebghoub, Saliha Oukid, Omar Boussaid
2016 conf
EDA
Sarah Attaf, Nadjia Benblidia, Omar Boussaid
2016 J jnl
Int. J. Data Warehous. Min.
Sandro Bimonte, Michel Schneider, Omar Boussaid
2016 J jnl
Int. J. Decis. Support Syst. Technol.
Mahfoud Bala, Omar Boussaid, Zaia Alimazighi
2016 B conf
WI
Saida Kichou, Hakima Mellah, Omar Boussaid, Abdelkrim Meziane
2016 conf
EDA
Rado Ratsimbazafy, Fadila Bentayeb, Omar Boussaid
2016 J jnl
Int. J. Data Warehous. Min.
Lamia Oukid, Omar Boussaid, Nadjia Benblidia, Fadila Bentayeb
2015 C conf
IDEAS
Billel Arres, Nadia Kabachi, Omar Boussaid, Fadila Bentayeb
2015 J jnl
Int. J. Data Warehous. Min.
Lamia Oukid, Nadjia Benblidia, Fadila Bentayeb, Ounas Asfari, Omar Boussaid
2015 J jnl
J. Inf. Knowl. Manag.
Amina Madani, Omar Boussaid, Djamel Eddine Zegour
2015 C conf
PDP
Billel Arres, Nadia Kabachi, Omar Boussaid
2015 J jnl
Soc. Netw. Anal. Min.
Amina Madani, Omar Boussaid, Djamel Eddine Zegour
2015 J jnl
Int. J. Metadata Semant. Ontologies
Messaouda Fareh, Omar Boussaid, Rachid Chalal
2015 conf
EGC
Mahfoud Bala, Oussama Mokeddem, Omar Boussaid, Zaia Alimazighi
2014 J jnl
J. Digit. Inf. Manag.
Zoubir Ouaret, Rachid Chalal, Omar Boussaid
2014 C conf
ISMIS
Sid-Ali Selmane, Fadila Bentayeb, Rokia Missaoui, Omar Boussaid
2014 C conf
MEDI
Khaled Dehdouh, Omar Boussaid, Fadila Bentayeb
2014 J jnl
Fundam. Informaticae
Doulkifli Boukraâ, Omar Boussaid, Fadila Bentayeb
2014 C conf
ADBIS
Sid-Ali Selmane, Omar Boussaid, Fadila Bentayeb
2014 conf
ISDOC
Yasmina Ghebghoub, Omar Boussaid, Saliha Oukid
2014 C conf
MEDI
Sarah Attaf, Nadjia Benblidia, Omar Boussaid
2014 B conf
DaWaK
Khaled Dehdouh, Fadila Bentayeb, Omar Boussaid, Nadia Kabachi
2013 J jnl
Int. J. Inf. Coding Theory
Zoubir Ouaret, Rachid Chalal, Omar Boussaid
2013 C conf
AICCSA
Billel Arres, Nadia Kabachi, Omar Boussaid
2013 C conf
DOLAP
Lamia Oukid, Ounas Asfari, Fadila Bentayeb, Nadjia Benblidia, Omar Boussaid
2013 J jnl
Int. J. Intell. Inf. Database Syst.
Hacène Derrar, Mohamed Ahmed-Nacer, Omar Boussaid
2013 ch.
Modeling Approaches and Algorithms for Advanced Computer Applications
Messaouda Fareh, Omar Boussaid, Rachid Chalal
2013 J jnl
Int. J. Metadata Semant. Ontologies
Messaouda Fareh, Omar Boussaid, Rachid Chalal, Melyara Mezzi, Khadija Nadji
2013 C conf
AICCSA
Messaouda Fareh, Omar Boussaid, Rachid Chalal
2013 B conf
KES
Amina Madani, Omar Boussaid, Djamel Eddine Zegour
2013 C conf
DOLAP
Lilia Hannachi, Nadjia Benblidia, Fadila Bentayeb, Omar Boussaid
2012 Misc conf
SAC
Rashed K. Salem, Omar Boussaid, Jérôme Darmont
2012 C conf
ADMA
Lilia Hannachi, Ounas Asfari, Nadjia Benblidia, Fadila Bentayeb, Nadia Kabachi, Omar Boussaid
2012 conf
CD-ARES
Rachid Aknouche, Ounas Asfari, Fadila Bentayeb, Omar Boussaid
2012 conf
INFORSID
Sandro Bimonte, Omar Boussaid, Lama El Sarraj
2012 J jnl
Int. J. Bio Inspired Comput.
Hacène Derrar, Mohamed Ahmed-Nacer, Omar Boussaid
2012 conf
EGC
Rachid Aknouche, Omar Boussaid, Fadila Bentayeb
2012 J jnl
Int. J. Data Warehous. Min.
Sandro Bimonte, Michela Bertolotto, Jérôme Gensel, Omar Boussaid
2012 B conf
TrustBus
Ali Salem, Salah Triki, Hanêne Ben-Abdallah, Nouria Harbi, Omar Boussaid
2011 conf
MLDM
Amina Madani, Omar Boussaid, Djamel Eddine Zegour
2011 J jnl
CoRR
Rashed K. Salem, Jérôme Darmont, Omar Boussaid
2011 C conf
IDEAS
Rashed K. Salem, Jérôme Darmont, Omar Boussaid
2011 conf
KDIR
Rezoug Nachida, Omar Boussaid, Fahima Nader
2011 J jnl
Ingénierie des Systèmes d Inf.
Doulkifli Boukraâ, Omar Boussaid, Fadila Bentayeb, Djamel Eddine Zegour
2011 J jnl
Tech. Sci. Informatiques
Sahla Bouattour, Omar Boussaid, Hanêne Ben-Abdallah, Jamel Feki
2011 conf
CAiSE Forum
Sabine Loudcher Rabaséda, Omar Boussaid
2011 conf
CAiSE Forum (Selected Papers)
Sabine Loudcher Rabaséda, Omar Boussaid
2011 conf
CIIA
Rezoug Nachida, Omar Boussaid, Fahima Nader
2011 C conf
MEDI
Salah Triki, Hanêne Ben-Abdallah, Nouria Harbi, Omar Boussaid
2011 B conf
DaWaK
Doulkifli Boukraâ, Omar Boussaid, Fadila Bentayeb
2010 conf
EGC
Loïc Mabit, Sabine Loudcher Rabaséda, Omar Boussaid
2010 ch.
Complex Data Warehousing and Knowledge Discovery for Advanced Retrieval Development
Fadila Bentayeb, Cécile Favre, Omar Boussaid
2010 C conf
ADBIS
Doulkifli Boukraâ, Omar Boussaid, Fadila Bentayeb
2010 conf
EGC
Doulkifli Boukraâ, Omar Boussaid
2010 C conf
PRO-VE
Kafil Hajlaoui, Xavier Boucher, Omar Boussaid
2009 J jnl
Ingénierie des Systèmes d Inf.
Cécile Favre, M. Rougié, Fadila Bentayeb, Omar Boussaid
2009 ch.
Encyclopedia of Data Warehousing and Mining
Omar Boussaid, Doulkifli Boukraâ
2009 ch.
Database Technologies: Concepts, Methodologies, Tools, and Applications
Marinette Bouet, Pierre Gançarski, Marie-Aude Aufaure, Omar Boussaid
2008 J jnl
CoRR
Omar Boussaid, Fadila Bentayeb, Jérôme Darmont
2008 conf
EGC
Anouck Bodin-Niemczuk, Riadh Ben Messaoud, Sabine Loudcher Rabaséda, Omar Boussaid
2008 J jnl
Int. J. Web Eng. Technol.
Omar Boussaid, Jérôme Darmont, Fadila Bentayeb, Sabine Loudcher Rabaséda
2007 J jnl
CoRR
Jérôme Darmont, Omar Boussaid, Jean-Christian Ralaivao, Kamel Aouiche
2007 J jnl
CoRR
Kamel Aouiche, Jérôme Darmont, Omar Boussaid, Fadila Bentayeb
2007 J jnl
Int. J. Bus. Intell. Data Min.
Jérôme Darmont, Fadila Bentayeb, Omar Boussaid
2007 J jnl
CoRR
Jérôme Darmont, Fadila Bentayeb, Omar Boussaid
2007 J jnl
CoRR
Jérôme Darmont, Fadila Bentayeb, Omar Boussaid
2007 conf
ICEIS (1)
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2007 conf
INFORSID
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2007 B conf
DaWaK
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2007 J jnl
J. Glob. Optim.
Omar Boussaid, Adrian Tanasescu, Fadila Bentayeb, Jérôme Darmont
2007 conf
EGC
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2007 conf
EGC
Rémy Brisson, Omar Boussaid, Pierre Gançarski, Anne Puissant, Nicolas Durand
2007 conf
ICTAI (1)
Nicolas Durand, Sébastien Derivaux, Germain Forestier, Cédric Wemmert, Pierre Gançarski, Omar Boussaid, Anne Puissant
2007 J jnl
CoRR
Jérôme Darmont, Omar Boussaid, Fadila Bentayeb
2007 J jnl
CoRR
Sami Miniaoui, Jérôme Darmont, Omar Boussaid
2006 J jnl
Int. J. Data Warehous. Min.
Riadh Ben Messaoud, Omar Boussaid, Sabine Loudcher Rabaséda
2006 conf
CE
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2006 Misc conf
DB&IS
Riadh Ben Messaoud, Omar Boussaid, Sabine Loudcher Rabaséda
2006 conf
BNCOD
Cécile Favre, Fadila Bentayeb, Omar Boussaid
2006 conf
EDA
Omar Boussaid, Riadh Ben Messaoud, Rémy Choquet, Stéphane Anthoard
2006 A* conf
KDD
Riadh Ben Messaoud, Omar Boussaid, Sabine Loudcher Rabaséda
2006 C conf
DOLAP
Riadh Ben Messaoud, Sabine Loudcher Rabaséda, Omar Boussaid, Rokia Missaoui
2006 conf
INFORSID
Omar Boussaid, Sabine Loudcher Rabaséda
2006 J jnl
Monde des Util. Anal. Données
Omar Boussaid, Pierre Gançarski, Florent Masseglia, Brigitte Trousse, Dominique Desbois
2006 conf
CE
Nora Maiz, Omar Boussaid, Fadila Bentayeb
2006 C conf
ADBIS
Omar Boussaid, Riadh Ben Messaoud, Rémy Choquet, Stéphane Anthoard
2005 conf
ICEIS (1)
Jérôme Darmont, Omar Boussaid, Jean-Christian Ralaivao, Kamel Aouiche
2005 B conf
DaWaK
Kamel Aouiche, Jérôme Darmont, Omar Boussaid, Fadila Bentayeb
2005 B conf
DaWaK
Jérôme Darmont, Omar Boussaid, Fadila Bentayeb
2005 A conf
CIKM
Riadh Ben Messaoud, Omar Boussaid, Sabine Rabaséda
2005 C conf
AICCSA
Adrian Tanasescu, Omar Boussaid, Fadila Bentayeb
2004 C conf
DOLAP
Riadh Ben Messaoud, Omar Boussaid, Sabine Rabaséda
2004 conf
BDA
Jérôme Darmont, Fadila Bentayeb, Omar Boussaid
2004 conf
EGC
Amandine Duffoux, Omar Boussaid, Stéphane Lallich, Fadila Bentayeb
2004 conf
EGC
Cédric Udréa, Fadila Bentayeb, Jérôme Darmont, Omar Boussaid
2004 conf
EGC
Riadh Ben Messaoud, Sabine Rabaséda, Omar Boussaid, Fadila Bentayeb
2003 conf
CE
Omar Boussaid, Fadila Bentayeb, Jérôme Darmont
2003 conf
HoloMAS
Omar Boussaid, Fadila Bentayeb, Amandine Duffoux, Frederic Clerc
2003 J jnl
Ingénierie des Systèmes d Inf.
Omar Boussaid, Fadila Bentayeb, Jérôme Darmont, Sabine Rabaséda
2001 conf
EGC
Fadila Bentayeb, Omar Boussaid, Nicolas Nicoloyannis
tests/unit/test_decompile_medium_level.py
← Index tests/unit/test_decompile_medium_level.py python
# tests/unit/test_decompile_medium_level.py
"""Unit tests (mocked BN) for bninja/analysis/medium_level.py
   and bninja/analysis/medium_level_normalization.py."""
# tests/unit/test_decompile_medium_level.py
import sys
from unittest.mock import MagicMock, patch

# Installa gli stubs BN
from tests.unit.conftest_binja_stubs import install_binja_stubs
install_binja_stubs()

# ── Definisci MockMLILInstruction PRIMA di importare il modulo ──
class MockMLILInstruction:
    def __init__(self, operation, address=0, operands=None):
        self.operation = operation
        self.address = address
        self.operands = operands or []

# ── Patcha il modulo BN in modo che isinstance() funzioni ──
sys.modules["binaryninja"].MediumLevelILInstruction = MockMLILInstruction
sys.modules["binaryninja"].SSAVariable = type("SSAVariable", (), {})
sys.modules["binaryninja"].Variable = type("Variable", (), {})
sys.modules["binaryninja"].ILIntrinsic = type("ILIntrinsic", (), {})

# Ora importa il modulo — vede già i tipi corretti
from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
    MediumLevelNormalization,
)	

class MockMLILFunction:
    def __init__(self, instructions):
        self._instructions = instructions

    @property
    def instructions(self):
        return iter(self._instructions)

    @property
    def basic_blocks(self):
        # one block containing all instructions, good enough for MinHasher
        block = MagicMock()
        block.__iter__ = lambda self_: iter([])  # not used by MediumLevelAnalysis
        return [block]


class MockFunction:
    def __init__(self, name="func", start=0x1000, mlil=None):
        self.name = name
        self.start = start
        self.mlil = mlil



class TestMediumLevelNormalization:
    def setup_method(self):
        from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
            MediumLevelNormalization,
        )
        self.norm = MediumLevelNormalization()

    def test_normalize_skeleton_single_instruction(self):
        il = MockMLILInstruction(operation=42, operands=[])
        result = self.norm.normalize_instruction_all_levels(il)
        assert result == [42]

    def test_normalize_skeleton_nested(self):
        inner = MockMLILInstruction(operation=7, operands=[])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [1, 7]

    def test_normalize_skeleton_with_list_operand(self):
        inner_a = MockMLILInstruction(operation=10, operands=[])
        inner_b = MockMLILInstruction(operation=11, operands=[])
        outer = MockMLILInstruction(operation=2, operands=[[inner_a, inner_b]])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [2, 10, 11]

    def test_normalize_skeleton_none(self):
        result = self.norm.normalize_instruction_all_levels(None)
        # collect on None should leave ops empty
        assert result == []

    def test_normalize_typed_appends_leaf_types(self):
        # operand is a plain int -> "CONST"
        il = MockMLILInstruction(operation=3, operands=[42])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [3, "CONST"]

    def test_normalize_typed_bool_before_int(self):
        # bool must be detected before int (since bool is an int subclass)
        il = MockMLILInstruction(operation=4, operands=[True])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [4, "BOOL"]

    def test_normalize_typed_float(self):
        il = MockMLILInstruction(operation=5, operands=[1.5])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [5, "FLOAT_CONST"]

    def test_normalize_typed_str(self):
        il = MockMLILInstruction(operation=6, operands=["hello"])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [6, "STR"]

    def test_normalize_typed_unknown_falls_back_to_typename(self):
        class Weird:
            pass
        il = MockMLILInstruction(operation=8, operands=[Weird()])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [8, "WEIRD"]

    def test_normalize_typed_nested_mlil(self):
        inner = MockMLILInstruction(operation=99, operands=[7])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instr_with_operands(outer)
        assert result == [1, 99, "CONST"]

    def test_normalize_typed_list_mixed(self):
        inner = MockMLILInstruction(operation=50, operands=[])
        il = MockMLILInstruction(operation=2, operands=[[inner, 99]])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [2, 50, "CONST"]


class TestMediumLevelAnalysis:
    def _make_analysis(self, instructions=None, mlil=True, start=0x1000):
        from redb.extractors.decompiler.bninja.analysis.medium_level import (
            MediumLevelAnalysis,
        )
        mlil_func = MockMLILFunction(instructions or []) if mlil else None
        func = MockFunction(name="testfunc", start=start, mlil=mlil_func)
        bv = MagicMock()
        return MediumLevelAnalysis(func, bv, MagicMock())

    def test_collect_returns_empty_when_no_mlil(self):
        a = self._make_analysis(mlil=False)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk == [] and sk_addr == [] and ty == [] and ty_addr == []

    def test_collect_skeleton_and_typed_basic(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()

        assert sk == [[1], [2]]
        assert ty == [[1], [2, "CONST"]]
        assert sk_addr == [(0, [1]), (4, [2])]
        assert ty_addr == [(0, [1]), (4, [2, "CONST"])]

    def test_collect_negative_offset_clamped_to_zero(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x900, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        _, sk_addr, _, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk_addr[0][0] == 0
        assert ty_addr[0][0] == 0

    def test_log_error_records_entry(self):
        a = self._make_analysis()
        a.log_error("boom", "fname", 0x1234, ValueError("x"), "loc")
        assert len(a.errors) == 1
        err = a.errors[0]
        assert err["function_name"] == "fname"
        assert err["function_address"] == "4660"  # hex 0x1234
        assert err["error_location"] == "loc"
        assert err["error_message"] == "boom"
        assert err["error_type"] == "ValueError"
        assert "timestamp" in err

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_returns_expected_keys(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = [1, 2, 3]

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        result, errors = a.analyze()

        expected_keys = {
            "function_address",
            "body_mlil_skeleton_vector",
            "sha256_mlil_skeleton",
            "tlsh_mlil_skeleton",
            "minhash_mlil_skeleton",
            "body_mlil_typed_vector",
            "sha256_mlil_typed",
            "tlsh_mlil_typed",
            "minhash_mlil_typed",
        }
        assert set(result.keys()) == expected_keys
        assert result["function_address"] == 0x1000
        assert result["minhash_mlil_skeleton"] == [1, 2, 3]
        assert result["minhash_mlil_typed"] == [1, 2, 3]
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_empty_mlil(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []
        a = self._make_analysis(mlil=False)
        result, errors = a.analyze()
        assert result["body_mlil_skeleton_vector"] == []
        assert result["body_mlil_typed_vector"] == []
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_sha256_differs_skeleton_vs_typed(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[42]),
            MockMLILInstruction(operation=2, address=0x1004, operands=["foo"]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[True]),
        ]
        a = self._make_analysis(instructions=instrs)
        result, _ = a.analyze()
        # skeleton ignores operand leaves, typed includes them -> different hashes
        assert result["sha256_mlil_skeleton"] != result["sha256_mlil_typed"]


class TestMinHasherMLILKinds:
    def _make_func(self, instrs):
        # MinHasher iterates basic_blocks then over each block
        block = MagicMock()
        block.__iter__ = lambda self_: iter(instrs)
        f = MagicMock()
        f.basic_blocks = [block]
        return f

    def test_mlil_skeleton_uses_medium_normalizer(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=i, operands=[]) for i in range(5)
        ]
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        result = hasher.calculateMinHash()
        # 5 instructions -> 3 trigrams -> non-empty signature
        assert result != []

    def test_typed_mlil_differs_from_skeleton(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=1, operands=[42]),
            MockMLILInstruction(operation=2, operands=["s"]),
            MockMLILInstruction(operation=3, operands=[True]),
            MockMLILInstruction(operation=4, operands=[1.5]),
        ]
        func = self._make_func(instrs)
        skel = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL).calculateMinHash()
        typed = MinHasher(seed=42, il_function=func, kind=TokenKind.TYPED_MLIL).calculateMinHash()
        # Same seed, same instructions, but typed has extra leaf tokens
        # -> hashes should generally differ
        assert skel != typed

    def test_mlil_too_few_instructions(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [MockMLILInstruction(operation=1, operands=[])] * 2
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        assert hasher.calculateMinHash() == []

    def test_unsupported_kind_raises(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import MinHasher
        func = self._make_func([])
        hasher = MinHasher(seed=42, il_function=func, kind="bogus")
        with pytest.raises(ValueError):
            hasher.calculateMinHash()