fixtureqa 0.9.0__tar.gz → 0.9.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. {fixtureqa-0.9.0/fixtureqa.egg-info → fixtureqa-0.9.1}/PKG-INFO +1 -1
  2. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/perf.py +31 -0
  3. fixtureqa-0.9.0/fixture/static/assets/index-D2BF3qaF.js → fixtureqa-0.9.1/fixture/static/assets/index-CbJP_HMn.js +17 -17
  4. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/index.html +1 -1
  5. {fixtureqa-0.9.0 → fixtureqa-0.9.1/fixtureqa.egg-info}/PKG-INFO +1 -1
  6. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixtureqa.egg-info/SOURCES.txt +1 -1
  7. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/pyproject.toml +1 -1
  8. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_perf_api.py +21 -0
  9. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/LICENSE +0 -0
  10. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/README.md +0 -0
  11. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/__init__.py +0 -0
  12. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/__main__.py +0 -0
  13. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/__init__.py +0 -0
  14. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/app.py +0 -0
  15. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/connection_manager.py +0 -0
  16. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/deps.py +0 -0
  17. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/__init__.py +0 -0
  18. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/admin.py +0 -0
  19. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/auth.py +0 -0
  20. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/branding.py +0 -0
  21. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/custom_tags.py +0 -0
  22. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/fix_spec.py +0 -0
  23. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/messages.py +0 -0
  24. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/scenarios.py +0 -0
  25. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/sessions.py +0 -0
  26. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/setup.py +0 -0
  27. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/spec_overlay.py +0 -0
  28. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/templates.py +0 -0
  29. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/routers/ws.py +0 -0
  30. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/api/schemas.py +0 -0
  31. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/config/__init__.py +0 -0
  32. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/__init__.py +0 -0
  33. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/atomic_io.py +0 -0
  34. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/auth.py +0 -0
  35. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/config_store.py +0 -0
  36. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/custom_tag_store.py +0 -0
  37. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/db_migrations.py +0 -0
  38. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/events.py +0 -0
  39. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_application.py +0 -0
  40. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_builder.py +0 -0
  41. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_parser.py +0 -0
  42. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_spec_parser.py +0 -0
  43. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_tags.py +0 -0
  44. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/fix_time.py +0 -0
  45. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/housekeeping.py +0 -0
  46. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/inbound.py +0 -0
  47. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/json_store.py +0 -0
  48. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/latency_csv_writer.py +0 -0
  49. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/message_log.py +0 -0
  50. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/message_store.py +0 -0
  51. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/models.py +0 -0
  52. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_charts.py +0 -0
  53. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_engine.py +0 -0
  54. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_models.py +0 -0
  55. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_payload.py +0 -0
  56. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_stats.py +0 -0
  57. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_store.py +0 -0
  58. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/perf_writer.py +0 -0
  59. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/scenario_runner.py +0 -0
  60. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/scenario_store.py +0 -0
  61. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/session.py +0 -0
  62. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/session_manager.py +0 -0
  63. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/spec_overlay_store.py +0 -0
  64. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/template_store.py +0 -0
  65. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/user_store.py +0 -0
  66. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/value_gen.py +0 -0
  67. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/core/venue_responses.py +0 -0
  68. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/fix_specs/FIX42.xml +0 -0
  69. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/fix_specs/FIX44.xml +0 -0
  70. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/server.py +0 -0
  71. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/assets/ag-grid-_QKprVdm.js +0 -0
  72. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/assets/index-B-hpSZWZ.css +0 -0
  73. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/assets/index-CyNOPa0n.js +0 -0
  74. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/assets/react-vendor-2eF0YfZT.js +0 -0
  75. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/static/favicon.svg +0 -0
  76. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixture/ui/__init__.py +0 -0
  77. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixtureqa.egg-info/dependency_links.txt +0 -0
  78. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixtureqa.egg-info/entry_points.txt +0 -0
  79. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixtureqa.egg-info/requires.txt +0 -0
  80. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/fixtureqa.egg-info/top_level.txt +0 -0
  81. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/setup.cfg +0 -0
  82. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_atomic_io.py +0 -0
  83. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_auth.py +0 -0
  84. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_config_store.py +0 -0
  85. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_connection_manager.py +0 -0
  86. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_db_migrations.py +0 -0
  87. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_fix_builder.py +0 -0
  88. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_health.py +0 -0
  89. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_inbound.py +0 -0
  90. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_inbound_validation.py +0 -0
  91. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_message_store.py +0 -0
  92. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_non_stop_session.py +0 -0
  93. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_perf_engine.py +0 -0
  94. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_perf_models.py +0 -0
  95. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_perf_payload.py +0 -0
  96. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_perf_rehydrate.py +0 -0
  97. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_scenarios.py +0 -0
  98. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_session_auto_response.py +0 -0
  99. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_session_lifecycle.py +0 -0
  100. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_session_manager_concurrency.py +0 -0
  101. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_sessions.py +0 -0
  102. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_templates.py +0 -0
  103. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_timezone_data.py +0 -0
  104. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_value_gen.py +0 -0
  105. {fixtureqa-0.9.0 → fixtureqa-0.9.1}/tests/test_ws.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fixtureqa
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: FIXture — FIX Protocol Testing Tool
5
5
  Requires-Python: >=3.10
