-
Notifications
You must be signed in to change notification settings - Fork 354
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
Conversation
✅ Deploy Preview for determined-ui canceled.
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
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
Flags with carried forward coverage won't be shown. Click here to find out more. |
There was a problem hiding this 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.
func setupDBForTest(t *testing.T) *PgDB { | ||
require.NoError(t, etc.SetRootPath(RootFromDB)) | ||
|
||
db := MustResolveTestPostgres(t) | ||
MustMigrateTestPostgres(t, db, MigrationsFromDB) | ||
return db | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!!
There was a problem hiding this comment.
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(...)
.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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)
?
There was a problem hiding this comment.
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
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) | ||
}) | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
overassert
, this means the test stops at the first test case that fails. With the existing code structure we can run individual cases or runTestUpdateJobPosition
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, great work
* 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
Description
Add integration test coverage for postgres_jobs.go - DET-10133.
Test Plan
Run integration tests locally, and via CI. Ensure they pass.
Checklist
docs/release-notes/
.See Release Note for details.
Ticket
DET-10133