source: flexoentity/tests/test_id_stress.py@ 6ad031b

Last change on this file since 6ad031b was 6ad031b, checked in by Enrico Schwass <ennoausberlin@…>, 2 months ago

another round of domain refactoring

  • Property mode set to 100644
File size: 2.9 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
11
12from flexoentity import FlexOID, EntityType, EntityState
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
68
69def test_massive_lifecycle_simulation(sample_question):
70 """
71 Generate 100 random SingleChoiceQuestions, simulate multiple edits and state transitions,
72 ensure all final IDs and fingerprints are unique and valid.
73 """
74 entities = [
75 copy.deepcopy(sample_question) for _ in range(100)
76 ]
77
78 for i, e in enumerate(entities):
79 # random edit
80 e.text += f" updated #{i}"
81 e._update_fingerprint()
82
83 # lifecycle transitions
84 e.approve()
85 if random.random() > 0.3:
86 e.sign()
87 if random.random() > 0.6:
88 e.publish()
89
90 flexoids = [e.flexo_id for e in entities]
91 assert len(flexoids) == len(set(flexoids)), "Duplicate FlexOIDs after lifecycle simulation"
Note: See TracBrowser for help on using the repository browser.