Refactor how VisitPayloads is tested - #304
Conversation
| func (w *PayloadWalker) walkMessageField(m protoreflect.Message, fd protoreflect.FieldDescriptor) { | ||
| // A field of the same type as its parent (e.g. Failure.cause) would recurse | ||
| // forever. Payloads underneath it are reachable through the parent anyway. | ||
| if fd.Message().FullName() == m.Descriptor().FullName() { |
There was a problem hiding this comment.
Could we test one level of self-reference here? I tried removing o.GetCause() from the production visitor, and the full proxy test suite still passed even though payloads in nested failures were no longer visited. Either walking one level before cutting the cycle or adding a focused test with a payload under Failure.Cause should cover this.
There was a problem hiding this comment.
I don't think we want to modify the PayloadWalker to "visit deeper", since this test harness is really just using the type information. (So if T is sound, there is no need to check T again.)
But if I understand correctly, there is a testing gap here, in that PayloadWalker can only validate things known statically. Whereas the actual VisitPayloads(...) function actually operates on proto objects.
So I created a testcase that instantiates a failurepb.Failure with nested cause, failure_info, and encoded_attribute fields set. And it confirms that VisitPayloads(...) correctly visits each Payload.
|
@yuandrew PTAL. I don't think it makes sense to tweak the logic of the The updated diff is unintelligible, so just checkout the commit: |
028c531 to
046fd2f
Compare
046fd2f to
c096a27
Compare
What changed?
When building
api-goafter picking up changes from a feature I was working on, I got an expected test failure... but figuring out why it failed, and what thefunc populatePayload(root *proto.Message, msg proto.Message, require *require.Assertions, totalCount *int, count *int)function actually did was harder than I'd care to admit.This PR refactors the test code such that the (kinda massive)
populatePayload(...)function could be replaced with a newtype PayloadWalker struct. Which will keep track of how many messages it has seen, the number ofPayload(s)visited, and so on.Why?
There are several motivations for this refactoring:
Provide an actual error message instead of a stack overflow if encountering recursive proto types. (We don't have any today, but if you tried to add one... it wouldn't go over well.)
Update the tests to use a more common "table-driven" style.
Provide better contextual information in case the expected number of payloads changes.
Previously, you'd just see that "7 != 8". Now, the
PayloadWalkertype will keep track of the payloads it has visited and provide much more detail about what would have caused a test failure.Example output:
How did you test it?
make testPotential risks
The refactoring was done by my pal Claude. So it's possible this is GenAI slop and/or deeply flawed. But nothing seems out of place from a cursory review.
FWIW, this also apparently fixes a bug that was already present in how maps were visited.