-
Notifications
You must be signed in to change notification settings - Fork 67
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
Mock DBClient with GoMock #1099
Conversation
Please rebase pull request. |
670bea5
to
b6ce6e7
Compare
b6ce6e7
to
eba3b64
Compare
Please rebase pull request. |
eba3b64
to
7b3b07d
Compare
c46d194
to
6744098
Compare
f9ec087
to
864ab95
Compare
ba53408
to
b59fd69
Compare
b59fd69
to
1443a79
Compare
All review comments are addressed. I was able to simplify all the |
1443a79
to
5ab00ac
Compare
5ab00ac
to
159915f
Compare
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 Matt! A few more comments here.
Makefile
Outdated
@@ -14,10 +14,18 @@ all: test lint | |||
|
|||
# There is currently no convenient way to run tests against a whole Go workspace | |||
# https://github.com/golang/go/issues/50745 | |||
test: | |||
test: mocks |
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 hope this isn't too much scope creep - but we've got new code that's auto-generated to consider in this PR, so a few things I want to note:
CONTEXT:
While I too was originally on-board with your pattern, where go generate
commands ultimately get called as a direct dependency of their requirements, in Classic, we eventually made the decision not to do this for a few key reasons:
- The golang maintainers say that
go generate
should not be part of your build process - it should be independent and committed as code (rather than generated on the fly). - In the case here - tests in CI might pass even though you didn't run
go generate
locally and committed the diff. This means that we haven't guaranteed the code in git is up-to-date with what is expected in a given commit on PRs. Instead, we should probably do the same in classic: if there's a diff after runninggo generate
, that should produce a CI error. - This extends the duration of our test suite long-term, especially when we have quite a few mocks to generate in the long-game of this repo.
More of me being ripped tearing and screaming away from this pattern can be read here: https://redhat-internal.slack.com/archives/C02ULBRS68M/p1724353443729429?thread_ts=1724304200.163579&cid=C02ULBRS68M
WHAT I THINK WE SHOULD DO:
- Remove
mocks
as a direct dependency oftest
, instead, the dev is expected to runmake mocks
if interfaces have changed. - Add CI logic to run an equivalent of
make mocks && exit 1 on git diff
to ensure thatmake mocks
was run correctly before merge: https://github.com/Azure/ARO-RP/blob/b6a5f9ca0d2862ba3672271204659d835d91470b/.github/workflows/ci-go.yml#L29-L42
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 removed mocks
as a prerequisite for test
in an existing commit and appended a new commit for a new "Regenerate mocks" CI step.
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.
Also ran a test with a now-reverted commit where I modified /internal/mocks/dbclient.go
and CI caught it.
internal/mocks/dbclient.go
Outdated
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: thinking long-game - do we potentially want to reflect the package directory structure inside of internal/mocks
to prevent the mocks
directory from being too much of a dumping ground? I would think we'd at least want something like:
./internal/
├── database
│ └── database.go
└── mocks
├── database
│ └── dbclient.go
└── generate.go
We could also consider renaming the mock file name to database.go
so we know what file the interface mocks are from - which is unknown without reading generate.go
?
./internal/
├── database
│ └── database.go
└── mocks
├── database
│ └── database.go
└── generate.go
Using this structure, our test suite would be doing something like:
import (
"internal/database"
db_mocks "internal/mocks/database"
)
Which feels more directed and obvious exactly what mocks we intend to use, instead of "the mocks"? For example, in a future PR, if I see an update to the internal/database tests, and it had:
import (
db_mocks "internal/mocks/database"
+ backend_mocks "internal/mocks/backend"
)
I would immediately recognize that as a code smell in a way that wouldn't be recognized with the current structure.
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 don't foresee us mocking much else beside maybe the ClusterServiceClient
interface. I'm not opposed to the idea if it does start to become a dumping ground, but I think it's a little premature now.
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.
and it looks like that is already mocked out by hand... ack
The local cache implementation is being dropped because it's an impediment to accessing more advanced Cosmos DB features. This makes running the RP locally with "make run" infeasible for now. It's an open question whether we will attempt to support this mode of operation again going forward.
Henceforth, unit tests should use MockDBClient instead.
This is to satisfy the Go requirement in .bingo/mockgen.mod
Ensures committed mock files are up-to-date.
e742b8f
to
6d2ab42
Compare
What this PR does
DBClient
implementation in a new "mocks" package under/internal/mocks
.DBClient
instead of the in-memory cacheDBClient
.--use-cache
command-line option.DBClient
.The justification for all this is explained in the epic ARO-14167 - Use Cosmos DB's Transactional Batch Operations in RP.
Jiras:
Link to demo recording:
Special notes for your reviewer
The last commit was arrived at after much trial and error. I don't know if there's a better way to adapt the GitHub workflow -- I couldn't find any predefined actions for installing Bingo, nor could I suss out how ARO-RP does it -- so someone with more experience can feel free to correct me.