Skip to content

fix(testnet/homeserver)!: DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param - #500

Merged
86667 merged 12 commits into
mainfrom
docker_postgres_shared_new_tables_per_test
Aug 26, 2026
Merged

fix(testnet/homeserver)!: DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param#500
86667 merged 12 commits into
mainfrom
docker_postgres_shared_new_tables_per_test

Conversation

@86667

@86667 86667 commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

The idea behind DockerPostgres::shared() is that the work of downloading, building and starting up Postgres shouldn't need to be done for each testnet which needs to use the Postgres instance. For example, in a test suite in which each test requires its own testnet.

The existing behaviour was that the Postgres instance and database was being shared. The fix here is to share the Postgres instance but give each test a fresh, ephemeral database.

These changes motivated a re-write of how databse urls are set, as the logic was spread across different places and behaviour not well-defined.

Previously we configured ephemeral database by a ?pubky-test=true query parameter in the connection URL, a fragile convention that is easy to forget and adds confusion. We replaced it with a DatabaseMode enum that is resolved at startup based on compile-time cfg flags. In test builds you always get EphemeralTest, in production you always get Direct. The URL is now just a server address, it no longer carries behavioral intent.

We also change database_url from ConnectionString to Option<ConnectionString>. Test configs set it to None, deferring resolution to the env var or built-in default. Explicit urls (e.g. Docker Postgres) are Some and used as-is. Production builds throw and error if None.

The priority for database URL resolution in test builds is:

  • Explicit URL set in config (e.g. from Docker Postgres or config.toml)
  • TEST_PUBKY_CONNECTION_STRING env var
  • Built-in test default

@86667 86667 changed the title fix: DockerPostgres::shared() to share Postgres instance but isolated databases fix: DockerPostgres::shared() to share Postgres instance but isolate databases Jul 16, 2026
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch 2 times, most recently from 68748c7 to 995e5fc Compare July 21, 2026 15:21
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from 995e5fc to 1d77cc7 Compare July 27, 2026 16:04
@86667 86667 changed the title fix: DockerPostgres::shared() to share Postgres instance but isolate databases fix: DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param Jul 28, 2026
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from 9a19656 to 18a8833 Compare July 28, 2026 14:19
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from 18a8833 to 457cbed Compare August 10, 2026 14:32
@86667 86667 changed the title fix: DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param fix(testnet/homeserver): DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param Aug 10, 2026
@86667 86667 changed the title fix(testnet/homeserver): DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param fix(testnet/homeserver)!: DockerPostgres::shared() to share Postgres instance but isolate databases and remove pubky-test URL query param Aug 10, 2026
@86667
86667 requested review from MCarlomagno and andrei-21 August 10, 2026 14:38
Comment thread pubky-homeserver/src/app_context.rs Outdated
Comment thread .github/workflows/pr-check.yml
Comment thread pubky-homeserver/src/persistence/sql/database_mode.rs Outdated
Comment thread pubky-homeserver/src/app_context.rs Outdated
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from 457cbed to 20b30f7 Compare August 13, 2026 10:03
@86667

86667 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator Author

@MCarlomagno @ok300

Thanks both for review and finding that issue. My bad - I must have made the removal of ?pubky-testnet=true change after testing the persistent StaticTestnet, then not re-tested after.

I have removed the "ephemeral db" decision from the testing cfg and instead drive it off of DataDir. Ie, If a data dir is persisted then so is the db, if datat dir is not persisted then neither is the db.

Im going to look into refactoring the whole DataDir trait with MockDataDir and PersistentDataDir implementors. I dont find it a clean abstraction. I didnt want to make this PR any larger though so used what i had.

@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from 20b30f7 to b4100e7 Compare August 24, 2026 11:00
if config_toml.general.database_url.is_test_db() {
// In test builds, no explicit database_url means we're in a test environment
// where we must avoid contacting the public DHT.
if config_toml.general.database_url.is_none() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we must avoid contacting the public DHT

This only happens if the database_url is unset. So if a MockDataDir is created with an explicit database_url:

let mut config = ConfigToml::minimal_test_config();
config.general.database_url = Some(postgres_url);

let dir = MockDataDir::new(config, None)?;
HomeserverApp::start_with_mock_data_dir(dir).await?;

then the test can publish test records to the public DHT, and / or fail the test if the environment is sandboxed and outbound connections are denied.

I guess in our test suites we wouldn't do that, but the README documents how library users might write their own tests, so others could inadvertently trigger this edge-case:

let config = ConfigToml::default_test_config();
let mock_dir = MockDataDir::new(config, None).unwrap();
let app = HomeserverApp::start_with_mock_data_dir(mock_dir).await.unwrap();

One solution could be to pass db_mode: &DatabaseMode as an extra arg to build_pkarr_builder_from_config then internally check it directly:

- if config_toml.general.database_url.is_none()
+ if matches!(db_mode, DatabaseMode::EphemeralTest(_))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is equal in fragility as before, when a provide database_url without ?pubky-test=true would not isolate pkarr. I'll fix this properly when i refactor the whole data dir/db/file system config situation, if that okay with you.

temp_dirs: vec![],
postgres_connection_string: Self::extract_postgres_connection_string_from_env_variable(
),
postgres_connection_string: None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change means the persistent command from pubky-testnet/README.md

TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres' \
  cargo run -p pubky-testnet -- persist ./my-testnet-data

now ignores TEST_PUBKY_CONNECTION_STRING and instead uses the generated config default

 database_url = "postgres://localhost:5432/pubky_homeserver"

from config.sample.toml, which doesn't have the user/pass or the right DB name for the Docker DB setup.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also is pre-existing and also will be addressed in the follow-up refactor

Comment thread pubky-homeserver/src/persistence/sql/sql_db.rs
Comment on lines +13 to +15
/// Create an ephemeral `pubky_test_{uuid}` database on the server
/// identified by the URL, then connect to it. The database is dropped
/// when the [`SqlDb`](super::SqlDb) is dropped.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The database is dropped when the SqlDb is dropped.

Dropping SqlDb only queues cleanup; deletion requires #[pubky_testnet::test] or an explicit drop_test_databases() call. Callers without either leak databases on external PostgreSQL instances.

Simplest fix is probably to change these doc lines to say that dropping registers the DB for cleanup and that callers must use the #[pubky_testnet::test] macro or call drop_test_databases(). Ideally the README examples1 should include or mention that too.

Footnotes

  1. https://github.com/pubky/pubky-homeserver/blob/b4100e7849d2db18cc2c8800ad57f6aa0b9f724a/pubky-testnet/README.md?plain=1#L146-L174

@86667 86667 Aug 25, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated doc here and also added missing [crate::test]!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll also look into making it clearer where/when this is needed, since it was missed on some tests already.

Comment thread pubky-homeserver/src/data_directory/data_dir.rs Outdated
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from b4100e7 to f6bb478 Compare August 25, 2026 10:30
… up various docs, add missing [crate::test] macros
@86667
86667 force-pushed the docker_postgres_shared_new_tables_per_test branch from f6bb478 to 95293f6 Compare August 25, 2026 10:38

@MCarlomagno MCarlomagno left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@86667
86667 merged commit ef250ee into main Aug 26, 2026
15 checks passed
@86667
86667 deleted the docker_postgres_shared_new_tables_per_test branch August 26, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants