-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix ExpandedValue sanitization on struct collection #14413
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 ExpandedValue sanitization on struct collection #14413
Conversation
… unmarshalling a confmap `useExpandedValue` would resolve ExpandedValues after checking if a collection's type was "stringy." For collections of structs, `isStringy` always returns false, causing all ExpandedValues to be sanitized to their parsed values and breaking decoding of string fields if the parsed value was not `string`. Now, `useExpandedValue` checks if it's dealing with a collection of structs; in which case, skip sanitization and rely on mapstructure's per-field decoding.
…n-on-struct-collection
|
As discussed with @mx-psi, I'm kindly pinging @jade-guiton-dd to this PR! |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #14413 +/- ##
==========================================
- Coverage 91.83% 91.79% -0.04%
==========================================
Files 677 677
Lines 42679 42680 +1
==========================================
- Hits 39195 39180 -15
- Misses 2427 2439 +12
- Partials 1057 1061 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hello 👋 Sorry, even after reading the existing code and your PR, I still don't really understand what the problem was. Could you expand on:
Reading the code, it seems to me that an array of structs should already be kept as-is by the sanitization operation. Did I miss something? |
The issue used to happen in cases like what this test does. When decoding an Commenting the fix and running the added tests fails with the error: Since the Sorry if I wasn't clear enough before, I hope my explanations help! |
|
Ah, it seems there was a misunderstanding on my part ( One thing I thought about is that, in the same way your PR delegates to |
|
I tested it and it also solves the issue and doesn't break any other tests. I do agree that removing the switch altogether would make the code simpler and would also resolve any edge cases like the one I brought up. What do you think? |
|
Regardless of Pablo's intent 2 years ago, I suspect it's not actually an optimization: I think However, I'm not 100% confident that this won't break someone somewhere ( |
confmap/internal/featuregates.go
Outdated
| featuregate.StageBeta, | ||
| featuregate.WithRegisterFromVersion("v0.144.0"), | ||
| featuregate.WithRegisterDescription("Disables early sanitization of ExpandedValue during config unmarshalling, allowing mapstructure to handle type conversion at the field level. Fixes decoding errors when environment variable values are parsed as non-string types (e.g., numbers, booleans) but need to be assigned to string fields."), | ||
| featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector/pull/14413#issuecomment-3754949484"), |
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.
All other featuregates reference issues directly instead of PRs.
Should I create an issue or is this good enough? Sorry.
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 referencing a PR should be fine.
confmap/internal/decoder.go
Outdated
| // converted based on its target field type. | ||
| if elemType.Kind() == reflect.Struct { | ||
| return data, nil | ||
| } |
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 still kept the original fix inside the old behavior since it's still required to fix the problem I encountered.
I'm happy to remove it if you think it's unnecessary.
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.
Hm, I doubt the original fix would cause issues, but out of caution, I'd rather have disabling the feature gate return to the previous behavior, bug included. I figure that if someone's setup is broken by the new fix, I think there's a reasonable chance they will be broken by the original fix as well.
To be clear although I don't remember exactly what I was thinking at that point I don't think my intent here was performance-related, it was probably more just an oversight/something behavior-related.
I agree with this, mapstructure is always arcane! |
- revert to old behavior when feature gate disabled, bug included
- test unmarshalling with both behaviors and expect error when feature
gate disabled
jade-guiton-dd
left a comment
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.
Looks good, just need to run make gotidy and add a change log entry (make chlog-new).
Codecov is claiming the old code in the if is completely untested, so I would also recommend confirming with a debugger whether the old code is being reached in the latter half of TestMapListWithExpandedValueIntValue. It could just be an issue with Codecov however.
0e6ef84 to
3f49486
Compare
| } | ||
|
|
||
| // TestStringyStructureWithExpandedValue tests the isStringyStructure path in useExpandValue | ||
| func TestStringyStructureWithExpandedValue(t *testing.T) { |
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.
With this new test, we should now cover all cases in both the new and old behavior.
3f49486 to
68015e6
Compare
- renamed featuregate - added test with a stringy collection - added changelog entry Co-authored-by: Jade Guiton <jade.guiton@datadoghq.com>
68015e6 to
97efc61
Compare
The e2e test module was not recording coverage for the parent `confmap/internal` package that it tests. This caused test coverage to appear as 0% even though the tests exercise the code. This adds the parent package to COVER_PKGS so coverage of `confmap/internal` is properly tracked for e2e tests.
confmap/internal/e2e/Makefile
Outdated
| include ../../../Makefile.Common | ||
|
|
||
| # Override COVER_PKGS to include the parent package that this e2e module tests | ||
| COVER_PKGS := go.opentelemetry.io/collector/confmap/internal,$(COVER_PKGS) |
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.
This seems to be needed since I am covering code in confmap/internal from the e2e module.
This feels out of scope of the PR to me and I would appreciate any suggestions on how we could handle this coverage issue!
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 we can do this in a separate PR if you are up to contributing it. In any case it's not a requirement for merging this PR (codecov is not a required check)
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.
Thank you. I will revert this commit and open a new PR.
In the meantime, do you have any ideas why the changelog validate is unhappy? I don't really understand the issue here.
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 an issue from other changelogs on main, so no worries.
.chloggen/fix-expandedvalue-sanitization-on-struct-collection.yaml
Outdated
Show resolved
Hide resolved
mx-psi
left a comment
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.
Almost there!
.chloggen/fix-expandedvalue-sanitization-on-struct-collection.yaml
Outdated
Show resolved
Hide resolved
.chloggen/fix-expandedvalue-sanitization-on-struct-collection.yaml
Outdated
Show resolved
Hide resolved
Co-authored-by: Pablo Baeyens <pbaeyens31+github@gmail.com>
|
Can you solve the merge conflict? Once you have dealt with that I can merge it |
246e428
|
Thank you for your contribution @theomagellan! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey. |
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description The e2e test module was not recording coverage for the parent `confmap/internal` package that it tests. This caused test coverage to appear as 0% even though the tests exercise the code. This adds the parent package to `COVER_PKGS` so coverage of `confmap/internal` is properly tracked for e2e tests. When looking at overall coverage of `confmap/internal/decoder.go`, it goes from 91.4% to 96.3% of statements. #### Link to tracking issue Issue was found in PR #14413 (review). <!--Describe what testing was performed and which tests were added.--> #### Testing Running `make gotest-with-cover` without the fix, then looking at coverage in percentage with ```bash go tool covdata percent -i=./coverage/unit -pkg=go.opentelemetry.io/collector/confmap/internal ``` Running these commands again with the fix added shows the improvement. The e2e tests can also be run individually to verify they're tracking parent package coverage: ```bash make -C confmap/internal/e2e test-with-cover # [...] coverage: 45.3% of statements in go.opentelemetry.io/collector/confmap/internal, go.opentelemetry.io/collector/confmap/internal/e2e, ) ``` <!--Describe the documentation added.-->
Description
useExpandedValuewould resolve ExpandedValues after checking if a collection's type was "stringy." For collections of structs,isStringyalways returns false, causing all ExpandedValues to be sanitized to their parsed values and breaking decoding of string fields if the parsed value was notstring.Now,
useExpandedValuechecks if it's dealing with a collection of structs; in which case, skip sanitization and rely on mapstructure's per-field decoding.Testing
Added tests relying on
configopaque.MapListwhich is an alias on the struct collection[]Pair