source: flexoentity/tests/test_id_stress.py@ ef964d8

Last change on this file since ef964d8 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
Line 
1"""
2Stress tests for the Flex-O ID lifecycle.
3Focus: collision avoidance, version ceiling, reproducibility.
4"""
5
6import copy
7import logging
8import random
9
10import pytest
11from uuid import uuid4
12from flexoentity import FlexOID, EntityType, EntityState, FlexoSignature
13
14logger = logging.getLogger(__name__)
15
16def test_bulk_generation_uniqueness(sample_domain):
17 """
18 Generate 100,000 IDs and ensure uniqueness using safe_generate().
19 If a collision occurs, safe_generate() must resolve it automatically
20 via salt + date adjustment.
21 """
22 entity_type = EntityType.ITEM
23 estate = EntityState.DRAFT
24 seeds = [f"question {i}" for i in range(100000)]
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))
31
32 # Generate IDs using safe_generate
33 ids = []
34 for seed in seeds:
35 oid = FlexOID.safe_generate(sample_domain.domain_id, entity_type.value,
36 estate.value, seed, repo=repo)
37 assert isinstance(oid, FlexOID)
38 ids.append(str(oid))
39 repo[str(oid)] = oid # register for future collision detection
40
41 unique_count = len(set(ids))
42 total_count = len(ids)
43 collisions = total_count - unique_count
44
45 logger.info(f"Generated {total_count} IDs ({collisions} collisions handled).")
46
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
51 # assert all(id_str.startswith("GENERIC") for id_str in ids)
52 assert all("@" in id_str for id_str in ids)
53
54def test_id_generation_is_deterministic(sample_domain):
55 """
56 Generating the same entity twice with same inputs yields identical ID.
57 (No runtime disambiguation; IDs are deterministic by design.)
58 """
59 entity_type = EntityType.ITEM
60 estate = EntityState.DRAFT
61 text = "identical question text"
62
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)
65 # IDs must be identical because generation is deterministic
66 assert id1 == id2
67
68def test_massive_lifecycle_simulation(cert_ref_linux, sample_domain):
69 """
70 Generate 100 random FlexoSignatures, mutate content, run through lifecycle,
71 and ensure all FlexOIDs are unique and valid.
72 """
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
86 for i, e in enumerate(entities):
87 # CONTENT CHANGE → fingerprint changes → hash → FlexOID.prefix changes
88 e.comment += f" updated-{i}"
89 e._update_fingerprint()
90
91 # lifecycle transitions
92 e.approve()
93 if random.random() > 0.3:
94 e.sign()
95 if random.random() > 0.6:
96 e.publish()
97
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.