Skip to content

[CMCSMACD-6648] Allow for a setup function in SchemaTest#25

Merged
hundt-corbalt merged 3 commits into
mainfrom
hundt-setup
Jul 16, 2026
Merged

[CMCSMACD-6648] Allow for a setup function in SchemaTest#25
hundt-corbalt merged 3 commits into
mainfrom
hundt-setup

Conversation

@hundt-corbalt

Copy link
Copy Markdown
Contributor

This allows callers to set up prerequisite data or tables that are needed for the migrations without running afoul of the empty- database check at the beginning of SchemaTest.

Testing: pulled this into professor-mac and successfully used it to allow app migrations to depend on teamsapi migrations.

  • New automated tests have been written to the extent possible.
  • The code has been checked for structural/syntactic validity.
    • AMI/application: a build was performed
    • terraform changes: "terraform plan" checked on every affected environment
  • (If applicable) the code has been manually tested on our infrastructure.
    • AMI/application: deployed an a test or dev environment
    • terraform changes: applied to test or dev environment
    • script: run against test or dev environment
  • Likely failure points and new functionality have been identified and tested manually.
    Examples:
    • Application manually run in a way that triggers any new branches
    • AMI logged into and changes verified from login shell
  • Pull request description includes a description of all the manual steps performed to accomplish the above.

This allows callers to set up preerquisite data or tables that are
needed for the migrations without running afoul of the empty-
database check at the beginning of SchemaTest.

@leslie-corbalt leslie-corbalt left a comment

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.

cmd/schema-test/README.md, line 3 is stale.

My comments are related to additional clarification and preciseness.

Comment thread migrations/verify.go Outdated

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.

A more precise message:
Existing relations found. You must run this on an empty database

Maybe omit specifying SchemaTest, since it can also be called by SchemaTestWithSetup?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go Outdated
@@ -145,6 +132,10 @@ func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) e

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 is not part of this change, but a better function name is verifyNoRelations since \d returns user relations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go Outdated

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.

Replace tables with relations

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go
func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error {
// Does a SchemaTest but calls the provided setup function after verifying that the
// database is empty.
func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error {

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.

If setup is required to be non-nil, then the comment should say that.
If setup can be nil, the code must check for it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the name makes clear that this function only exists to add a setup step to the standard SchemaTest. It would be silly to call it with a nil setup function. I think it's better to keep documentation concise.

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.

Makes sense.

Comment thread migrations/verify.go
return nil
}

// Schema test expects a new *empty* postgres database.

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.

Replace this comment with:
// SchemaTest runs SchemaTestWithSetup with no setup step.

Comment thread migrations/verify.go
func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error {
// Does a SchemaTest but calls the provided setup function after verifying that the
// database is empty.
func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error {

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 function should get the long comment. This suggestion adds the points that

  1. the caller must remove objects that the setup created before running another schema test on the same database
  2. setup() must be non-nil (based on the current code)
  // SchemaTestWithSetup expects a new *empty* postgres database. After confirming
  // the database is empty, it calls setup once - e.g. to create schemas or tables
  // the migrations depend on - and then:
  //  1. Applies all migrations
  //  2. Reverses all migrations
  //  3. For each migration:
  //     a. Applies the migration
  //     b. Reverses the migration
  //     c. Applies the migration again
  //
  // Before and after each step, it uses pg_dump to dump the schema, and verifies:
  // A. The schema after reversing matches the schema before applying.
  // B. (If re-applying) The schema after applying matches the schema after re-applying.
  //
  // Whatever setup is created is treated as the baseline schema: it is not rolled
  // back or dropped, so the caller must remove it before running another schema
  // test on the same database. setup must not be nil.
  //
  // You must have `pg_dump` in your `PATH` to run this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually think it's better to have the long docstring on the standard function and not this variant.

The caller is not required to remove objects that setup created. They are if they are going to call the function twice, but that is implied by the fact that SchemaTest requires an empty database.

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.

Makes sense.

@hundt-corbalt hundt-corbalt left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review!

Comment thread migrations/verify.go Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go
func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error {
// Does a SchemaTest but calls the provided setup function after verifying that the
// database is empty.
func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the name makes clear that this function only exists to add a setup step to the standard SchemaTest. It would be silly to call it with a nil setup function. I think it's better to keep documentation concise.

Comment thread migrations/verify.go
func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error {
// Does a SchemaTest but calls the provided setup function after verifying that the
// database is empty.
func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually think it's better to have the long docstring on the standard function and not this variant.

The caller is not required to remove objects that setup created. They are if they are going to call the function twice, but that is implied by the fact that SchemaTest requires an empty database.

Comment thread migrations/verify.go Outdated
@@ -145,6 +132,10 @@ func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) e

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread migrations/verify.go Outdated
//
// You must have `pg_dump` in your `PATH` to run this.
func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error {
// Does a SchemaTest but calls the provided setup function after verifying that the

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 capitalization SchemaTest sounds like SchemaTestWithSetup calls SchemaTest but calls the provided setup after verifying that the database is empty.

This comment is confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

How about now?

@leslie-corbalt leslie-corbalt left a comment

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.

A comment on your short docstring.

@leslie-corbalt leslie-corbalt left a comment

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.

LGTM

@hundt-corbalt
hundt-corbalt merged commit c57eab5 into main Jul 16, 2026
1 check passed
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.

2 participants