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

fix: enable formatter rule from testifylint #18741

Merged
merged 1 commit into from
Oct 22, 2024

Conversation

ghouscht
Copy link
Contributor

This PR enables the formatter testifylint rule as part of #18719

Please read https://github.com/etcd-io/etcd/blob/main/CONTRIBUTING.md#contribution-flow.

@k8s-ci-robot
Copy link

Hi @ghouscht. Thanks for your PR.

I'm waiting for a etcd-io member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@codecov-commenter
Copy link

codecov-commenter commented Oct 15, 2024

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 68.71%. Comparing base (3d6ff97) to head (8495e8d).

Current head 8495e8d differs from pull request most recent head ff4a8df

Please upload reports for the commit ff4a8df to get more accurate results.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
Files with missing lines Coverage Δ
server/storage/mvcc/testutil/hash.go 83.78% <100.00%> (ø)

... and 27 files with indirect coverage changes

@@            Coverage Diff             @@
##             main   #18741      +/-   ##
==========================================
- Coverage   68.77%   68.71%   -0.06%     
==========================================
  Files         420      420              
  Lines       35501    35501              
==========================================
- Hits        24416    24395      -21     
- Misses       9657     9675      +18     
- Partials     1428     1431       +3     

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3d6ff97...ff4a8df. Read the comment docs.