6
6
  License-File: LICENSE
@@ -53,6 +53,18 @@ _TERMINAL = ("completed", "stopped", "error")
53
53
  # up front (before the run starts) rather than wedging the server.
54
54
  DURABLE_SAFE_MSG_RATE = 30 # messages/second a logged/durable session can sustain
55
55
 
56
+ # Session configs that add work to the per-message hot path on the event loop —
57
+ # they distort (or, for check_latency, can outright reject messages and corrupt)
58
+ # the very latency a perf run measures. Unlike durable persistence there is no
59
+ # rate at which they're safe, so a run that drives a session with any of them on
60
+ # is refused up front. (label, why) — the Performance-session toggle in the
61
+ # session modal clears all of them.
62
+ _PERF_HOSTILE_KEYS: tuple[tuple[str, str], ...] = (
63
+ ("validate_inbound", "validates every inbound message against the spec on the loop"),
64
+ ("check_latency", "parses SendingTime(52) and may reject messages on the loop"),
65
+ ("enable_last_msg_seq_num_processed", "stamps LastMsgSeqNumProcessed(369) on every outbound message"),
66
+ )
67
+
56
68
 
57
69
  def _order_rate_per_s(body: RunConfig) -> float:
58
70
  r = body.rate
@@ -144,6 +156,25 @@ async def create_run(body: RunConfig, sm: SM, reg: REG, ts: TS, admin: Admin):
144
156
  f"~{safe_order_rate:.0f} orders/s (~{DURABLE_SAFE_MSG_RATE} msg/s) — at "
145
157
  f"higher rates the event loop stalls on per-message fsync/DB writes")
146
158
 
159
+ # Per-message latency guard — BEFORE reg.create(). Refuse outright if any
160
+ # driven session has a perf-hostile key on: these add work to the per-message
161
+ # hot path on the event loop (or reject messages outright) and distort the
162
+ # latency the run exists to measure. No safe rate, so unlike the durability
163
+ # guard this is a hard refusal rather than a throttle.
164
+ offenders = [
165
+ (label, attr, why)
166
+ for label, cfg in participating
167
+ for attr, why in _PERF_HOSTILE_KEYS
168
+ if getattr(cfg, attr, False)
169
+ ]
170
+ if offenders:
171
+ detail = "; ".join(f"{label} session has {attr} on ({why})"
172
+ for label, attr, why in offenders)
173
+ raise HTTPException(status_code=409, detail=(
174
+ f"Refusing to start: {detail}. These add per-message work on the event "
175
+ f"loop and distort latency measurement — turn them off (or tick "
176
+ f"'Performance session' in the session modal) before running a perf test."))
177
+
147
178
  # CompIDs from the driving (client, else venue) session — for template tokens.
148
179
  drive_sid = body.client_session_id if need_client else body.venue_session_id
149
180
  dcfg = sm.get_state(drive_sid).config