datasette/tests
Claude 1bc15caef7
Connection budget: pages, startup and sweeps only touch the databases they need
Adds tests/connection_budget.py, a helper that records which databases a
block of code opens, reads, writes or ATTACHes, and tests/test_connection_budget.py
which asserts budgets for ~60 endpoints, startup, sweeps and telemetry with
50 attached databases.

Fixes for every all-database loop it found:

- Index page: tables, views, hidden tables, columns, primary keys, FTS
  tables and foreign-key relationship counts come from the _internal
  catalog (a few queries for any number of databases). Row counts are only
  run when at most 20 databases need counting (COUNT_MAX_DATABASES);
  above that the page shows table counts plus counts already known.
- Derived-table permissions: allowed_resources() no longer queries every
  database per page; dependency maps are computed by the SchemaWatcher from
  the rows it scans, cached per database, and read back from the catalog
  for databases restored from a persisted catalog.
- catalog_tables gains a type column (PRAGMA table_list: table, virtual,
  shadow) so hidden shadow tables can be identified without a connection.
- PaginatedResources.all() fetches pages of 1000 after the first.
- /-/api and /-/debug/autocomplete use the catalog; /-/schema does one
  permission query and skips databases with nothing visible.
- /-/versions computes SQLite details once per instance, without crossdb
  ATTACHes; detect_json1() caches its answer.
- /-/databases only stats/hashes databases the actor can see.
- Immutable table counts are computed when first needed, not at startup.
- check_databases() (serve, --get) reuses the catalog scan instead of
  opening every database a second time, and reports "file is not a
  database" as a usage error.
- SchemaWatcher: failed scans are retried when the file changes, not on
  every sweep; scan connections skip crossdb ATTACH; catalog_generation
  counter for caches.
