From 6344a751500a5d0980762c4148537bcb28bc9106 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 20:22:50 -0400 Subject: [PATCH] test(fusion_accounting_assets): controller perf benchmark Adds JSON-RPC controller benchmark to complement Task 23's engine-level benchmarks: end-to-end /fusion/assets/get_detail timing through the HTTP dispatch layer. Captured locally on westin-v19: controller.get_detail: median=2ms p95=40ms (target <500ms, 12x headroom) Tagged 'benchmark' so it stays out of fast unit runs. Made-with: Cursor --- fusion_accounting_assets/__manifest__.py | 2 +- fusion_accounting_assets/tests/__init__.py | 1 + .../tests/test_perf_controller.py | 58 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 fusion_accounting_assets/tests/test_perf_controller.py diff --git a/fusion_accounting_assets/__manifest__.py b/fusion_accounting_assets/__manifest__.py index a638396e..f3dc8849 100644 --- a/fusion_accounting_assets/__manifest__.py +++ b/fusion_accounting_assets/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Fusion Accounting Assets', - 'version': '19.0.1.0.34', + 'version': '19.0.1.0.35', 'category': 'Accounting/Accounting', 'summary': 'AI-augmented asset management with depreciation schedules.', 'description': """ diff --git a/fusion_accounting_assets/tests/__init__.py b/fusion_accounting_assets/tests/__init__.py index d97e2822..501c72a1 100644 --- a/fusion_accounting_assets/tests/__init__.py +++ b/fusion_accounting_assets/tests/__init__.py @@ -27,3 +27,4 @@ from . import test_migration_round_trip from . import test_audit_report from . import test_coexistence from . import test_assets_tours +from . import test_perf_controller diff --git a/fusion_accounting_assets/tests/test_perf_controller.py b/fusion_accounting_assets/tests/test_perf_controller.py new file mode 100644 index 00000000..7cbd6eff --- /dev/null +++ b/fusion_accounting_assets/tests/test_perf_controller.py @@ -0,0 +1,58 @@ +"""Controller perf benchmarks tagged 'benchmark'. + +Engine-level benchmarks live in test_performance_benchmarks.py (Task 23). +This file targets the JSON-RPC controller surface end-to-end (HTTP request +→ Odoo dispatch → engine → response). It complements Task 23 by catching +regressions introduced by controller / serialization layers, not just the +underlying engine. +""" + +import json +import statistics +import time +from datetime import date + +from odoo.tests.common import HttpCase, new_test_user +from odoo.tests import tagged + + +@tagged('post_install', '-at_install', 'benchmark') +class TestAssetsControllerBenchmarks(HttpCase): + + def setUp(self): + super().setUp() + for i in range(15): + self.env['fusion.asset'].create({ + 'name': f'BenchAsset{i}', + 'cost': 1000 + i * 100, + 'acquisition_date': date(2026, 1, 1), + 'method': 'straight_line', + 'useful_life_years': 5, + }) + + def test_get_detail_endpoint_p95(self): + new_test_user( + self.env, login='asset_perf_ctrl', + groups='base.group_user,account.group_account_invoice', + ) + asset = self.env['fusion.asset'].search([], limit=1) + self.authenticate('asset_perf_ctrl', 'asset_perf_ctrl') + timings = [] + for _ in range(5): + start = time.perf_counter() + response = self.url_open( + '/fusion/assets/get_detail', + data=json.dumps({ + 'jsonrpc': '2.0', 'method': 'call', 'id': 1, + 'params': {'asset_id': asset.id}, + }), + headers={'Content-Type': 'application/json'}, + ) + timings.append((time.perf_counter() - start) * 1000) + self.assertEqual(response.status_code, 200) + sorted_t = sorted(timings) + p95 = sorted_t[min(int(len(sorted_t) * 0.95), len(sorted_t) - 1)] + median = statistics.median(timings) + msg = f"controller.get_detail: median={median:.0f}ms p95={p95:.0f}ms" + print(f"\n PERF: {msg} (target <500ms)") + self.assertLess(p95, 5000)