Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testability #12

Open
thruflo opened this issue Feb 4, 2025 · 1 comment
Open

Testability #12

thruflo opened this issue Feb 4, 2025 · 1 comment

Comments

@thruflo
Copy link

thruflo commented Feb 4, 2025

At the moment, testing an app that uses electric_stream (or any Electric.Client requests) makes requests to an external Electric service.

The URL is configurable in the Electric.Client config:

config :electric_phoenix, Electric.Client,
  base_url: System.get_env("ELECTRIC_URL", "http://localhost:3000")

This allows different databases to be used in dev and test. However:

  1. in some cases, like unit tests, it may be more desirable to stub/mock out the Electric calls
  2. using a long running external DB for Electric may not be compatible (a) a Postgres sandbox or (b) mix ecto.reset

With the Postgres sandbox, using Ecto.Adapters.SQL.Sandbox, operations are wrapped in an outer transaction. This means that Electric never sees the events, because they're not put on the external logical replication stream. This is a bit of a non-starter.

With ecto.reset, wiping a Postgres DB needs to also wipe Electric. The developer will get into issues. We know the ins and outs of this, so we should prescribe a pattern and if necessary provide helpers. The implementation of this may be affected by the mechanism of embedding Electric (because it affects how much control we have over the shape storage etc).

@thruflo
Copy link
Author

thruflo commented Feb 4, 2025

Just chatted to @magnetised on this.

  1. we can run Electric in ephemeral (storage in memory) mode
  2. we can provide a mix task to add into your ecto.reset list that wipes electric when you wipe the DB
  3. we can maybe provide a setup/teardown helper to wipe shapes before and after tests / test suites
  4. the simplest approach for unit test support is to document how to use the client mock to emit events that you're expecting
  5. a more advanced/complex route is to somehow auto-intercept writes and generate stream events automatically (short cutting logical replication which won't run bc of the sandbox transaction wrapper)
  6. one of the tweaks is to configure Electric to always use a unique shape for each test, which in async mode means maybe having a mode where the lookup of shape handle from definition always fails; so that way concurrent tests can use the same shape definition without re-using shapes
  7. we would also want a way for Electric to use a sandboxed conn in test, so that new shapes can be created that can read the data inserted within the sandbox transaction (for queries to power initial data sync)

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

No branches or pull requests

1 participant