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

chore: cover postgres_jobs.go #8841

Merged
merged 9 commits into from
Feb 16, 2024
Merged

chore: cover postgres_jobs.go #8841

merged 9 commits into from
Feb 16, 2024

Conversation

kkunapuli
Copy link
Contributor

@kkunapuli kkunapuli commented Feb 13, 2024

Description

Add integration test coverage for postgres_jobs.go - DET-10133.

Test Plan

Run integration tests locally, and via CI. Ensure they pass.

Checklist

  • Changes have been manually QA'd
  • User-facing API changes need the "User-facing API Change" label.
  • Release notes should be added as a separate file under docs/release-notes/.
    See Release Note for details.
  • Licenses should be included for new code which was copied and/or modified from any external code.

Ticket

DET-10133

@cla-bot cla-bot bot added the cla-signed label Feb 13, 2024
Copy link

netlify bot commented Feb 13, 2024

Deploy Preview for determined-ui canceled.

Name Link
🔨 Latest commit 440cbf7
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/65cf793cf4320b0008560a14

Copy link

codecov bot commented Feb 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (a4dbc03) 47.70% compared to head (440cbf7) 47.71%.
Report is 9 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8841   +/-   ##
=======================================
  Coverage   47.70%   47.71%           
=======================================
  Files        1065     1065           
  Lines      169614   169614           
  Branches     2238     2238           
=======================================
+ Hits        80920    80930   +10     
+ Misses      88536    88526   -10     
  Partials      158      158           
Flag Coverage Δ
backend 43.55% <ø> (+0.02%) ⬆️
harness 64.11% <ø> (ø)
web 42.55% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

see 2 files with indirect coverage changes

@kkunapuli kkunapuli marked this pull request as ready for review February 13, 2024 21:59
@kkunapuli kkunapuli requested a review from a team as a code owner February 13, 2024 21:59
@kkunapuli kkunapuli requested a review from ioga February 13, 2024 21:59
@kkunapuli kkunapuli changed the title chore: cover postgres_go chore: cover postgres_jobs.go Feb 13, 2024
Copy link
Contributor

@carolinaecalderon carolinaecalderon left a comment

Choose a reason for hiding this comment

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

Great work, a couple notes/links on writing table-driven tests & the golang 'testing' package.

