Mamoun Filali

82 papers A 4B 12C 11Misc 5Journal 19Unranked 30
YearRankTypeTitle / Venue / Authors
2025 conf
SBESC
Leandro Buss Becker, M. L. Pinto, Jean-Paul Bodeveix, Mamoun Filali
2025 C conf
ABZ
Anne Grieu, Jean-Paul Bodeveix, Mamoun Filali
2024 conf
FACS
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2024 C conf
ABZ
Jean-Paul Bodeveix, Thomas Carle, Elie Fares, Mamoun Filali, Thai Son Hoang
2023 C conf
ABZ
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2021 J jnl
J. Syst. Archit.
Zhibin Yang, Zhikai Qiu, Yong Zhou, Zhiqiu Huang, Jean-Paul Bodeveix, Mamoun Filali
2021 C conf
ABZ
Jean-Paul Bodeveix, Mamoun Filali
2021 J jnl
Formal Aspects Comput.
Zhibin Yang, Yang Bao, Yongqiang Yang, Zhiqiu Huang, Jean-Paul Bodeveix, Mamoun Filali, Zonghua Gu
2021 B conf
COMPSAC
Jian Zhu, Kai Hu, Mamoun Filali, Jean-Paul Bodeveix, Jean-Pierre Talpin, Haitao Cao
2021 J jnl
Sci. Comput. Program.
Zhibin Yang, Shenghao Yuan, Jean-Paul Bodeveix, Mamoun Filali, Tiexin Wang, Yong Zhou
2020 J jnl
IEEE Trans. Reliab.
Fei Wang, Zhibin Yang, Zhi-qiu Huang, Chengwei Liu, Yong Zhou, Jean-Paul Bodeveix, Mamoun Filali
2020 J jnl
Sci. Comput. Program.
Jean-Paul Bodeveix, Arnaud Dieumegard, Mamoun Filali
2020 J jnl
CoRR
Jian Zhu, Kai Hu, Mamoun Filali, Jean-Paul Bodeveix, Jean-Pierre Talpin
2019 B conf
ICECCS
Quentin Rouland, Brahim Hamid, Jean-Paul Bodeveix, Mamoun Filali
2019 conf
FTSCS
Shenghao Yuan, Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali, Tiexin Wang, Yong Zhou
2019 B conf
FM
Jean-Paul Bodeveix, Julien Brunel, David Chemouil, Mamoun Filali
2019 J jnl
Frontiers Comput. Sci.
Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali
2018 J jnl
Acta Informatica
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2018 conf
FACS
Jean-Paul Bodeveix, Arnaud Dieumegard, Mamoun Filali
2018 C conf
MEMOCODE
Jinmiao Xu, Zhibin Yang, Zhiqiu Huang, Yong Zhou, Chengwei Liu, Lei Xue, Jean-Paul Bodeveix, Mamoun Filali
2017 J jnl
CoRR
Jean-Paul Bodeveix, Mamoun Filali, Mohamed Tahar Bhiri, Badr Siala
2017 C conf
PDP
Badr Siala, Jean-Paul Bodeveix, Mamoun Filali, Mohamed Tahar Bhiri
2016 C conf
ICFEM
Badr Siala, Mohamed Tahar Bhiri, Jean-Paul Bodeveix, Mamoun Filali
2016 J jnl
Frontiers Comput. Sci.
Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali, Kai Hu, Yongwang Zhao, Dianfu Ma
2015 J jnl
CoRR
Bernard Berthomieu, Jean-Paul Bodeveix, Silvano Dal-Zilio, Mamoun Filali, Didier Le Botlan, Guillaume Verdier, François Vernadat
2015 J jnl
Sci. Comput. Program.
Jean-Paul Bodeveix, Mamoun Filali, Manuel Garnacho, Régis Spadotti, Zhibin Yang
2014 conf
FTSCS
Mamoun Filali, Meriem Ouederni, Jean-Baptiste Raclet
2014 C conf
SCOPES
Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali, Kai Hu, Dianfu Ma
2014 conf
ARCS
Hajer Herbegue, Mamoun Filali, Hugues Cassé
2014 conf
ACVI@MoDELS
Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali
2013 J jnl
Frontiers Comput. Sci.
Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali
2013 C conf
TIME
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2013 conf
FSEN
Abdeldjalil Boudjadar, Frits W. Vaandrager, Jean-Paul Bodeveix, Mamoun Filali
2013 conf
SIES
Hajer Herbegue, Hugues Cassé, Mamoun Filali, Christine Rochange
2012 C conf
TIME
Abdeldjalil Boudjadar, Jean-Paul Bodeveix, Mamoun Filali
2012 A conf
SC
Abdeldjalil Boudjadar, Jean-Paul Bodeveix, Mamoun Filali
2011 B conf
ATVA
Jean-Paul Bodeveix, Abdeldjalil Boudjadar, Mamoun Filali
2011 B conf
ICECCS
Isabelle Perseil, Laurent Pautet, Jean-François Rolland, Mamoun Filali, Didier Delanote, Stefan Van Baelen, Wouter Joosen, Yolande Berbers, Frédéric Mallet, Dominique Bertrand, Sébastien Faucou, Abdelhafid Zitouni, Mahmoud Boufaïda, Lionel Seinturier, Joël Champeau, Thomas Abdoul, Peter H. Feiler, Chokri Mraidha, Sébastien Gérard
2011 conf
WS-FM
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2011 conf
B@FM
Jean-Paul Bodeveix, Mamoun Filali
2011 conf
BMMDS/EMMSAD
Elie Fares, Jean-Paul Bodeveix, Mamoun Filali
2010 B conf
ICECCS
T. Correa, Leandro Buss Becker, Jean-Marie Farines, Jean-Paul Bodeveix, Mamoun Filali, François Vernadat
2010 ch.
Synthesis of Embedded Software
Alexandre Cortier, Loïc Besnard, Jean-Paul Bodeveix, Jérémy Buisson, Fabien Dagnat, Mamoun Filali, Gérald Garcia, Julien Ouy, Marc Pantel, Ana-Elena Rugina, Martin Strecker, Jean-Pierre Talpin
2009 B conf
ICECCS
Lei Pi, Zhibin Yang, Jean-Paul Bodeveix, Mamoun Filali, Kai Hu, Dianfu Ma
2009 Misc conf
Ada-Europe
Bernard Berthomieu, Jean-Paul Bodeveix, Christelle Chaudet, Silvano Dal-Zilio, Mamoun Filali, François Vernadat
2009 Misc conf
Ada-Europe
Lei Pi, Jean-Paul Bodeveix, Mamoun Filali
2009 conf
SBMF
Ricardo Bedin França, Leandro Buss Becker, Jean-Paul Bodeveix, Jean-Marie Farines, Mamoun Filali
2008 conf
MoDELS (Workshops)
Iulian Ober, Stefan Van Baelen, Susanne Graf, Mamoun Filali, Thomas Weigert, Sébastien Gérard
2008 B conf
ICECCS
Jean-François Rolland, Jean-Paul Bodeveix, Mamoun Filali, David Chemouil, Dave Thomas
2008 J jnl
Obj. Logiciel Base données Réseaux
Odile Nasr, M. Rached, Jean-Paul Bodeveix, Mamoun Filali
2007 conf
VERIFY
Mamoun Filali
2007 conf
JTRES
Jean-Paul Bodeveix, Raphaël Cavallero, David Chemouil, Mamoun Filali, Jean-François Rolland
2007 B conf
ICECCS
Ricardo Bedin França, Jean-Paul Bodeveix, Mamoun Filali, Jean-François Rolland, David Chemouil, Dave Thomas
2007 J jnl
SIGBED Rev.
Sébastien Gérard, Peter H. Feiler, Jean-François Rolland, Mamoun Filali, Mark-Oliver Reiser, Didier Delanote, Yolande Berbers, Laurent Pautet, Isabelle Perseil
2006 conf
DEON
Julien Brunel, Jean-Paul Bodeveix, Mamoun Filali
2006 conf
AVoCS
Jean-Paul Bodeveix, Mamoun Filali, Julia L. Lawall, Gilles Muller
2006 Misc conf
SAC
Odile Nasr, Jean-Paul Bodeveix, Mamoun Filali, Miloud Rached Irit
2005 B conf
IFM
Jean-Paul Bodeveix, Mamoun Filali, Julia Lawall, Gilles Muller
2005 Misc conf
PPAM
Mamoun Filali, Valérie Issarny, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
2005 conf
FESCA@ETAPS
Jean-Paul Bodeveix, David Chemouil, Mamoun Filali, Martin Strecker
2003 A conf
IPDPS
Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
2003 C conf
FMICS
Bernard Berthomieu, Pierre-Olivier Ribet, François Vernadat, J. L. Bernartt, Jean-Marie Farines, Jean-Paul Bodeveix, Mamoun Filali, Gérard Padiou, Pierre Michel, Patrick Farail, Pierre Gauffilet, Pierre Dissaux, Jean-Luc Lambert
2002 J jnl
Formal Methods Syst. Des.
Jean-Paul Bodeveix, Mamoun Filali
2002 conf
ZB
Jean-Paul Bodeveix, Mamoun Filali
2000 B conf
OPODIS
Philippe Quéinnec, Mamoun Filali, Philippe Mauran, Gérard Padiou
2000 conf
ICDCS Workshop on Distributed System Validation and Verification
Jean-Paul Bodeveix, Mamoun Filali
2000 A conf
TACAS
Jean-Paul Bodeveix, Mamoun Filali
2000 conf
IPDPS Workshops
Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec, Xavier Thirioux
1999 B conf
OPODIS
Michel Charpentier, Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
1999 conf
Euro-Par
Luc Bougé, Bill McColl, Mamoun Filali, Henk J. Sips
1999 J jnl
Parallel Process. Lett.
Michel Charpentier, Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
1998 conf
IPPS/SPDP Workshops
Jean-Paul Bodeveix, Mamoun Filali
1998 conf
IPPS/SPDP Workshops
Michel Charpentier, Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
1997 J jnl
Parallel Process. Lett.
Jean-Paul Bodeveix, Mamoun Filali
1996 conf
WDAG
Michel Charpentier, Mamoun Filali, Philippe Mauran, Gérard Padiou, Philippe Quéinnec
1995 conf
TPHOLs
Jean-Paul Bodeveix, Mamoun Filali
1994 conf
RTS
Mamoun Filali
1994 conf
TPHOLs
Jean-Paul Bodeveix, Mamoun Filali, P. Roche
1993 conf
RTS
Mamoun Filali, Philippe Mauran, Gérard Padiou
1992 Misc conf
Ada-Europe
G. Bazalgette, D. Bekele, Carole Bernon, Mamoun Filali, J. M. Rigaud, A. Sayah
1989 J jnl
Softw. Eng. J.
F. Bichon, Mamoun Filali, Gérard Padiou, R. Smith
1985 A conf
ICDCS
Claude Bétourné, Mamoun Filali, Gérard Padiou, A. Sayah
tests/unit/test_dataclasses.py
← Index tests/unit/test_dataclasses.py python
"""
Unit tests for redb.models.dataclasses.

These tests verify construction, field defaults, and type expectations for
every dataclass in the module (excluding Mach-O dataclasses, which are
covered by test_macho_dataclasses.py).
"""
import pytest
from dataclasses import asdict, fields

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


