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

xds/resolver: cleanup tests to use real xDS client 3/n #5953

Merged
merged 4 commits into from Jan 25, 2023

Conversation

easwars
Copy link
Contributor

@easwars easwars commented Jan 18, 2023

#resource-agnostic-xdsclient-api

RELEASE NOTES: n/a

@@ -104,12 +107,12 @@ type testClientConn struct {
}

func (t *testClientConn) UpdateState(s resolver.State) error {
t.stateCh.Send(s)
t.stateCh.Replace(s)
Copy link
Member

Choose a reason for hiding this comment

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

FYI: this seems okay as long as everywhere we read from this channel is resilient - as in, if the expected value isn't read, it reads again. Otherwise, you can run into races if you read from the channel before it's written.

And even then, we can have false positives. E.g.:

  1. Random setup thing happens that pushes the expected value.
  2. Test condition occurs, which will result in pushing something bad here.
  3. Read expected value from channel and pass test.
  4. Bad value we were hoping to test is actually pushed.

Forcing pulling every update off the channel effectively ensures the above won't happen.

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 both options here have problems, so I'm fine with this change.

return nil
}

func (t *testClientConn) ReportError(err error) {
t.errorCh.Send(err)
t.errorCh.Replace(err)
Copy link
Member

Choose a reason for hiding this comment

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

Should this use the same channel as above? The signals are supposed to be mutually exclusive, and at some point we may want to refactor things to make the two conditions happen via the same call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I switched to Replace() mainly to workaround go-control-plane's behavior when the xDS client NACKs an update. The go-control-plane keeps resending the same update until it is ACKed. In one of our test scenarios where we test that a NACKed update results in the error being propagated to the channel, the test logic only reads the error out of the testClientConn once. But since the go-control-plane keeps sending the same update again and again, the resolver receives the same error from the xDS client and has to push it up to the ClientConn. Without a Replace() here, the test will fail with a leaked goroutine.

Changing this to use the same channel will make things more complicated, because I cannot reliably call Replace() because I won't know whether the item that I'm pulling from the channel is an update or an error.

Copy link
Member

Choose a reason for hiding this comment

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

So what will we do if we refactor the resolver API to merge ReportError and Update? We can still use a different channel if the Update reflects an error, I suppose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that seems doable to me. I think we have this testClientConn implementation in a few other places as well. So, we would have to get to them as well.

@dfawley dfawley assigned easwars and unassigned dfawley Jan 25, 2023
@easwars easwars merged commit a6376c9 into grpc:master Jan 25, 2023
1 check passed
@easwars easwars deleted the xds_resolver_test_cleanup_3 branch January 25, 2023 03:16
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants