source: flexoentity/tests/test_id_stress.py@ 4e11d58

Last change on this file since 4e11d58 was ef964d8, checked in by Enrico Schwass <ennoausberlin@…>, 7 weeks ago

new serialization structure adopted and tests fixed

  • Property mode set to 100644
File size: 3.3 KB
RevLine 
[59342ce]1"""
2Stress tests for the Flex-O ID lifecycle.
3Focus: collision avoidance, version ceiling, reproducibility.
4"""
[02d288d]5
[8aa20c7]6import copy
[02d288d]7import logging
[8aa20c7]8import random
9
10import pytest
[ef964d8]11from uuid import uuid4
12from flexoentity import FlexOID, EntityType, EntityState, FlexoSignature
[59342ce]13
[02d288d]14logger = logging.getLogger(__name__)
[2f650ac]15
[6ad031b]16def test_bulk_generation_uniqueness(sample_domain):
[02d288d]17 """
[4ceca57]18 Generate 100,000 IDs and ensure uniqueness using safe_generate().
[02d288d]19 If a collision occurs, safe_generate() must resolve it automatically
20 via salt + date adjustment.
21 """
[8aa20c7]22 entity_type = EntityType.ITEM
[59342ce]23 estate = EntityState.DRAFT
[4ceca57]24 seeds = [f"question {i}" for i in range(100000)]
[02d288d]25
26 # Simulate a simple in-memory repository for collision detection
27 repo = {}
28
29 def repo_get(oid_str):
30 return repo.get(str(oid_str))
[59342ce]31
[02d288d]32 # Generate IDs using safe_generate
33 ids = []
34 for seed in seeds:
[6ad031b]35 oid = FlexOID.safe_generate(sample_domain.domain_id, entity_type.value,
36 estate.value, seed, repo=repo)
[02d288d]37 assert isinstance(oid, FlexOID)
38 ids.append(str(oid))
39 repo[str(oid)] = oid # register for future collision detection
[59342ce]40
[02d288d]41 unique_count = len(set(ids))
42 total_count = len(ids)
43 collisions = total_count - unique_count
[59342ce]44
[02d288d]45 logger.info(f"Generated {total_count} IDs ({collisions} collisions handled).")
[8a238e2]46
[02d288d]47 # Assert that safe_generate avoided duplicates
48 assert total_count == unique_count, f"Unexpected duplicate IDs ({collisions} found)"
49
50 # Sanity check: IDs should look canonical
[6ad031b]51 # assert all(id_str.startswith("GENERIC") for id_str in ids)
[02d288d]52 assert all("@" in id_str for id_str in ids)
53
[6ad031b]54def test_id_generation_is_deterministic(sample_domain):
[8a238e2]55 """
56 Generating the same entity twice with same inputs yields identical ID.
57 (No runtime disambiguation; IDs are deterministic by design.)
58 """
[8aa20c7]59 entity_type = EntityType.ITEM
[8a238e2]60 estate = EntityState.DRAFT
61 text = "identical question text"
[02d288d]62
[6ad031b]63 id1 = FlexOID.generate(sample_domain.domain_id, entity_type.value, estate.value, text)
64 id2 = FlexOID.generate(sample_domain.domain_id, entity_type.value, estate.value, text)
[02d288d]65 # IDs must be identical because generation is deterministic
[8a238e2]66 assert id1 == id2
67
[ef964d8]68def test_massive_lifecycle_simulation(cert_ref_linux, sample_domain):
[59342ce]69 """
[ef964d8]70 Generate 100 random FlexoSignatures, mutate content, run through lifecycle,
71 and ensure all FlexOIDs are unique and valid.
[59342ce]72 """
[ef964d8]73 entities = []
74
75 for i in range(100):
76 sig = FlexoSignature.with_domain_id(
77 domain_id="SIGTEST",
78 signed_entity=sample_domain.flexo_id,
79 signer_id=uuid4(),
80 certificate_reference=cert_ref_linux,
81 comment=f"Initial signature #{i}"
82 )
83 entities.append(sig)
84
85 # Mutate + lifecycle transitions
[8aa20c7]86 for i, e in enumerate(entities):
[ef964d8]87 # CONTENT CHANGE → fingerprint changes → hash → FlexOID.prefix changes
88 e.comment += f" updated-{i}"
[8a238e2]89 e._update_fingerprint()
[02d288d]90
91 # lifecycle transitions
[59342ce]92 e.approve()
93 if random.random() > 0.3:
94 e.sign()
95 if random.random() > 0.6:
96 e.publish()
97
[ef964d8]98 # Check ID uniqueness
99 flexoids = [str(e.flexo_id) for e in entities]
100 assert len(flexoids) == len(set(flexoids)), "Duplicate FlexOIDs detected"
Note: See TracBrowser for help on using the repository browser.