- The SQL write UI no longer forces a stat sweep of every database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwkLo2rJWidpkDVT3HkvNv
2026-10-04 05:58:31 +00:00
..
plugins Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_templates Fix handling of nested custom page wildcard paths, closes #996 2020-10-07 15:51:11 -07:00
__init__.py Broke up test_app into test_api and test_html 2017-12-15 04:08:24 -08:00
build_small_spatialite_db.py New run_sanity_checks mechanism, for SpatiLite 2019-05-11 15:55:30 -07:00
conftest.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
connection_budget.py Connection budget: pages, startup and sweeps only touch the databases they need 2026-10-04 05:58:31 +00:00
ext.c Add new entrypoint option to --load-extensions. (#1789) 2022-08-23 11:34:30 -07:00
fixtures.py Fix remaining pytest warnings (#2928) 2026-09-16 14:50:06 -07:00
spatialite.db New run_sanity_checks mechanism, for SpatiLite 2019-05-11 15:55:30 -07:00
test-datasette-load-plugins.sh fix (typo): Corrected spelling of 'environments' (#2268) 2024-02-19 14:41:32 -08:00
test_actions_sql.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_actor_restriction_bug.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_allowed_many.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_allowed_resources.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_api.py Merge spike/schema-watcher into spike/integrated, reconciling the three spikes 2026-10-04 04:49:04 +00:00
test_api_write.py Fix for GHSA-h547-rmjf-5m2m 2026-09-16 16:43:34 -07:00
test_auth.py Refuse API token creation from restricted actors 2026-09-09 08:38:40 -07:00
test_autocomplete.py Add "ok": true to every JSON object success response 2026-07-04 13:40:05 +00:00
test_background_tasks.py Add datasette.add_background_task() with supervised launch after startup (#2889) 2026-09-15 10:55:54 -07:00
test_base_view.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_cli.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_cli_serve_get.py Add datasette.add_background_task() with supervised launch after startup (#2889) 2026-09-15 10:55:54 -07:00
test_cli_serve_server.py Fix remaining pytest warnings (#2928) 2026-09-16 14:50:06 -07:00
test_column_types.py Fix remaining pytest warnings (#2928) 2026-09-16 14:50:06 -07:00
test_config_dir.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_config_permission_rules.py Run black formatter 2025-10-25 15:38:07 -07:00
test_connection_budget.py Connection budget: pages, startup and sweeps only touch the databases they need 2026-10-04 05:58:31 +00:00
test_connection_leases.py Keep num_sql_threads=0 thread-free and refresh_schemas loop-agnostic 2026-10-04 04:57:33 +00:00
test_crossdb.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_csrf_middleware.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_csv.py Return CSV errors as plain text, closes #2129 2026-09-15 15:53:10 -07:00
test_custom_pages.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_datasette_https_server.sh More robust test_datasette_https_server.sh test 2026-06-22 10:11:56 -07:00
test_debug_autocomplete.py Autocomplete widget and /-/debug/autocomplete test page 2026-06-13 22:59:37 -07:00
test_default_deny.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_docs.py Use cog to show default values in settings.rst 2026-09-17 12:30:47 -07:00
test_docs_plugins.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_error_shape.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_extras.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_facets.py Don't 500 on ?_facets=x 2026-09-24 11:34:45 -07:00
test_fd_leak.py FD-leak regression test for Datasette.close() 2026-04-16 20:18:05 -07:00
test_filters.py Fix for SQL injection issue in table filters, refs #2868 2026-08-06 11:19:50 -07:00
test_fixtures.py datasette.fixtures module, closes #2733 2026-05-21 23:05:37 -07:00
test_fts_permissions.py Connection budget: pages, startup and sweeps only touch the databases they need 2026-10-04 05:58:31 +00:00
test_html.py Fix missing space before the view count on the index page (#2951) 2026-09-24 11:50:01 -07:00
test_http_span.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
test_internal_db.py Connection budget: pages, startup and sweeps only touch the databases they need 2026-10-04 05:58:31 +00:00
test_internals_database.py Lease proxies for write and isolated callbacks; close() never frees a busy connection 2026-10-04 04:51:51 +00:00
test_internals_datasette.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_internals_datasette_client.py Migrate from httpx to httpx2, closes #2879 2026-09-10 19:44:49 -07:00
test_internals_request.py Make request header lookups case-insensitive 2026-09-16 10:27:35 -07:00
test_internals_response.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_internals_urls.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_jump.py Autocomplete widget and /-/debug/autocomplete test page 2026-06-13 22:59:37 -07:00
test_label_column_for_table.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_lifespan.py Connection budget: pages, startup and sweeps only touch the databases they need 2026-10-04 05:58:31 +00:00
test_load_extensions.py Disable extension loading once --load-extension extensions are loaded 2026-09-08 10:48:19 -07:00
test_messages.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_multipart.py Fix remaining pytest warnings (#2928) 2026-09-16 14:50:06 -07:00
test_numeric_filter_values.py Fix remaining pytest warnings (#2928) 2026-09-16 14:50:06 -07:00
test_package.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_permission_endpoints.py Require view-instance permission for /-/allowed 2026-09-08 10:48:19 -07:00
test_permissions.py Add /-/tasks introspection endpoint for supervised background tasks (#2892) 2026-09-15 11:56:53 -07:00
test_playwright.py Rename modal trigger option to returnFocusTo, refs #2790 2026-09-17 15:46:34 -07:00
test_plugins.py Allow extra_template_vars to resolve to None 2026-09-16 10:30:11 -07:00
test_pr76_fts_policy.py Limit derived-table permissions to one source hop 2026-09-10 16:52:52 -07:00
test_pr76_statistics_policy.py Deny SQLite statistics table access through a default hook 2026-09-10 16:52:25 -07:00
test_publish_cloudrun.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_publish_heroku.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_pytest_autoclose_plugin.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_queries.py execute-write: Check view-table for every table in a CREATE VIEW 2026-09-08 10:48:19 -07:00
test_read_pool.py Merge spike/schema-watcher into spike/integrated, reconciling the three spikes 2026-10-04 04:49:04 +00:00
test_restriction_sql.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_routes.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_schema_endpoints.py Only allow /db/name/-/schema against tables and views 2026-09-08 10:48:20 -07:00
test_schema_watcher.py Merge spike/schema-watcher into spike/integrated, reconciling the three spikes 2026-10-04 04:49:04 +00:00
test_search_tables.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_shutdown.py Add shutdown() plugin hook with ordered graceful teardown (#2890) 2026-09-15 11:09:57 -07:00
test_spatialite.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_stored_queries.py Protect personalized dynamic responses from shared caching 2026-09-08 21:16:36 -07:00
test_success_envelope.py Add /-/tasks introspection endpoint for supervised background tasks (#2892) 2026-09-15 11:56:53 -07:00
test_table_api.py Authorize configured full-text search targets 2026-09-08 21:16:35 -07:00
test_table_count.py Tests for table count endpoint, refs #2914 2026-09-15 12:21:36 -07:00
test_table_html.py Case insensitive check for foreign key tables 2026-09-24 12:10:42 -07:00
test_table_resource_identity.py Match table permission identities using SQLite case semantics 2026-09-09 08:39:03 -07:00
test_tasks_endpoint.py Add /-/tasks introspection endpoint for supervised background tasks (#2892) 2026-09-15 11:56:53 -07:00
test_telemetry.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
test_telemetry_metrics.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
test_telemetry_registry.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
test_telemetry_testing_kit.py Simplify code comments added since 1.0a40 (#2957) 2026-09-24 13:52:29 -07:00
test_template_context.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_token_handler.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_tracer.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_utils.py Fix for GHSA-h547-rmjf-5m2m 2026-09-16 16:43:34 -07:00
test_utils_check_callable.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_utils_permissions.py Upgrade to ruff>=0.16.0 (#2857) 2026-07-25 15:47:08 -07:00
test_utils_sql_analysis.py Fix CREATE VIEW analysis on Python 3.10 2026-09-08 10:49:52 -07:00
test_write_sql_operation_decisions.py Refactored write decision tests 2026-05-28 12:09:20 -07:00
test_write_thread_idle.py Merge spike/schema-watcher into spike/integrated, reconciling the three spikes 2026-10-04 04:49:04 +00:00
test_write_wrapper.py Keep alter-table changes rollbackable by write wrappers 2026-09-16 14:40:50 -07:00
utils.py From 409 warnings down to 52 warnings. 2026-04-14 18:46:47 -07:00