Comment on lines +162 to +168
func setupDBForTest(t *testing.T) *PgDB {
require.NoError(t, etc.SetRootPath(RootFromDB))

db := MustResolveTestPostgres(t)
MustMigrateTestPostgres(t, db, MigrationsFromDB)
return db
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: replace this with TestMain -- see other TestMains in the repo for more context. Then, you can reference it in the other test functions with db.SingleDB()
https://medium.com/goingogo/why-use-testmain-for-testing-in-go-dafb52b406bc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TestMain(...) is so clean. Unfortunately, the db package has a lot of integration test files, some of which are closing db connections in an attempt to ensure they are using a fresh/clean database. Details here: https://hpe-aiatscale.atlassian.net/browse/RM-27

This means that until they are refactored to their own package, tests need to establish their own database connection instead of using TestMain(...).

Copy link
Contributor

Choose a reason for hiding this comment

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

Good to know, I think all the tests I've written have been outside the 'db' package so I hadn't run into this before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was a good experience to learn about TestMain and implement the change even if it didn't work out! Now I know to be aware of it in the future. :)

assert.Equal(t, sendJob.JobID, recvJob.JobID)
assert.Equal(t, sendJob.JobType, recvJob.JobType)
assert.Equal(t, sendJob.OwnerID, recvJob.OwnerID)
assert.Equal(t, decimal.NewFromInt(10).Equal(recvJob.QPos), true)
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a reason you can't assert.Equal(t, decimal.NewFromInt(10), recvJob.QPos)?

Copy link
Contributor Author

@kkunapuli kkunapuli Feb 14, 2024

Choose a reason for hiding this comment

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

Yes, two decimal.Decimal variables are not equal even if their values are equal. We need to use the .Equal() method to test for the values being equal.

I made a playground to demonstrate: https://go.dev/play/p/asTPVa4OuQZ

Comment on lines 75 to 160
func TestUpdateJobPosition(t *testing.T) {
db := setupDBForTest(t)

t.Run("update position", func(t *testing.T) {
// create and send job
origPos := decimal.NewFromInt(10)
newPos := decimal.NewFromInt(5)
sendJob := model.Job{
JobID: model.NewJobID(),
JobType: model.JobTypeExperiment,
QPos: origPos,
}
err := db.AddJob(&sendJob)
require.NoError(t, err)

// update job position
err = db.UpdateJobPosition(sendJob.JobID, newPos)
require.NoError(t, err)

// retrieve job and confirm pos update
recvJob, err := db.JobByID(sendJob.JobID)
require.NoError(t, err)
assert.Equal(t, newPos.Equal(recvJob.QPos), true)
})

t.Run("update position - negative value", func(t *testing.T) {
// create and send job
origPos := decimal.NewFromInt(10)
newPos := decimal.NewFromInt(-5)
sendJob := model.Job{
JobID: model.NewJobID(),
JobType: model.JobTypeExperiment,
QPos: origPos,
}
err := db.AddJob(&sendJob)
require.NoError(t, err)

// update job position
err = db.UpdateJobPosition(sendJob.JobID, newPos)
require.NoError(t, err)

// retrieve job and confirm pos update
recvJob, err := db.JobByID(sendJob.JobID)
require.NoError(t, err)
assert.Equal(t, newPos.Equal(recvJob.QPos), true)
})

t.Run("update position - empty ID", func(t *testing.T) {
// create and send job
origPos := decimal.NewFromInt(10)
newPos := decimal.NewFromInt(5)
sendJob := model.Job{
JobID: model.NewJobID(),
JobType: model.JobTypeExperiment,
QPos: origPos,
}
err := db.AddJob(&sendJob)
require.NoError(t, err)

// update job position
err = db.UpdateJobPosition(model.JobID(""), newPos)
require.Error(t, err)

// retrieve job and ensure queue pos not updated
recvJob, err := db.JobByID(sendJob.JobID)
require.NoError(t, err)
assert.Equal(t, origPos.Equal(recvJob.QPos), true)
})

t.Run("update position - ID does not exist", func(t *testing.T) {
// create and send job
origPos := decimal.NewFromInt(10)
newPos := decimal.NewFromInt(5)
sendJob := model.Job{
JobID: model.NewJobID(),
JobType: model.JobTypeExperiment,
QPos: origPos,
}
err := db.AddJob(&sendJob)
require.NoError(t, err)

// update job position for a job that doesn't exist
err = db.UpdateJobPosition(model.NewJobID(), newPos)
require.NoError(t, err)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

blocker: since this test has a lot of repeated code, I recommend setting this test up with test cases and then looping through them, see https://dave.cheney.net/2019/05/07/prefer-table-driven-tests or search for cases := []struct { in the repo.

Copy link
Contributor Author

@kkunapuli kkunapuli Feb 14, 2024

Choose a reason for hiding this comment

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

I appreciate the desire to limit repeated code! I also see your point - but I don't think table tests are the best approach here.

  • the tests aren't exact copies of each other; I think it will add complexity to try and fit them all in the same table test. Basically, there's two types of variations: position value and job ID.
  • you can't run a single test case with table tests (as far as I can tell); since we prefer require over assert, this means the test stops at the first test case that fails. With the existing code structure we can run individual cases or run TestUpdateJobPosition and get info on all failing cases

Repeated code is usually more tolerated in test code because the purpose is a little different. It's more important to be usable and to easily understand what a test is doing.

I think a nice alternative might be to extract some of the repeated code into a helper function. How does that sound to you?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's a good idea

Copy link
Contributor

@carolinaecalderon carolinaecalderon left a comment

Choose a reason for hiding this comment

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

LGTM, great work

@kkunapuli kkunapuli merged commit de28a57 into main Feb 16, 2024
74 of 86 checks passed
@kkunapuli kkunapuli deleted the kunapuli/cover-postgres_jobs branch February 16, 2024 16:12
maxrussell pushed a commit that referenced this pull request Mar 21, 2024
* chore: cover postgres_go

* gofumpt update

* remove comments; entered by accident

* update from make fmt

* fix check issues

* use TestMain in db package to setup db for tests

* reduce amount of duplicate code with utility function

* additional cleanup

* initialize db outside of TestMain until enough isolation is achieved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants