Skip to content

log/logtest: Redesign #6342

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

Closed
wants to merge 51 commits into from
Closed

Conversation

pellared
Copy link
Member

@pellared pellared commented Feb 19, 2025

Fixes #6341

  • Remove RecordFactory

    • The function is not used anywhere.
  • Change the result type of Recorder.Result from []*ScopeRecords to Recording et al.

    • The types represent better the data model. For instance it is a map of scope -> records. Previously each Logger (with e.g. with the same name) was producing a new ScopeRecords element.
  • Remove AssertRecordEqual

    • The new types are easier to compare with go-cmp, testify and even standard library. Give the user feedom on how to compare.
    • Add testable example on how to compare using go-cmp. This is probably going to our the way of testing log bridges and instrumentation libraries emitting log or event records. More log/logtest: Redesign #6342 (comment)
  • No Equal (59b557a)

    • We do not need it as we can use go-cmp. However, it even works testify and reflect.DeepEqual (sic!).
    • We can always consider adding it later if there would be a demand from user. Similarly a Compare could also be needed in case of bigger demand. However, it feels YAGNI.

Here are examples of how the current tests of log bridges can be improved:

@pellared pellared added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Feb 19, 2025
@pellared pellared changed the title log/logtest: Redesign [WIP] log/logtest: Redesign Feb 19, 2025
@pellared pellared changed the title [WIP] log/logtest: Redesign [Prototype] log/logtest: Redesign Feb 19, 2025
@pellared pellared marked this pull request as ready for review February 19, 2025 22:49
Copy link
Member

@dmathieu dmathieu left a comment

Choose a reason for hiding this comment

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

This looks very nice.
I think it would make sense to see what changes will be required in one of the bridges?

@pellared pellared self-assigned this Feb 20, 2025
@pellared pellared added pkg:API Related to an API package area:logs Part of OpenTelemetry logs labels Feb 20, 2025
@pellared pellared changed the title log/logtest: Redesign [DoNotMergeBeforeRelease] log/logtest: Redesign Feb 26, 2025
@pellared pellared changed the title [DoNotMergeBeforeRelease] log/logtest: Redesign log/logtest: Redesign Mar 5, 2025
Copy link

linux-foundation-easycla bot commented Mar 5, 2025

@pellared
Copy link
Member Author

pellared commented Mar 6, 2025

/easycla

@pellared
Copy link
Member Author

pellared commented Mar 6, 2025

@dmathieu, PTAL

@pellared
Copy link
Member Author

pellared commented Mar 6, 2025

@open-telemetry/go-maintainers, planning to merge on Monday my morning and start working on creating PRs in Contrib.

@pellared
Copy link
Member Author

pellared commented Mar 7, 2025

@open-telemetry/go-maintainers, planning to merge on Monday my morning and start working on creating PRs in Contrib.

This PR still needs an additional approval.

CHANGELOG.md Outdated
Comment on lines 18 to 19
- Remove `ScopeRecords`, `EmittedRecord`, `RecordFactory` types.
- Remove `AssertRecordEqual` function.
Copy link
Contributor

Choose a reason for hiding this comment

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

