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

Export test-specific functions without go:linkname #657

Merged
merged 2 commits into from
Dec 19, 2024

Conversation

adombeck
Copy link
Contributor

@adombeck adombeck commented Nov 27, 2024

Using go:linkname is poorly supported by tooling, for example it breaks code navigation because IDEs don't support going to the function's implementation.

To still make it clear that those functions are only for use in tests, and to group test-specific functions together in code completion lists, we are now prefixing them with "Z_ForTests". The "Z_" should ensure that they are listed at the end (although that doesn't work for Intellij unfortunately).

UDENG-5449

@adombeck
Copy link
Contributor Author

adombeck commented Nov 28, 2024

Blocked by #641

@adombeck adombeck force-pushed the export-for-tests-functions-without-linkname branch 2 times, most recently from b680c48 to 3f9eb52 Compare December 2, 2024 11:44
@adombeck adombeck marked this pull request as ready for review December 2, 2024 12:36
@adombeck adombeck requested a review from a team as a code owner December 2, 2024 12:36
@adombeck
Copy link
Contributor Author

adombeck commented Dec 3, 2024

In Intellij, the Z_ prefix does not provide any value, because the code completion popup doesn't order completions alphabetically. @didrocks could you check if it has the desired effect in your editor?

@adombeck adombeck force-pushed the export-for-tests-functions-without-linkname branch from 3f9eb52 to ee8477b Compare December 3, 2024 13:22
@didrocks
Copy link
Member

didrocks commented Dec 3, 2024

In Intellij, the Z_ prefix does not provide any value, because the code completion popup doesn't order completions alphabetically. @didrocks could you check if it has the desired effect in your editor?

Yes, vscode is using ascii ordering for it.

@3v1n0
Copy link
Collaborator

3v1n0 commented Dec 3, 2024

Mhmh, I agree go:linkname isn't the nicest thing, but by adding actually linked functions, don't we end up adding test-only code to the final binaries?

@adombeck
Copy link
Contributor Author

adombeck commented Dec 3, 2024

Mhmh, I agree go:linkname isn't the nicest thing, but by adding actually linked functions, don't we end up adding test-only code to the final binaries?

No, the Go compiler removes functions from the binary which are not used: https://stackoverflow.com/a/48688904/2804197

For methods it's apparently harder to detect, and in fact the two methods which were part of this PR were included in the authd binary. I pushed a fixup commit which turns those into functions and now none of the Z_ForTests functions is included in the binary:

go build -o authd ./cmd/authd && go tool nm authd | grep Z_ForTests

@3v1n0
Copy link
Collaborator

3v1n0 commented Dec 3, 2024

go build -o authd ./cmd/authd && go tool nm authd | grep Z_ForTests

Maybe we can add this check to a CI job too?

@adombeck
Copy link
Contributor Author

adombeck commented Dec 3, 2024

Maybe we can add this check to a CI job too?

We could, but do we care that much about not adding test-only code to the binaries? What's the problem with it? It just increases the binary size by a few kilobyte.

@adombeck adombeck requested a review from 3v1n0 December 4, 2024 11:57
jibel
jibel previously approved these changes Dec 4, 2024
@adombeck adombeck force-pushed the export-for-tests-functions-without-linkname branch from 7ca6f70 to 978d4d8 Compare December 5, 2024 16:44
@adombeck
Copy link
Contributor Author

adombeck commented Dec 5, 2024

rebased on main and resolved merge conflicts

@jibel jibel requested review from jibel and removed request for jibel December 11, 2024 13:55
@jibel jibel dismissed their stale review December 11, 2024 13:55

testing

Copy link
Collaborator

@3v1n0 3v1n0 left a comment

Choose a reason for hiding this comment

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

Not totally a fan of having these kind of test-only functions, as I'd like that the language would provide some nicer way for us to use them without having to explicitly including the code (not sure if using instead some kind of go shared library could help?).

However, not blocking this, indeed it has good side effects for us developers...

As further work, it would be nice if we could plan couple of things:

  • Add CI job checking symbols aren't there
  • See if we can protect us even more by using go:build: feature and include these at least some functions only if a tag is defined (making them no-op otherwise).

@adombeck
Copy link
Contributor Author

adombeck commented Dec 19, 2024

Not totally a fan of having these kind of test-only functions, as I'd like that the language would provide some nicer way for us to use them without having to explicitly including the code (not sure if using instead some kind of go shared library could help?).

Didier also didn't like having test-only functions in non-test code. We discussed possible alternatives but to the best of our knowledge, Go doesn't provide any other way than this go:linkname workaround to make internal functions of another package usable in test code (and only test code) of other packages. I find that the go:linkname workaround very annoying when navigating through the code, so we discussed other options.

This PR implements the compromise we found, which is to prefix it with Z_ForTests so that it's clear from the name that they are test-only and so that they are listed at the end in the code completions pop-up, which was important for Didier. I find that prefix not aesthetically pleasing and would have preferred a ForTests suffix, but that's the compromise we found.

However, not blocking this, indeed it has good side effects for us developers...

As further work, it would be nice if we could plan couple of things:

* Add CI job checking symbols aren't there

I won't push for that because I don't see why that's important, but I won't stand in the way either, so feel free to create a ticket for it.

* See if we can protect us even more by using `go:build:` feature and include these at least some functions only if a tag is defined (making them no-op otherwise).

We already considered that. If I remember correctly, Didier pointed to a related open issue in the go stdlib, but I can't find it.

Using go:linkname is poorly supported by tooling, for example it breaks
code navigation because IDEs don't support going to the function's
implementation.

To still make it clear that those functions are only for use in tests,
and to group test-specific functions together in code completion lists,
we are now prefixing them with "Z_ForTests". The "Z_" should ensure that
they are listed at the end (although that doesn't work for Intellij
unfortunately).
@adombeck adombeck force-pushed the export-for-tests-functions-without-linkname branch from 978d4d8 to 33afdeb Compare December 19, 2024 22:39
@adombeck adombeck merged commit b1d0b5c into main Dec 19, 2024
8 of 10 checks passed
@adombeck adombeck deleted the export-for-tests-functions-without-linkname branch December 19, 2024 22:40
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.

4 participants