@@ -40,12 +40,12 @@ func AssertNotNil(t *testing.T, v any) {
// Deprecated: use github.com/stretchr/testify/assert.True instead.
func AssertTrue(t *testing.T, v bool, msg ...string) {
t.Helper()
assert.True(t, v, msg)
assert.True(t, v, msg) //nolint:testifylint
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both the AssertTrue and AssertFalse functions are part of the public API of the testutils pkg. It looks like they are no longer used within the etcd codebase but they could be used outside of the etcd codebase. I thought it is best to keep them as they are, thus the nolint directive. Let me know if you think that is ok.

Copy link
Contributor

Choose a reason for hiding this comment

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

Until this code is removed, it's better to keep it as is . I agree to disable the linter here

@ghouscht
Copy link
Contributor Author

FYI: @mmorel-35 here is the second PR for the formatterrule. From my point of view it is ready but I marked it as draft to keep the number of open and ready testifylint PRs small.

@ghouscht ghouscht mentioned this pull request Oct 15, 2024
19 tasks
@mmorel-35
Copy link
Contributor

There are many places where the expected or unexpected error is is printed with : %v", err

I'm wondering if it's not redondant with the behavior of testify which will print it

@ghouscht
Copy link
Contributor Author

There are many places where the expected or unexpected error is is printed with : %v", err

I'm wondering if it's not redondant with the behavior of testify which will print it

Yes, that is true. I can clean them up if you and the maintainers agree on that.

@mmorel-35
Copy link
Contributor

Yes, that is true. I can clean them up if you and the maintainers agree on that.

I feel like it's the best opportunity to do that as most of them are probably modified in this PR.

Let's see what the maintainers think.


leaderIndex := epc.WaitLeader(t)
_, err = epc.Procs[leaderIndex].Logs().ExpectWithContext(ctx, expect.ExpectedResponse{Value: "finished compaction hash check"})
require.NoError(t, err, "can't get log indicating finished compaction hash check")
require.NoErrorf(t, err, "can't get log indicating finished compaction hash check")
Copy link
Member

Choose a reason for hiding this comment

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

Question: there is no variable-length variable in this case, shouldn't require.NoError be better than require.NoErrorf?

Copy link
Member

Choose a reason for hiding this comment

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

Note this is a generic question.

Copy link
Contributor

Choose a reason for hiding this comment

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

I had the same question and the author of linter directed me to the rule's documentation:

https://github.com/Antonboom/testifylint?tab=readme-ov-file#formatter

And the historical note associated:

https://github.com/Antonboom/testifylint?tab=readme-ov-file#historical-reference

Copy link
Member

Choose a reason for hiding this comment

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

We should always use *f functions when require-f-funcs: true no matter there is variable-length variables or not?

Copy link
Contributor

Choose a reason for hiding this comment

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

That seems to be the recommended way to do indeed

- go-require
- require-error
enable-all: true
formatter:
require-f-funcs: true
Copy link
Member

Choose a reason for hiding this comment

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

What does this option mean? Could you add a comment to clarify?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://golangci-lint.run/usage/linters/#testifylint states:

To require f-assertions if format string is used.

I'll add a comment 👍🏻

@ahrtr
Copy link
Member

ahrtr commented Oct 16, 2024

There are many places where the expected or unexpected error is is printed with : %v", err

I'm wondering if it's not redondant with the behavior of testify which will print it

Yes, testify already prints the error, so we don't need to print it again. But not a big deal.

@ghouscht ghouscht force-pushed the testifylint-formatter branch 2 times, most recently from 4babfc2 to 2d144f0 Compare October 16, 2024 12:18
@k8s-ci-robot k8s-ci-robot added the github_actions Pull requests that update GitHub Actions code label Oct 16, 2024
@ghouscht ghouscht force-pushed the testifylint-formatter branch 2 times, most recently from 76e0c60 to be02cdb Compare October 16, 2024 12:20
@ghouscht
Copy link
Contributor Author

There are many places where the expected or unexpected error is is printed with : %v", err
I'm wondering if it's not redondant with the behavior of testify which will print it

Yes, testify already prints the error, so we don't need to print it again. But not a big deal.

👍🏻 I cleaned up the messages and removed redundant information.

@mmorel-35
Copy link
Contributor

@ghouscht ,
Feel free to undraft when you you are ready

@ghouscht ghouscht marked this pull request as ready for review October 16, 2024 17:33
@ivanvc
Copy link
Member

ivanvc commented Oct 17, 2024

/ok-to-test

@mmorel-35
Copy link
Contributor

/test pull-etcd-integration-2-cpu-arm64

- go-require
- require-error
enable-all: true
formatter:
# Require f-assertions (e.g. assert.Equalf) if a format string is used.
Copy link
Member

Choose a reason for hiding this comment

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

It could be just a nitpick on the comment, but after reading

I think this comment's "format string" part is inaccurate. The suggestion is to use the *f functions regardless of whether the message string has formatting or not (if I understood correctly).

Copy link
Contributor

@mmorel-35 mmorel-35 Oct 17, 2024

Choose a reason for hiding this comment

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

In https://golangci-lint.run/usage/linters/#testifylint

The comment is:

To require f-assertions if format string is used.

Copy link
Contributor Author

@ghouscht ghouscht Oct 17, 2024

Choose a reason for hiding this comment

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

You're right, even in the documentation from golangci-lint it is not very accurate. I think it something like

Require f-assertions (e.g. assert.Equalf) if a message is passed to the assertion.

might be better.

Copy link
Member

Choose a reason for hiding this comment

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

How about

Require f-assertions (e.g. assert.Equalf) if a message is passed to the assertion, even there is no variable-length variables, i.e. require require.NoErrorf for both cases below,
require.NoErrorf(t, err, "whatever message")
require.NoErrorf(t, err, "whatever message: %v", v)

@ghouscht ghouscht force-pushed the testifylint-formatter branch from be02cdb to 4af1959 Compare October 17, 2024 12:09
@ghouscht ghouscht force-pushed the testifylint-formatter branch from 4af1959 to ff4a8df Compare October 17, 2024 12:10
@mmorel-35
Copy link
Contributor

/test pull-etcd-integration-1-cpu-amd64

@ghouscht
Copy link
Contributor Author

/test pull-etcd-integration-1-cpu-amd64

One last try, seems there is always some kind of timeout in this test.

@ahrtr
Copy link
Member

ahrtr commented Oct 18, 2024

From golang programming perspective, I think we still prefer non-f-functions (i.e. fmt.Print) to f-functions (i.e. fmt.Printf) when there is no variable-length parameters.

For example, we prefer to use Print instead of Printf when no variable-length parameters.

in fmt package

func Print(a ...any) (n int, err error)
func Printf(format string, a ...any) (n int, err error)

in log package

func (l *Logger) Print(v ...any)
func (l *Logger) Printf(format string, v ...any)

But in stretchr/testify, each f-function is actually a syntax sugar of corresponding non-f-function. For example, Containsf is just a simple encapsulation of Contains. also refer to here.

So there is no reason to keep both. But they can't simplify remove anyone otherwise it will break lots of application's tests.

func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
	if h, ok := t.(tHelper); ok {
		h.Helper()
	}
	return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
}

So it's accepted to always require f-functions for stretchr/testify, but not for golang standard lib.

Copy link
Member

@ahrtr ahrtr left a comment

Choose a reason for hiding this comment

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

LGTM

Thanks

Copy link
Member

@ivanvc ivanvc left a comment

Choose a reason for hiding this comment

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

To @ahrtr's point, I agree it may not be straight forward if you're not familiar with stretchr/testify. When I initially saw the pull request I had to check the documentation to understand the issue and the linter rule.

But with that aside, it LGTM. Thanks, @ghouscht.

@k8s-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ahrtr, ghouscht, ivanvc, mmorel-35

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ahrtr ahrtr merged commit a7dcfdb into etcd-io:main Oct 22, 2024
33 checks passed
@ahrtr
Copy link
Member

ahrtr commented Oct 22, 2024

Raised a followup #18766

@ghouscht ghouscht deleted the testifylint-formatter branch November 7, 2024 08:25
@Antonboom
Copy link

Hi, guys

@ghouscht appeciated for using of testifylint. @mmorel-35, thank you for support.

@ahrtr, @ivanvc I improved the linter description based on your threads:

  1. https://github.com/Antonboom/testifylint?tab=readme-ov-file#3
  2. docs: improve testifylint description of require-f-funcs flag golangci/golangci-lint#5131

Also, I reviewed the testify code deeper and was surprised, but you can use non-string arg in asserts if this is the single argument, like

assert.Equal(a, b, new(time.Time))

It leads to the following points:

Thanks! 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

7 participants