import json from pathlib import Path import subprocess import sys import tempfile from types import SimpleNamespace import unittest from unittest.mock import Mock, patch from cms import (CmsClient, ReadLatency, concurrent_reads, decode_response, execute, isolated_settings, latency_summary, publish_workload, run_postgres_case, run_postgres_rbac) from settings import write_private_json class CmsMeasurementTests(unittest.TestCase): def test_long_read_histogram_is_bounded_and_reports_upper_bounds(self): latency = ReadLatency() for _ in range(10000): latency.add(3) other = ReadLatency() other.add(100) latency.merge(other) self.assertEqual(len(latency.buckets), 2048) self.assertEqual(latency.count, 10001) self.assertGreaterEqual(latency.percentile(.99), 3) self.assertLess(latency.percentile(.99), 3.05) client = CmsClient(12345) client.record_timings = False client.connection = SimpleNamespace(request=Mock(), getresponse=Mock(return_value=SimpleNamespace( status=200, read=Mock(return_value=b'{"code":0,"message":"ok","data":1}'))), close=Mock()) try: self.assertEqual(client.request("GET", "/test"), 1) self.assertEqual(client.timings, {}) finally: client.close() def test_concurrent_read_failure_closes_clients_and_cannot_be_counted_as_success(self): expected = {"total": 1, "items": [{"title": "published"}]} for reply in ({"total": 0, "items": []}, RuntimeError("HTTP 403")): with self.subTest(reply=reply): opened = [] def client(_port): request = Mock(side_effect=reply) if isinstance(reply, Exception) else Mock(return_value=reply) instance = SimpleNamespace(cookies={}, timings={}, request=request, close=Mock()) opened.append(instance) return instance process = SimpleNamespace(samples=[], check=Mock()) with patch("cms.CmsClient", side_effect=client), patch("cms.observe"): with self.assertRaises(RuntimeError): concurrent_reads(12345, {"front": "test-only-cookie"}, expected, process, concurrency=2, seconds=.1, interval=.01) self.assertEqual(len(opened), 2) for instance in opened: instance.close.assert_called_once() def test_delete_inputs_use_query_instead_of_json_body(self): client = CmsClient(12345) response = SimpleNamespace(status=200, read=Mock(return_value=b'{"code":0,"message":"ok","data":true}')) connection = SimpleNamespace(request=Mock(), getresponse=Mock(return_value=response), close=Mock()) client.connection = connection try: self.assertIs(client.request("DELETE", "/revoke", {"user_id": 3, "role_id": "fixture reader"}), True) sent = connection.request.call_args.args self.assertEqual(sent[:3], ("DELETE", "/revoke?user_id=3&role_id=fixture+reader", None)) finally: client.close() def test_postgres_rbac_checks_catalog_roles_and_same_session_revocation(self): catalog = [ {"component": "news", "domain": "article", "site": "admin", "action": "list", "method": "GET", "key": "news.article.admin.list"}, {"component": "user", "domain": "authorization", "site": "admin", "action": "permissions", "method": "GET", "key": "user.authorization.admin.permissions"}, {"component": "news", "domain": "article", "site": "front", "action": "list", "method": "GET", "key": "news.article.front.list"}, ] identity = {"user_id": 1, "tenant_id": 2} member = {"user_id": 3, "tenant_id": 2, "credential_id": 4} login = [{"account": {"id": 3}, "tenant_id": 2, "site": site} for site in ("admin", "front")] for failure in (False, True): with self.subTest(failure=failure): owner = SimpleNamespace(request=Mock(side_effect=[ [entry for entry in catalog if entry["site"] == "admin"], [entry for entry in catalog if entry["site"] == "front"], ] + [True] * 9)) responses = login + ([RuntimeError("missing denial")] if failure else [None] * 11) client = SimpleNamespace(request=Mock(side_effect=responses), close=Mock()) with patch("cms.execute", return_value=member), patch("cms.CmsClient", return_value=client): if failure: with self.assertRaisesRegex(RuntimeError, "missing denial"): run_postgres_rbac(Path("owned-app"), Path("owned-output"), 12345, owner, identity) else: result = run_postgres_rbac(Path("owned-app"), Path("owned-output"), 12345, owner, identity) self.assertEqual(result["member_user_id"], 3) self.assertEqual(set(result["permissions"]), {"admin_read", "admin_permissions", "front_list"}) self.assertNotIn("password", result) calls = client.request.call_args_list[2:] self.assertEqual([call.kwargs.get("expected", 200) for call in calls], [403, 403, 403, 200, 200, 200, 403, 200, 200, 403, 403]) saves = [call for call in owner.request.call_args_list if call.args[1].endswith("/save")] self.assertEqual(owner.request.call_args_list[1].kwargs["site"], "front") self.assertEqual(saves[0].args[2]["id"], saves[2].args[2]["id"]) self.assertNotEqual(saves[0].kwargs["site"], saves[2].kwargs["site"]) client.close.assert_called_once() def test_postgres_case_keeps_source_configuration_on_build_failure(self): with tempfile.TemporaryDirectory(prefix="dever-cms-source-") as temporary: directory = Path(temporary) source = directory / "project" source.mkdir() for name in ("config", "module", "test"): (source / name).mkdir() original = { "runtime": {"mode": "all"}, "database": {"default": { "type": "postgres", "url": "postgres://fixture@127.0.0.1:12345/control", "tenant_database_prefix": "dever_test_owned", }}, "auth": {"providers": {"session": {"jwtSecret": "original"}}}, "sites": {}, "log": {"level": "info"}, } setting = source / "config/setting.json" write_private_json(setting, original) before = setting.read_bytes() staged_paths = [] def fail_check(command, *_args, **_kwargs): staged = command[2] staged_paths.append(staged) self.assertNotEqual(staged, source) changed = json.loads((staged / "config/setting.json").read_text()) self.assertEqual(changed["runtime"]["mode"], "api") self.assertNotEqual(changed["auth"]["providers"]["session"]["jwtSecret"], "original") raise RuntimeError("owned check failed") output = directory / "result" with patch("cms.execute", side_effect=fail_check): with self.assertRaisesRegex(RuntimeError, "owned check failed"): run_postgres_case(source, output, directory / "compiler", articles=2) self.assertEqual(setting.read_bytes(), before) self.assertFalse((source / "cms-app").exists()) self.assertTrue(staged_paths) self.assertFalse(staged_paths[0].exists()) self.assertEqual(json.loads((output / "report.json").read_text())["status"], "failed") def test_private_config_replacement_is_atomic_and_keeps_exclusive_creation(self): with tempfile.TemporaryDirectory(prefix="dever-cms-setting-") as temporary: directory = Path(temporary) setting = directory / "setting.json" write_private_json(setting, {"original": True}) with self.assertRaises(FileExistsError): write_private_json(setting, {"overwrite": True}) with self.assertRaises(TypeError): write_private_json(setting, {"invalid": object()}, replace=True) self.assertEqual(json.loads(setting.read_text()), {"original": True}) self.assertEqual(list(directory.iterdir()), [setting]) write_private_json(setting, {"postgres": True}, replace=True) self.assertEqual(json.loads(setting.read_text()), {"postgres": True}) self.assertEqual(setting.stat().st_mode & 0o777, 0o600) self.assertEqual(list(directory.iterdir()), [setting]) def test_envelope_failure_cannot_count_as_publication(self): self.assertEqual(decode_response(b'{"code":0,"message":"ok","data":{"id":1}}', 200), {"id": 1}) for document, status in (({"code": 0, "message": "ok", "data": {}}, 500), ({"code": 409, "message": "conflict", "data": None}, 200), ({"id": 1}, 200)): with self.assertRaises(RuntimeError): decode_response(json.dumps(document).encode(), status) def test_isolation_preserves_site_contract_without_mutating_input(self): source = { "runtime": {"mode": "all"}, "http": {"port": 8080}, "database": {"default": {"type": "sqlite", "path": "old.db"}}, "auth": {"providers": {"session": {"jwtSecret": "example", "verify": "user.account.verify"}}}, "sites": {"admin": {"path": "admin", "auth": "session", "origin": "https://example.invalid"}}, "log": {"level": "info"}, } staged = isolated_settings(source, 12345) self.assertEqual(source["runtime"]["mode"], "all") self.assertEqual(source["database"]["default"]["path"], "old.db") self.assertEqual(staged["runtime"]["mode"], "api") self.assertEqual(staged["sites"]["admin"]["path"], "admin") self.assertEqual(staged["sites"]["admin"]["origin"], "http://127.0.0.1:12345") self.assertNotEqual(staged["auth"]["providers"]["session"]["jwtSecret"], "example") self.assertEqual(staged["auth"]["providers"]["session"]["verify"], "user.account.verify") self.assertEqual(source["log"]["level"], "info") self.assertEqual(staged["log"]["level"], "error") source["database"]["default"]["type"] = "postgres" with self.assertRaises(RuntimeError): isolated_settings(source, 12345) def test_postgres_isolation_preserves_explicit_control_database_and_prefix(self): source = { "runtime": {"mode": "all"}, "database": {"default": { "type": "postgres", "url": "postgres://fixture@127.0.0.1:12345/control", "tenant_database_prefix": "dever_test_owned", "tls": "disabled", }}, "auth": {"providers": {"session": {"jwtSecret": "example"}}}, "sites": {"admin": {"origin": "https://example.invalid"}}, "log": {"level": "info"}, } staged = isolated_settings(source, 23456) self.assertEqual(staged["database"], source["database"]) self.assertEqual(staged["http"], {"host": "127.0.0.1", "port": 23456}) self.assertNotIn("path", staged["database"]["default"]) source["database"]["default"].pop("tenant_database_prefix") with self.assertRaises(RuntimeError): isolated_settings(source, 23456) def test_publish_workload_uses_tenant_and_title_parameters(self): identity = {"credential_id": 11, "user_id": 3, "tenant_id": 2} publication = {"slug": "bench-0", "title": "Tenant A 0 published", "body": "Published body"} client = SimpleNamespace(request=Mock(side_effect=[ {"account": {"id": 3}, "tenant_id": 2, "site": "admin"}, {"account": {"id": 3}, "tenant_id": 2, "site": "front"}, {"id": 1, "slug": "bench-0", "title": "Tenant A 0", "version": 1}, {"id": 7, "article_id": 1, "title": "Tenant A 0 published", "version": 2}, publication, {"total": 1, "items": [publication]}, None, ])) process = SimpleNamespace(sample=Mock()) contract = publish_workload(client, process, identity, "fixture-password", 1, tenant_key="tenant_a", title_prefix="Tenant A") self.assertEqual(contract, {"articles": 1, "titles": ["Tenant A 0 published"], "duplicate_publish_status": 409}) for call in client.request.call_args_list[:2]: self.assertEqual(call.args[2]["tenant"], "tenant_a") revision = client.request.call_args_list[3] self.assertEqual(revision.args[:2], ("POST", "/content/revision/admin/manage/create")) self.assertEqual(revision.args[2]["expected_version"], 1) self.assertEqual(revision.args[2]["selected_article_id"], 1) self.assertEqual(process.sample.call_count, 1) def test_small_workload_reports_samples_without_implying_p99(self): self.assertEqual(latency_summary({"publish": [4, 1, 3]}), {"publish": {"samples": 3, "p50_ms": 3, "max_ms": 4}}) def test_command_timeout_retains_output_and_reaps_its_owned_process(self): with tempfile.TemporaryDirectory(prefix="dever-cms-timeout-") as temporary: directory = Path(temporary) command = [sys.executable, "-u", "-c", "import time,sys; print('starting'); print('diagnostic',file=sys.stderr); time.sleep(10)"] with self.assertRaises(subprocess.TimeoutExpired): execute(command, directory, "timeout", timeout=0.2) self.assertEqual((directory / "timeout.stdout.log").read_text(), "starting\n") self.assertEqual((directory / "timeout.stderr.log").read_text(), "diagnostic\n") if __name__ == "__main__": unittest.main()