These need to be moved to the Removed section of the changelog.

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines 46 to 51
opts := []cmp.Option{
cmpopts.IgnoreFields(logtest.Record{}, "Context"), // Ignore Context.
cmpopts.IgnoreTypes(time.Time{}), // Ignore Timestamps.
cmpopts.SortSlices(func(a, b log.KeyValue) bool { return a.Key < b.Key }), // Unordered compare of the key values.
cmpopts.EquateEmpty(), // Empty and nil collections are equal.
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Please do not exemplify use of cmp. This project heavily uses testify/assert. We should match that with our example here.

Copy link
Member Author

@pellared pellared Mar 7, 2025

Choose a reason for hiding this comment

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

This was done following #6342 (comment)

I've liked working with go's CMP library when i've used it. It is definitely very powerful, but does take a while to figure out which options to pass. It would be good to document recommended options for most instrumentation tests. I suspect they will generally be the same for most instrumentation libraries

The main reason I do not want to use testify is (from #6342 (comment)):

With testify the biggest issue you cannot force []log.KeyValue to sort slices before comparing (unordered collection equality). This can make the test too much "white-boxed" and can easy break during refactoring.

The example draft PRs use cmp:

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I'm not in favor of this. We extensively use testify/assert throughout this and our other projects. We need to design testing libraries for the things we use, not have our testing libraries dictate to us what testing packages we use.

Copy link
Member

Choose a reason for hiding this comment

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

It seems to me the goal of this change is to allow both, the use of testify and its avoidance.
Maybe the example/doc should show both.

Copy link
Member Author

@pellared pellared Mar 7, 2025

Choose a reason for hiding this comment

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

  1. There are already some tests which use cmp in places where testify is not an effective choice. See: https://github.com/search?q=repo%3Aopen-telemetry%2Fopentelemetry-go%20github.com%2Fgoogle%2Fgo-cmp%2Fcmp&type=code
  2. We have nothing in CONTRIBUTING.md telling that we cannot use cmp or what are our testing strategies/technologies. And cmp is a recommended by the Go team for comparing structures: https://go.dev/wiki/TestComments
  3. At last, I think that the tests that use testify would still be benefit from this change. Next week, I will look into refactoring otelzap tests so that they use testify. For instance, I could use assert.ElementsMatch instead of assert.Equal for asserting record's attributes. However, it will not work correctly for "complex attributes". Yet, I think may be worth exploring.

Copy link
Contributor

@MrAlias MrAlias Mar 7, 2025

Choose a reason for hiding this comment

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

Really?

Here are all the places we currently use testify in otel. Here are all the places we use it in contrib.

Here are the places we use cmp in otel, and in contrib

That is 6109 uses of testify to 58.

This is pretty clear that we use testify in these projects. I don't think you can fairly say there is confusion about what technology we use here. A developer who has worked in either of the projects would not be unclear about what is the commonly used tooling.

Copy link
Contributor

Choose a reason for hiding this comment

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

At last, I think that the tests that use testify would still be benefit from this change.

If that is the case it needs to be shown. You are exemplifying a different technology than is used throughout our projects without showing the value to our existing development practices.

If you plan to show how this is a benefit, I am all for it. I do not think this should be merged prior to that given that should be the primary design driver, not cmp.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you would like, we can codify our defacto choice in using testify as our testing technology throughout our project in a policy. I have not opposition to that.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we want to remove our use of cmp to make it even clearer that we have a strong preference for using testify in our testing I am also not opposed to that.

Copy link
Member Author

Choose a reason for hiding this comment

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

If that is the case it needs to be shown. You are exemplifying a different technology than is used throughout our projects without showing the value to our existing development practices.

If you plan to show how this is a benefit, I am all for it. I do not think this should be merged prior to that given that should be the primary design driver, not cmp.

Ok. Then this is what I will be working on next week. Thanks for your feedback 👍

@pellared pellared requested a review from MrAlias March 7, 2025 17:41
Copy link
Contributor

@MrAlias MrAlias left a comment

Choose a reason for hiding this comment

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

It seems like this PR is not so much a PR about redesigning the logtest package as it is proposing we adopt a different testing strategy. This is an inappropriate way to achieve this type of change.

I appreciate refactoring this package as needed, but it needs to be centered on supporting the technologies we already use. If we want to undertake the monumental task of changing our testing technology that needs to be a proposal and project on itself.

Comment on lines 46 to 51
opts := []cmp.Option{
cmpopts.IgnoreFields(logtest.Record{}, "Context"), // Ignore Context.
cmpopts.IgnoreTypes(time.Time{}), // Ignore Timestamps.
cmpopts.SortSlices(func(a, b log.KeyValue) bool { return a.Key < b.Key }), // Unordered compare of the key values.
cmpopts.EquateEmpty(), // Empty and nil collections are equal.
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I'm not in favor of this. We extensively use testify/assert throughout this and our other projects. We need to design testing libraries for the things we use, not have our testing libraries dictate to us what testing packages we use.

Copy link
Member

@XSAM XSAM left a comment

Choose a reason for hiding this comment

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

I personally prefer testify than cmp, if one line of testify code can finish the job (compare and return; exit and print the diff when failed)

This one line of testify code is easy to write (not much of a chance to write a typo) and easy to understand

assert.Equal(t, want, got)

than cmp.

if diff := cmp.Diff(want, got); diff != "" {
	t.Errorf("Recorded records mismatch (-want +got):\n%s", diff)
}

For cmp, reviewers need additional attention since there is a chance of having a typo like diff == "".


We usually have a lot of data that need to be compared, so the gap in clearance between these two libraries can only be bigger.

@pellared
Copy link
Member Author

pellared commented Mar 8, 2025

After feedback received by @MrAlias and @XSAM, I think that if we have bigger issues with testify then we could consider adding something like https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest#AssertEqual. This would follow our existing patterns and would be a way mitigate the issues of testify that I mentioned before.

@pellared pellared marked this pull request as draft March 10, 2025 22:26
@pellared
Copy link
Member Author

I am closing this PR in favor of:

@pellared pellared closed this Mar 18, 2025
@github-project-automation github-project-automation bot moved this from In Progress to Done in Go: Logs (GA) Mar 18, 2025
@pellared pellared removed this from Go: Logs (GA) Mar 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:logs Part of OpenTelemetry logs pkg:API Related to an API package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make log/logtest more convenient
6 participants