# ============================================================================
# Hash / Hashes
# ============================================================================

class TestHashDataclass:
    """Tests for the Hash dataclass."""

    def test_creation(self):
        from redb.models.dataclasses import Hash

        h = Hash(
            md5="d41d8cd98f00b204e9800998ecf8427e",
            sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709",
            sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
        assert h.md5 == "d41d8cd98f00b204e9800998ecf8427e"
        assert h.sha1 == "da39a3ee5e6b4b0d3255bfef95601890afd80709"
        assert h.sha256 == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

    def test_asdict(self):
        from redb.models.dataclasses import Hash

        h = Hash(md5="a", sha1="b", sha256="c")
        d = asdict(h)
        assert d == {"md5": "a", "sha1": "b", "sha256": "c"}


class TestHashesDataclass:
    """Tests for the Hashes dataclass."""

    def test_required_fields(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(
            md5="md5val",
            sha1="sha1val",
            sha256="sha256val",
            ssdeep_hash="ssdeep",
            tlsh_hash="tlsh",
        )
        assert h.md5 == "md5val"
        assert h.ssdeep_hash == "ssdeep"

    def test_optional_pe_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.authentihash is None
        assert h.imphash is None
        assert h.richhash is None
        assert h.richpe_hash is None
        assert h.richpv_hash is None
        assert h.richpv_hash_sorted is None
        assert h.typerefhash is None
        assert h.impfuzzy is None

    def test_optional_elf_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.import_hash is None
        assert h.export_hash is None
        assert h.section_hash is None
        assert h.symbol_hash is None
        assert h.dynamic_hash is None

    def test_optional_macho_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.macho_dylib_hash is None
        assert h.macho_import_hash is None
        assert h.macho_export_hash is None
        assert h.macho_entitlement_hash is None
        assert h.macho_symhash is None

    def test_macho_fields_settable(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(
            md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e",
            macho_dylib_hash="dylib_h",
            macho_import_hash="import_h",
            macho_export_hash="export_h",
            macho_entitlement_hash="ent_h",
            macho_symhash="sym_h",
        )
        assert h.macho_dylib_hash == "dylib_h"
        assert h.macho_import_hash == "import_h"
        assert h.macho_export_hash == "export_h"
        assert h.macho_entitlement_hash == "ent_h"
        assert h.macho_symhash == "sym_h"


# ============================================================================
# BasicProperties
# ============================================================================

class TestBasicPropertiesDataclass:
    """Tests for the BasicProperties dataclass."""

    def test_required_fields(self):
        from redb.models.dataclasses import BasicProperties

        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,
        )
        assert bp.filename == "test.exe"
        assert bp.filesize == 1024
        assert bp.file_entropy == 6.5

    def test_optional_fields_default_none(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="x", sample_name="x", filesize=0,
            filetype="t", filetype_mime="m", filetype_magika="k", file_entropy=0.0,
        )
        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_fat_fields(self):
        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 len(bp.child_sha256) == 2
        assert bp.child_architecture == ["x86_64", "arm64"]

    def test_asdict_roundtrip(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="f", sample_name="s", filesize=10,
            filetype="t", filetype_mime="m", filetype_magika="k", file_entropy=1.0,
        )
        d = asdict(bp)
        assert d["filename"] == "f"
        assert d["is_fat"] is None


# ============================================================================
# DIEinfo / CAPA
# ============================================================================

class TestDIEinfoDataclass:
    def test_creation(self):
        from redb.models.dataclasses import DIEinfo

        d = DIEinfo(die_full_dump="dump_text")
        assert d.die_full_dump == "dump_text"
        assert d.die_info == {}

    def test_with_info(self):
        from redb.models.dataclasses import DIEinfo

        d = DIEinfo(die_full_dump="x", die_info={"packer": "UPX"})
        assert d.die_info["packer"] == "UPX"


class TestCAPADataclass:
    def test_creation(self):
        from redb.models.dataclasses import CAPA

        c = CAPA(
            capa_dump="dump",
            capabilities=["cap1"],
            namespaces=["ns1"],
            attack_dump="attack",
            tactics=["TA0001"],
            techniques=["T1059"],
            techniques_id=["T1059.001"],
            mbc_dump="mbc",
            mbc_objectives=["obj1"],
            mbc_behaviors=["beh1"],
            mbc_behaviors_id=["B0001"],
        )
        assert c.capa_dump == "dump"
        assert "cap1" in c.capabilities
        assert "TA0001" in c.tactics


# ============================================================================
# Malcontent
# ============================================================================

class TestMalcontentDataclass:
    def test_creation(self):
        from redb.models.dataclasses import Malcontent

        m = Malcontent(
            malcontent_dump='{"RiskScore": 2}',
            version="malcontent v1.0.0",
            risk_score=2,
            risk_level="MEDIUM"
        )
        assert m.malcontent_dump == '{"RiskScore": 2}'
        assert m.version == "malcontent v1.0.0"
        assert m.risk_score == 2
        assert m.risk_level == "MEDIUM"

    def test_with_json_content(self):
        from redb.models.dataclasses import Malcontent
        import json

        # Now stores unwrapped content (without Files/<path> wrapper)
        file_content = {
            "RiskScore": 3,
            "RiskLevel": "HIGH",
            "IsMalcontent": True,
            "Behaviors": [
                {"RuleName": "exec/shell", "RiskLevel": "HIGH", "Description": "executes shell commands"}
            ]
        }
        m = Malcontent(
            malcontent_dump=json.dumps(file_content),
            version="v0.5.0",
            risk_score=3,
            risk_level="HIGH"
        )
        parsed = json.loads(m.malcontent_dump)
        assert parsed["RiskLevel"] == "HIGH"
        assert parsed["Behaviors"][0]["RuleName"] == "exec/shell"

    def test_asdict(self):
        from redb.models.dataclasses import Malcontent
        from dataclasses import asdict

        m = Malcontent(malcontent_dump="{}", version="v1", risk_score=0, risk_level="")
        d = asdict(m)
        assert d == {"malcontent_dump": "{}", "version": "v1", "risk_score": 0, "risk_level": ""}


# ============================================================================
# String
# ============================================================================

class TestStringDataclass:
    def test_creation(self):
        from redb.models.dataclasses import String

        s = String(string="hello", string_length=5, string_entropy=2.3, string_frequency=10)
        assert s.string == "hello"
        assert s.md5 == []
        assert s.sha1 == []
        assert s.sha256 == []

    def test_with_hashes(self):
        from redb.models.dataclasses import String

        s = String(
            string="test", string_length=4, string_entropy=2.0, string_frequency=1,
            md5=["abc"], sha256=["def"],
        )
        assert s.md5 == ["abc"]
        assert s.sha256 == ["def"]


# ============================================================================
# PE Dataclasses
# ============================================================================

class TestPEDataclass:
    def test_required_fields(self):
        from redb.models.dataclasses import PE

        pe = PE(
            dos_header="dos", nt_header="nt", optional_header="opt",
            file_header="fh", magic="0x10b", entry_point="0x1000",
            major_linker_version=14, minor_linker_version=0,
            target_machine="I386", architecture="x86",
            compilation_time=1609459200, compilation_time_utc="2021-01-01T00:00:00",
            is_dotnet=False, is_signed=False, has_overlay=False,
            number_of_sections=4, number_of_imports=10,
            number_of_exports=0, number_of_resources=2,
            type="EXE",
        )
        assert pe.architecture == "x86"
        assert pe.type == "EXE"

    def test_optional_fields_default_none(self):
        from redb.models.dataclasses import PE

        pe = PE(
            dos_header="d", nt_header="n", optional_header="o",
            file_header="f", magic="m", entry_point="e",
            major_linker_version=0, minor_linker_version=0,
            target_machine="t", architecture="a",
            compilation_time=0, compilation_time_utc="",
            is_dotnet=False, is_signed=False, has_overlay=False,
            number_of_sections=0, number_of_imports=0,
            number_of_exports=0, number_of_resources=0,
            type="DLL",
        )
        assert pe.dbg_struct is None
        assert pe.tls_struct is None
        assert pe.rich_header_dump is None
        assert pe.version_info is None


class TestPEImportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEImport

        pi = PEImport(pe_imports_total=5)
        assert pi.pe_imports_total == 5
        assert pi.pe_import_libraryName is None
        assert pi.pe_import_functions is None


class TestPESectionDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PESection

        ps = PESection(
            _id="sec_id", section_entropy=6.5, section_sha256="sha",
            section_md5="md5", section_name=".text", section_name_b64=".text",
            section_pointer_to_raw_data="0x400",
            section_size=4096, section_v_addr="0x1000",
            section_v_addr_hex="0x1000", section_v_size=8192,
        )
        assert ps.section_name == ".text"
        assert ps.section_entropy == 6.5


class TestPEResourceDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEResource

        pr = PEResource(
            _id="res_id", resource_type="RT_ICON", resource_entropy=3.5,
            resource_sha256="sha", resource_filetype="image/png",
            resource_magika="png", resource_language="LANG_ENGLISH",
            resource_sub_lang="SUBLANG_DEFAULT",
            resource_rva="0x2000", resource_size=1024,
        )
        assert pr.resource_type == "RT_ICON"


class TestPEOverlayDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEOverlay

        po = PEOverlay(
            _id="ovl_id", overlay_size=512, overlay_entropy=7.9,
            overlay_offset="0x5000", overlay_mimetype="application/octet-stream",
            overlay_type="data", overlay_magika="unknown",
            overlay_sha256="sha", overlay_sha1="sha1", overlay_md5="md5",
        )
        assert po.overlay_size == 512


class TestPESignerDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PESigner

        ps = PESigner(
            signer_serial_number="01", signer_subject="CN=Test",
            signer_issuer="CN=CA", signer_valid_from="2021-01-01",
            signer_valid_to="2025-01-01", signer_thumbprint="aabb",
            signer_algorithm="sha256WithRSAEncryption",
        )
        assert ps.signer_subject == "CN=Test"


class TestPECertificateDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PECertificate

        pc = PECertificate(
            certificate_serial_number="02", certificate_subject="CN=Cert",
            certificate_issuer="CN=CA", certificate_valid_from="2021-01-01",
            certificate_valid_to="2025-01-01", certificate_thumbprint="ccdd",
            certificate_algorithm="sha256",
        )
        assert pc.certificate_serial_number == "02"


class TestPECodeSigningInfoDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PECodeSigningInfo

        cs = PECodeSigningInfo(
            _id="cs_id", signature_verified=True, number_of_certificates=2,
        )
        assert cs.signature_verified is True
        assert cs.x509_certificates is None

    def test_with_certificates(self):
        from redb.models.dataclasses import PECodeSigningInfo

        cs = PECodeSigningInfo(
            _id="cs_id", signature_verified=False, number_of_certificates=0,
            x509_certificates=[{"cn": "test"}],
        )
        assert len(cs.x509_certificates) == 1


class TestPEExtraFindingDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEExtraFinding

        ef = PEExtraFinding(context="anomaly_detection")
        assert ef.context == "anomaly_detection"
        assert ef.finding is None


class TestPEDotNetDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEDotNet

        dn = PEDotNet()
        assert dn.dotnet == {}

    def test_with_data(self):
        from redb.models.dataclasses import PEDotNet

        dn = PEDotNet(dotnet={"runtime": "v4.0.30319"})
        assert dn.dotnet["runtime"] == "v4.0.30319"


class TestDotNetInconsistencyTestsDataclass:
    def test_creation(self):
        from redb.models.dataclasses import DotNetInconsistencyTests

        it = DotNetInconsistencyTests(
            test_dotnet_data_dir_hidden=False,
            test_dotnet_fake_types=True,
            test_dotnet_extra_data=None,
            test_dotnet_invalid_type_ref=False,
            test_dotnet_fake_datastreams=False,
            test_dotnet_extra_module_table=None,
            test_dotnet_extra_assembly_table=False,
            test_dotnet_invalid_strings_stream=False,
            test_dotnet_streams_mixed_case=True,
            test_dotnet_method_def_invalid_table=False,
            test_dotnet_max_len_exceeding_strings=False,
        )
        assert it.test_dotnet_fake_types is True
        assert it.test_dotnet_extra_data is None


class TestPEInconsistencyTestsDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEInconsistencyTests

        it = PEInconsistencyTests(
            test_rich_header_checksum=True,
            test_rich_header_duplicate=False,
            test_rich_header_linker=None,
            test_rich_header_import_count=True,
        )
        assert it.test_rich_header_checksum is True
        assert it.test_rich_header_linker is None


# ============================================================================
# YARA Dataclasses
# ============================================================================

class TestYaraRuleDataclass:
    def test_creation(self):
        from redb.models.dataclasses import YaraRule

        yr = YaraRule(
            rule_name="test_rule",
            rule_tags=["malware", "trojan"],
            rule_meta={"author": "test", "description": "A test rule"},
        )
        assert yr.rule_name == "test_rule"
        assert "malware" in yr.rule_tags


class TestYaraMatchDataclass:
    def test_creation(self):
        from redb.models.dataclasses import YaraMatch

        ym = YaraMatch(rule_name="test_rule", match_strings=["$s1", "$s2"])
        assert ym.rule_name == "test_rule"
        assert len(ym.match_strings) == 2


# ============================================================================
# ELF Dataclasses
# ============================================================================

class TestELFFeaturesDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFFeatures

        ef = ELFFeatures(
            ei_class=2, ei_data=1, ei_version=1, ei_osabi=0, ei_abiversion=0,
            e_type=2, e_machine=62, e_version=1, e_entry=0x400000, e_flags=0,
            ei_class_str="ELFCLASS64", ei_data_str="ELFDATA2LSB",
            ei_osabi_str="ELFOSABI_SYSV", e_type_str="ET_EXEC",
            e_machine_str="EM_X86_64",
            is_64bit=1, is_stripped=0, is_pie=0, has_canary=1, has_nx=1,
            has_relro=1, has_fortify=0,
            number_of_segments=9, number_of_sections=31,
            number_of_symbols=100, number_of_dynamic_symbols=50,
            number_of_relocations=25, number_of_dependencies=5,
            gnu_hash_present=1, has_debug_info=0,
        )
        assert ef.ei_class == 2
        assert ef.e_machine_str == "EM_X86_64"
        assert ef.build_id is None

    def test_with_build_id(self):
        from redb.models.dataclasses import ELFFeatures

        ef = ELFFeatures(
            ei_class=2, ei_data=1, ei_version=1, ei_osabi=0, ei_abiversion=0,
            e_type=3, e_machine=62, e_version=1, e_entry=0, e_flags=0,
            ei_class_str="64", ei_data_str="LE", ei_osabi_str="SYSV",
            e_type_str="DYN", e_machine_str="X86_64",
            is_64bit=1, is_stripped=1, is_pie=1, has_canary=0, has_nx=1,
            has_relro=1, has_fortify=0,
            number_of_segments=8, number_of_sections=28,
            number_of_symbols=0, number_of_dynamic_symbols=30,
            number_of_relocations=10, number_of_dependencies=3,
            gnu_hash_present=1, has_debug_info=0,
            build_id="abc123def456",
        )
        assert ef.build_id == "abc123def456"


class TestELFDependencyDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFDependency

        dep = ELFDependency(
            dependency_name="libc.so.6",
            dependency_type=1,
            dependency_type_str="NEEDED",
        )
        assert dep.dependency_name == "libc.so.6"


class TestELFImportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFImport

        ei = ELFImport(elf_imports_total=3)
        assert ei.elf_imports_total == 3
        assert ei.elf_import_libraries == []
        assert ei.elf_import_functions == []


class TestELFExportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFExport

        ee = ELFExport(elf_exports_total=5)
        assert ee.elf_exports_total == 5
        assert ee.elf_export_functions == []


class TestELFSectionDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSection

        es = ELFSection(
            section_name=".text", section_type=1, section_type_str="SHT_PROGBITS",
            section_flags=6, section_flags_str=["SHF_ALLOC", "SHF_EXECINSTR"],
            section_addr=0x400000, section_offset=0x1000, section_size=4096,
            section_link=0, section_info=0, section_addralign=16, section_entsize=0,
            section_entropy=6.8, section_sha256="sha", section_md5="md5",
        )
        assert es.section_name == ".text"
        assert "SHF_ALLOC" in es.section_flags_str


class TestELFSegmentDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSegment

        seg = ELFSegment(
            segment_type=1, segment_type_str="PT_LOAD",
            segment_flags=5, segment_flags_str=["PF_R", "PF_X"],
            segment_offset=0, segment_vaddr=0x400000, segment_paddr=0x400000,
            segment_filesz=0x1000, segment_memsz=0x1000, segment_align=0x200000,
            segment_entropy=5.5, segment_sha256="sha", segment_md5="md5",
        )
        assert seg.segment_type_str == "PT_LOAD"


class TestELFSymbolDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSymbol

        sym = ELFSymbol(
            symbol_name="main", symbol_value=0x401000, symbol_size=100,
            symbol_type=2, symbol_type_str="STT_FUNC",
            symbol_bind=1, symbol_bind_str="STB_GLOBAL",
            symbol_visibility=0, symbol_visibility_str="STV_DEFAULT",
            symbol_section_index=14, symbol_section_index_str="14",
            is_dynamic=0,
        )
        assert sym.symbol_name == "main"
        assert sym.symbol_type_str == "STT_FUNC"


class TestELFRelocationDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFRelocation

        rel = ELFRelocation(
            relocation_offset=0x601000, relocation_type=7,
            relocation_type_str="R_X86_64_JUMP_SLOT",
            relocation_symbol_index=1, relocation_symbol_name="printf",
            relocation_section=".rela.plt",
        )
        assert rel.relocation_addend is None

    def test_with_addend(self):
        from redb.models.dataclasses import ELFRelocation

        rel = ELFRelocation(
            relocation_offset=0x601000, relocation_type=7,
            relocation_type_str="R_X86_64_JUMP_SLOT",
            relocation_symbol_index=1, relocation_symbol_name="printf",
            relocation_section=".rela.plt",
            relocation_addend=-4,
        )
        assert rel.relocation_addend == -4


class TestELFNoteDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFNote

        note = ELFNote(
            note_name="GNU", note_type=3,
            note_type_str="NT_GNU_BUILD_ID",
            note_desc="abc123", note_section=".note.gnu.build-id",
        )
        assert note.note_name == "GNU"
        assert note.note_type_str == "NT_GNU_BUILD_ID"


# ============================================================================
# Decompiled
# ============================================================================

class TestDecompiledDataclass:
    def test_creation(self):
        from redb.models.dataclasses import Decompiled

        d = Decompiled(
            _id="func_hash",
            decompiled_function_name="main",
            decompiled_function_address="0x401000",
            decompiled_function="int main() { return 0; }",
        )
        assert d.decompiled_function_name == "main"