Allow explicit schema injection to rivertest.Require* test functions#926
Merged
Merged
Conversation
Here, resolve #907 by letting an explicit schema be injected into `rivertest.Require*` assertions in a similar way that one can be used in a client. This approach adds a schema in `RequireInsertedOpts`. This comment does a good job of highlight all the potential approaches for adding a schema [1], and unfortunately none of them are all that great. I implemented one other version of this (a variant of option 2 in that list), which as some advantages, but in the end it just ended up ballooning the API out to an uncomfortable degree. The worst part about adding schema to `RequireInsertedOpts` is its interact with the `RequireMany*` functions, where each expectation can set its own schema, and it's not clear what would happen if different expectations set different schemas. I resolved this ambiguity by making it an error to mix and match schemas. Assertions are allowed to send a schema in only the first position like: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}}, }) Or send the same schema in all positions: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}, Opts: bundle.schemaOpts}, }) But they aren't allowed to set a schema only in position other than the first, or mix and match schemas between expectations. Fixes #907. [1] #907 (comment)
08a640d to
9049281
Compare
bgentry
approved these changes
May 28, 2025
bgentry
left a comment
Contributor
There was a problem hiding this comment.
I think this seems like the best of the possible options and you explored those pretty thoroughly. Great pragmatic choice!
Contributor
Author
|
+1, wish there was a better option, but this should do it for now. Thanks! |
brandur
added a commit
that referenced
this pull request
May 28, 2025
#926) Here, resolve #907 by letting an explicit schema be injected into `rivertest.Require*` assertions in a similar way that one can be used in a client. This approach adds a schema in `RequireInsertedOpts`. This comment does a good job of highlight all the potential approaches for adding a schema [1], and unfortunately none of them are all that great. I implemented one other version of this (a variant of option 2 in that list), which as some advantages, but in the end it just ended up ballooning the API out to an uncomfortable degree. The worst part about adding schema to `RequireInsertedOpts` is its interact with the `RequireMany*` functions, where each expectation can set its own schema, and it's not clear what would happen if different expectations set different schemas. I resolved this ambiguity by making it an error to mix and match schemas. Assertions are allowed to send a schema in only the first position like: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}}, }) Or send the same schema in all positions: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}, Opts: bundle.schemaOpts}, }) But they aren't allowed to set a schema only in position other than the first, or mix and match schemas between expectations. Fixes #907. [1] #907 (comment)
brandur
added a commit
that referenced
this pull request
May 28, 2025
#926) Here, resolve #907 by letting an explicit schema be injected into `rivertest.Require*` assertions in a similar way that one can be used in a client. This approach adds a schema in `RequireInsertedOpts`. This comment does a good job of highlight all the potential approaches for adding a schema [1], and unfortunately none of them are all that great. I implemented one other version of this (a variant of option 2 in that list), which as some advantages, but in the end it just ended up ballooning the API out to an uncomfortable degree. The worst part about adding schema to `RequireInsertedOpts` is its interact with the `RequireMany*` functions, where each expectation can set its own schema, and it's not clear what would happen if different expectations set different schemas. I resolved this ambiguity by making it an error to mix and match schemas. Assertions are allowed to send a schema in only the first position like: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}}, }) Or send the same schema in all positions: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}, Opts: bundle.schemaOpts}, }) But they aren't allowed to set a schema only in position other than the first, or mix and match schemas between expectations. Fixes #907. [1] #907 (comment)
brandur
added a commit
that referenced
this pull request
May 28, 2025
#926) (#933) Here, resolve #907 by letting an explicit schema be injected into `rivertest.Require*` assertions in a similar way that one can be used in a client. This approach adds a schema in `RequireInsertedOpts`. This comment does a good job of highlight all the potential approaches for adding a schema [1], and unfortunately none of them are all that great. I implemented one other version of this (a variant of option 2 in that list), which as some advantages, but in the end it just ended up ballooning the API out to an uncomfortable degree. The worst part about adding schema to `RequireInsertedOpts` is its interact with the `RequireMany*` functions, where each expectation can set its own schema, and it's not clear what would happen if different expectations set different schemas. I resolved this ambiguity by making it an error to mix and match schemas. Assertions are allowed to send a schema in only the first position like: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}}, }) Or send the same schema in all positions: jobs := requireManyInserted(ctx, bundle.mockT, bundle.driver, []ExpectedJob{ {Args: &Job1Args{String: "foo"}, Opts: bundle.schemaOpts}, {Args: &Job1Args{String: "bar"}, Opts: bundle.schemaOpts}, }) But they aren't allowed to set a schema only in position other than the first, or mix and match schemas between expectations. Fixes #907. [1] #907 (comment)
zmwangx
added a commit
to zmwangx/river
that referenced
this pull request
May 31, 2026
…Worker`
`rivertest.Worker` works a job in three database steps: it inserts the job
through the client, builds an inline completer, and transitions the job to
`running` via `JobUpdateFull`. The first two already thread `config.Schema`
through — the client uses it internally, and it's passed explicitly to
`jobcompleter.NewInlineCompleter` — but the `JobUpdateFull` call omitted it.
With a non-default `Schema`, the insert lands the job in `<schema>.river_job`
correctly, then the running-state update runs unqualified and resolves only
through the connection's `search_path`. On a connection that doesn't include
the configured schema it fails one step later with:
test worker internal error: failed to update job to running state: ERROR: relation "river_job" does not exist (SQLSTATE 42P01)
Pass `w.config.Schema` into `JobUpdateFullParams` so all three steps agree on
the schema. This finishes custom-schema support for `rivertest.Worker`; the
`rivertest.Require*` family received an analogous per-call `Schema` option in
riverqueue#926 (riverqueue#907).
The regression tests migrate River into an isolated named schema and work jobs
through a transaction whose `search_path` is empty, so the tables resolve only
via schema qualification — the exact condition that fails before this change.
They live as `CustomSchema` subtests of `TestWorker_Work` and
`TestWorker_WorkJob`, each building its own bundle inline since the schema setup
differs from those tests' shared `setup`.
zmwangx
added a commit
to zmwangx/river
that referenced
this pull request
May 31, 2026
…Worker`
`rivertest.Worker` works a job in three database steps: it inserts the job
through the client, builds an inline completer, and transitions the job to
`running` via `JobUpdateFull`. The first two already thread `config.Schema`
through — the client uses it internally, and it's passed explicitly to
`jobcompleter.NewInlineCompleter` — but the `JobUpdateFull` call omitted it.
With a non-default `Schema`, the insert lands the job in `<schema>.river_job`
correctly, then the running-state update runs unqualified and resolves only
through the connection's `search_path`. On a connection that doesn't include
the configured schema it fails one step later with:
test worker internal error: failed to update job to running state: ERROR: relation "river_job" does not exist (SQLSTATE 42P01)
Pass `w.config.Schema` into `JobUpdateFullParams` so all three steps agree on
the schema. This finishes custom-schema support for `rivertest.Worker`; the
`rivertest.Require*` family received an analogous per-call `Schema` option in
riverqueue#926 (riverqueue#907).
The regression tests migrate River into an isolated named schema and work jobs
through a transaction whose `search_path` is empty, so the tables resolve only
via schema qualification — the exact condition that fails before this change.
They live as `CustomSchema` subtests of `TestWorker_Work` and
`TestWorker_WorkJob`, each building its own bundle inline since the schema setup
differs from those tests' shared `setup`.
brandur
pushed a commit
that referenced
this pull request
May 31, 2026
…Worker` (#1262) `rivertest.Worker` works a job in three database steps: it inserts the job through the client, builds an inline completer, and transitions the job to `running` via `JobUpdateFull`. The first two already thread `config.Schema` through — the client uses it internally, and it's passed explicitly to `jobcompleter.NewInlineCompleter` — but the `JobUpdateFull` call omitted it. With a non-default `Schema`, the insert lands the job in `<schema>.river_job` correctly, then the running-state update runs unqualified and resolves only through the connection's `search_path`. On a connection that doesn't include the configured schema it fails one step later with: test worker internal error: failed to update job to running state: ERROR: relation "river_job" does not exist (SQLSTATE 42P01) Pass `w.config.Schema` into `JobUpdateFullParams` so all three steps agree on the schema. This finishes custom-schema support for `rivertest.Worker`; the `rivertest.Require*` family received an analogous per-call `Schema` option in #926 (#907). The regression tests migrate River into an isolated named schema and work jobs through a transaction whose `search_path` is empty, so the tables resolve only via schema qualification — the exact condition that fails before this change. They live as `CustomSchema` subtests of `TestWorker_Work` and `TestWorker_WorkJob`, each building its own bundle inline since the schema setup differs from those tests' shared `setup`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here, resolve #907 by letting an explicit schema be injected into
rivertest.Require*assertions in a similar way that one can be used ina client.
This approach adds a schema in
RequireInsertedOpts. This comment doesa good job of highlight all the potential approaches for adding a schema
[1], and unfortunately none of them are all that great. I implemented
one other version of this (a variant of option 2 in that list), which as
some advantages, but in the end it just ended up ballooning the API out
to an uncomfortable degree.
The worst part about adding schema to
RequireInsertedOptsis itsinteract with the
RequireMany*functions, where each expectation canset its own schema, and it's not clear what would happen if different
expectations set different schemas. I resolved this ambiguity by making
it an error to mix and match schemas. Assertions are allowed to send a
schema in only the first position like:
Or send the same schema in all positions:
But they aren't allowed to set a schema only in position other than the
first, or mix and match schemas between expectations.
Fixes #907.
[1] #907 (comment)