Vagan Y. Terziyan

101 papers B 5C 27Misc 4Journal 25Unranked 39
YearRankTypeTitle / Venue / Authors
2025 J jnl
AI Ethics
Vagan Y. Terziyan, Timo Tiihonen, Amit K. Shukla, Svitlana Gryshko, Mariia Golovianko, Oleksandr Terziyan, Oleksandra Vitko
2024 C conf
ISM
Vagan Y. Terziyan, Oleksandra Vitko
2024 C conf
ISM
Vagan Y. Terziyan, Oleksandra Vitko
2024 C conf
ISM
Vagan Y. Terziyan, Timo Tiihonen
2024 C conf
ISM
Oleksii Streltsov, Vagan Y. Terziyan, Oleksandra Vitko
2024 C conf
ISM
Vagan Y. Terziyan, Olena Kaikova
2024 C conf
IEA/AIE
Vagan Y. Terziyan, Olena Kaikova
2023 C conf
ISM
Vagan Y. Terziyan, Olena Kaikova, Mariia Golovianko, Oleksandra Vitko
2023 C conf
ISM
Vagan Y. Terziyan, Artur Terziian, Oleksandra Vitko
2023 C conf
ISM
Vagan Y. Terziyan, Bohdan Bilokon, Mariia Gavriushenko
2023 C conf
ISM
Olena Kaikova, Vagan Y. Terziyan
2023 J jnl
Eur. J. Inf. Syst.
Mariia Golovianko, Svitlana Gryshko, Vagan Y. Terziyan, Tuure Tuunanen
2023 C conf
ISM
Vagan Y. Terziyan, Oleksandra Vitko
2023 C conf
ISM
Vagan Y. Terziyan, Timo Tiihonen
2022 C conf
ISM
Vagan Y. Terziyan, Oleksandra Vitko
2022 J jnl
Int. J. Simul. Process. Model.
Vladyslav Branytskyi, Mariia Golovianko, Svitlana Gryshko, Diana Malyk, Vagan Y. Terziyan, Tuure Tuunanen
2022 C conf
ISM
Vagan Y. Terziyan, Diana Malyk, Mariia Golovianko, Vladyslav Branytskyi
2022 J jnl
Neural Networks
Vagan Y. Terziyan, Diana Malyk, Mariia Golovianko, Vladyslav Branytskyi
2022 C conf
ISM
Mariia Golovianko, Vagan Y. Terziyan, Vladyslav Branytskyi, Diana Malyk
2022 J jnl
Neural Comput.
Vagan Y. Terziyan, Olena Kaikova
2022 C conf
ISM
Vagan Y. Terziyan, Olena Kaikova, Diana Malyk, Vladyslav Branytskyi
2021 C conf
ISM
Samu Kumpulainen, Vagan Y. Terziyan
2021 J jnl
CoRR
Valerii Semenets, Vagan Y. Terziyan, Svitlana Gryshko, Mariia Golovianko
2021 C conf
ISM
Vagan Y. Terziyan, Oleksandra Vitko
2021 C conf
ISM
Vladyslav Branytskyi, Mariia Golovianko, Diana Malyk, Vagan Y. Terziyan
2021 J jnl
CoRR
Valerii Semenets, Svitlana Gryshko, Mariia Golovianko, Oleksandr O. Shevchenko, Liudmyla Titova, Olena Kaikova, Vagan Y. Terziyan, Timo Tiihonen
2021 J jnl
ISPRS Int. J. Geo Inf.
Vagan Y. Terziyan, Anton Nikulin
2020 C conf
ISM
Anastasiia Girka, Vagan Y. Terziyan, Mariia Gavriushenko, Andrii Gontarenko
2020 C conf
ISM
Vagan Y. Terziyan, Svitlana Gryshko, Mariia Golovianko
2020 C conf
ISM
Mariia Golovianko, Svitlana Gryshko, Vagan Y. Terziyan, Tuure Tuunanen
2019 J jnl
CoRR
Vagan Y. Terziyan, Anton Nikulin
2017 conf
International KEYSTONE Conference
Mariia Golovianko, Svitlana Gryshko, Vagan Y. Terziyan
2017 J jnl
Trans. Comput. Collect. Intell.
Michael Cochez, Vagan Y. Terziyan, Vadim Ermolayev
2017 J jnl
Int. J. Geogr. Inf. Sci.
Vagan Y. Terziyan
2016 J jnl
Int. J. Metadata Semant. Ontologies
Vagan Y. Terziyan, Olena Kaikova
2016 conf
International KEYSTONE Conference
Vagan Y. Terziyan, Mariia Golovianko, Michael Cochez
2015 conf
International KEYSTONE Conference
Michael Cochez, Vagan Y. Terziyan, Vadim Ermolayev
2015 J jnl
Inf. Technol. Dev.
Vagan Y. Terziyan, Mariia Golovianko, Oleksandr O. Shevchenko
2015 J jnl
J. Decis. Syst.
Vagan Y. Terziyan, Olena Kaikova
2014 C conf
HSI
Sacha Helfenstein, Olena Kaikova, Oleksiy Khriyenko, Vagan Y. Terziyan
2012 Misc conf
ICTERI
Michael Cochez, Vagan Y. Terziyan
2011 conf
GPC Workshops
Vagan Y. Terziyan
2010 conf
ICEIS (2)
Oleksiy Khriyenko, Sergiy Nikitin, Vagan Y. Terziyan
2010 conf
ICINCO (1)
Sergiy Nikitin, Vagan Y. Terziyan, Michal Nagy
2010 conf
ICEIS (1)
Sergiy Nikitin, Vagan Y. Terziyan, Minna Lappalainen
2009 conf
ICAS
Joonas Kesäniemi, Artem Katasonov, Vagan Y. Terziyan
2009 conf
ICAS
Sergiy Nikitin, Artem Katasonov, Vagan Y. Terziyan
2009 conf
ICNS
Vagan Y. Terziyan, Dmytro Zhovtobryukh, Artem Katasonov
2009 conf
ICAS
Artem Katasonov, Vagan Y. Terziyan
2008 conf
ICSC
Artem Katasonov, Vagan Y. Terziyan
2008 conf
ICINCO-ICSO
Artem Katasonov, Olena Kaykova, Oleksiy Khriyenko, Sergiy Nikitin, Vagan Y. Terziyan
2007 conf
IESA
Anton Naumenko, Artem Katasonov, Vagan Y. Terziyan
2007 conf
ICEIS (2)
Kimmo Salmenjoki, Yaroslav Tsaruk, Vagan Y. Terziyan, Marko Viitala
2007 conf
ICINCO-RA (1)
Sergiy Nikitin, Vagan Y. Terziyan, Jouni Pyötsiä
2007 conf
KES (3)
Vagan Y. Terziyan
2007 conf
MATES
Artem Katasonov, Vagan Y. Terziyan
2006 J jnl
Int. J. Metadata Semant. Ontologies
Oleksiy Khriyenko, Vagan Y. Terziyan
2006 conf
SETN
Vagan Y. Terziyan
2006 J jnl
Appl. Intell.
Anton Naumenko, Sergiy Nikitin, Vagan Y. Terziyan
2006 J jnl
Electron. Commer. Res. Appl.
Jari Veijalainen, Vagan Y. Terziyan, Henry Tirri
2005 J jnl
Int. J. Artif. Intell. Tools
Vagan Y. Terziyan
2005 J jnl
Int. J. Semantic Web Inf. Syst.
Olena Kaykova, Oleksiy Khriyenko, D. Kovtun, Anton Naumenko, Vagan Y. Terziyan, Andriy Zharko
2005 ed.
IFIP IASW
Max Bramer, Vagan Y. Terziyan
2005 conf
AIS-ADM
Sergiy Nikitin, Vagan Y. Terziyan, Yaroslav Tsaruk, Andriy Zharko
2005 conf
IFIP IASW
Olena Kaykova, Oleksiy Khriyenko, Vagan Y. Terziyan, Andriy Zharko
2005 J jnl
Int. J. Intell. Inf. Technol.
Vagan Y. Terziyan
2005 conf
IFIP IASW
Anton Naumenko, Sergiy Nikitin, Vagan Y. Terziyan, Jari Veijalainen
2004 conf
Databases and Applications
Olena Kaykova, Oleksandr Kononenko, Vagan Y. Terziyan, Andriy Zharko
2004 Misc conf
AIAI
Vagan Y. Terziyan, Oleksandra Vitko
2004 conf
Parallel and Distributed Computing and Networks
Oleksiy Khriyenko, Oleksandr Kononenko, Vagan Y. Terziyan
2004 B conf
ICALT
Igor N. Keleberda, Natalya S. Lesna, Sergiy D. Makovetskiy, Vagan Y. Terziyan
2004 J jnl
Int. J. Web Serv. Res.
Vadim Ermolayev, Natalya Keberle, Sergey Plaksin, Oleksandr Kononenko, Vagan Y. Terziyan
2003 Misc conf
KI
Vagan Y. Terziyan, Oleksandra Vitko
2003 J jnl
Mob. Networks Appl.
Jian Tang, Vagan Y. Terziyan, Jari Veijalainen
2003 conf
Applied Informatics
Vladimir Ryabov, Vagan Y. Terziyan
2003 J jnl
Int. J. Comput. Syst. Signals
Vagan Y. Terziyan, Andriy Zharko
2003 conf
ICWS-Europe
Vagan Y. Terziyan, Oleksandr Kononenko
2003 conf
OTM Workshops
Vagan Y. Terziyan
2003 conf
CIA
Catholijn M. Jonker, Vagan Y. Terziyan, Jan Treur
2003 conf
HICSS
Jari Veijalainen, Vagan Y. Terziyan, Henry Tirri
2002 J jnl
Intell. Syst. Account. Finance Manag.
Vagan Y. Terziyan
2001 conf
WISE (2)
Kirsi Virrantaus, Jouni Markkula, Artem Garmash, Vagan Y. Terziyan, Jari Veijalainen, Artem Katasonov, Henry Tirri
2000 conf
Data Mining and Knowledge Discovery: Theory, Tools, and Technology
Seppo Puuronen, Alexey Tsymbal, Vagan Y. Terziyan
2000 conf
IRMA Conference
Helen Kaikova, Vagan Y. Terziyan, Borys Omelayenko
1999 C conf
ISMIS
Seppo Puuronen, Vagan Y. Terziyan, Alexey Tsymbal
1999 conf
CIA
Seppo Puuronen, Vagan Y. Terziyan
1999 conf
DEXA Workshop
Seppo Puuronen, Vagan Y. Terziyan
1999 C conf
ADBIS
Alexey Tsymbal, Seppo Puuronen, Vagan Y. Terziyan
1999 conf
Data Mining and Knowledge Discovery: Theory, Tools, and Technology
Seppo Puuronen, Vagan Y. Terziyan, Artyom Katasonov, Alexey Tsymbal
1999 C conf
IEA/AIE
Vagan Y. Terziyan, Seppo Puuronen
1999 B conf
EKAW
Seppo Puuronen, Vagan Y. Terziyan
1999 B conf
CBMS
Irina Skrypnik, Vagan Y. Terziyan, Seppo Puuronen, Alexey Tsymbal
1999 C conf
DEXA
Seppo Puuronen, Vagan Y. Terziyan, Alexander Logvinovsky
1999 conf
DEXA Workshop
Seppo Puuronen, Vagan Y. Terziyan, Alexander Logvinovsky
1999 Misc conf
FLAIRS
Vladimir Ryabov, Seppo Puuronen, Vagan Y. Terziyan
1998 B conf
CBMS
Alexey Tsymbal, Seppo Puuronen, Vagan Y. Terziyan
1998 J jnl
Int. J. Medical Informatics
Vagan Y. Terziyan, Alexey Tsymbal, Seppo Puuronen
1997 B conf
CBMS
Vagan Y. Terziyan, Seppo Puuronen, Mikko Kovalainen
1997 conf
NGITS
Helen Kaikova, Vagan Y. Terziyan
1997 conf
HICSS (5)
Seppo Puuronen, Vagan Y. Terziyan
1996 conf
ER Workshop Challenges of Application and Challenges of Design
Seppo Puuronen, Vagan Y. Terziyan
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"