-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
xdsclient: cleanup listener watchers test #5506
xdsclient: cleanup listener watchers test #5506
Conversation
I'd appreciate if @dfawley can also take a quick look at this. But I really want @zasweq to take a good look. I felt that the existing tests were very hard to read, over-specified, relying too much on internal state etc. So, I want to make sure the new ones are easier to read for someone who is not super familiar with them. |
Gentle ping ... |
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, thanks for doing this, much cleaner. The old tests were very hard to understand. Minor nits throughout.
xds/internal/xdsclient/watchers.go
Outdated
@@ -28,6 +28,7 @@ import ( | |||
// after the watcher is canceled. The caller needs to handle this case. | |||
func (c *clientImpl) WatchListener(serviceName string, cb func(xdsresource.ListenerUpdate, error)) (cancel func()) { | |||
n := xdsresource.ParseName(serviceName) | |||
logger.Infof("easwars: parsed name is %+V, %s", n, n) |
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.
Delete.
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.
Oops .. sorry
// TestLDSWatch_ThreeWatchesForDifferentResourceNames covers the case where | ||
// three watchers exist across two listener resources. The following sequence of | ||
// events happen: | ||
// 1. Three watches are registered for two listener resources |
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.
"resources: two watches for one, one watch for the other"
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.
Done.
// happen: | ||
// 1. Two watches are registered for two listener resources | ||
// 2. Management server sends an update containing both resources. | ||
// 3. Management server sends an update removing one of the above resources |
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.
"removing one of the above resources, should trigger callback with resource removed error". To keep it consistent with Menghan's 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.
Reworded the comment with this suggestion.
// 1. Two watches are registered for two listener resources | ||
// 2. Management server sends an update containing both resources. | ||
// 3. Management server sends an update removing one of the above resources | ||
// 4. Management server sends an update which modifies the exisiting resource. |
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.
"resource. The second watch shouldn't receive any update."
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.
Reworded the comment with this suggestion.
// TestLDSWatch_ResourceRemoved covers the cases where a resource being watched | ||
// is removed from the management server. The following sequence of events | ||
// happen: | ||
// 1. Two watches are registered for two listener resources |
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.
Nit: Some of your events have periods after, some don't. I'd prefer periods. Here and other parts of the test.
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.
Removed lists altogether. So, no more periods or the lack of them.
|
||
// Register the third watch for a different listener resource. | ||
updateCh3 := testutils.NewChannel() | ||
ldsCancel3 := client.WatchListener(fmt.Sprintf("xdstp:///envoy.config.listener.v3.Listener/%s", ldsName), func(u xdsresource.ListenerUpdate, err error) { |
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.
Optional: Make this fmt.Sprintf(expression) a var since used twice.
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.
Actually, this is used 10 times. Package level const like ldsName/rdsName?
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.
Done.
defaultTestShortTimeout = 10 * time.Millisecond // For events expected to *not* happen. | ||
) | ||
|
||
var cmpOpts = []cmp.Option{ |
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.
Is there a style reason this variable only used once is declared here rather than in the function it's used in?
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.
When I first added this, I though it would be used from multiple places. Didn't realize that it was being used only from one place. Moved it to that function.
defer client.Close() | ||
|
||
const ( | ||
ldsName = "xdsclient-test-lds-resource" |
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.
Nit: These two consts are declared 7 times, taking up 14 lines. Make this a package scoped const?
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.
Done.
} | ||
|
||
// Update the second listener resource on the management server. The first | ||
// watcher should not see an update, while the second wather should. |
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.
watcher*
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.
Done.
t.Fatalf("update received with error: %v, want %q", gotErr, wantNACKErr) | ||
} | ||
|
||
// Verify that the watcher requesting for the good resource receives a good update. |
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 comment wraps past 180. Perhaps reword to "Verify that the watcher watching the good resource". "Requesting for the good resource" feels off.
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.
Done.
Thanks for review @zasweq. Addressed all comments. |
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.
LGTM outside of very minor comment nits. Code looks good.
// TestLDSWatch covers the case where a single watcher exists for a single | ||
// listener resource. The test verifies the following scenarios: | ||
// 1. An update from the management server containing the resource being | ||
// watched, results in the invocation of the watch callback |
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.
Super nit: s results/should result, should not result for 2 and 3. Also periods after?
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.
Done. Here and in other comments. Thanks.
tests := []struct { | ||
desc string | ||
resourceName string | ||
watchedResource *v3listenerpb.Listener // The resource being watched. |
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.
Yeah, it's fine, I feel mildly about it. Maybe will help future readers.
// exist for a single listener resource. The test verifies the following | ||
// scenarios: | ||
// 1. An update from the management server containing the resource being | ||
// watched, results in the invocation of both watch callbacks |
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.
Similar to above, s/results to should result and s/does not result/should not result and add periods.
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.
Done.
|
||
// TestLDSWatch_ResourceCaching covers the case where a watch is registered for | ||
// a resource which is already in the cache. The test verifies that the new | ||
// watch is handled from the cache, without a request being sent to the |
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.
Super nit: handled from cache meaning? handle could mean a lot of things, including invoking watch callback with error. Can you switch this statement to receives update from resources present in cache or something.
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.
Done. Thanks.
// is removed from the management server. The test verifies that removing | ||
// resources from the management server triggers the watch callback with | ||
// resource removed error. It also verifies that the watch callback for an | ||
// unrelated resource is not invoked during the above flow. |
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.
Optional: also talk about line 656 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.
Done.
}) | ||
defer ldsCancel2() | ||
|
||
// Configure the management server two listener resources. One of these is a |
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.
server with two
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.
Done.
// TestLDSWatch_PartialValid covers the case where a response from the | ||
// management server contains both valid and invalid resources and is expected | ||
// to be NACK'ed by the xdsclient. The test verifies that watchers corresponding | ||
// to the valid resource (in the response) receive the update, while watchers |
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.
in the response is implied?
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.
Removed.
|
||
// Register two watches for two listener resources and have the | ||
// callbacks push the received updates on to a channel. | ||
resourceName1 := ldsName |
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.
Why are you aliasing here? I actually think it improves readability but wanted to hear an explanation from you.
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.
Same. I thought the distinction between the resources (just the fact that they correspond to different resources) was more important here than whether the resource name is of the old style or the new style.
Thank you very much for the detailed review. |
rdsNameNewStyle = "xdstp:///envoy.config.listener.v3.Listener/xdsclient-test-rds-resource" | ||
) | ||
|
||
func newStringP(s string) *string { |
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.
Is this unused? Or used by other tests that weren't changed 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.
Removed. Maybe it was used at some point in time.
// A very short deadline is used while waiting for the update, as this function | ||
// is intended to be used when an update is not expected. | ||
func verifyNoListenerUpdate(ctx context.Context, updateCh *testutils.Channel) error { |
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.
In this case, why require a context parameter?
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.
The incoming context will have the overall test deadline. And then we apply a shorter deadline here. This way, the callsite can have a single context and pass it to both verifyNoListenerUpdate
and verifyListenerUpdate
.
LGTM. |
b2c81ec
to
1d2733d
Compare
Current tests use way too much magic and rely on a lot of internal state. These were written prior to us having a go-control-plane management server.
This change tests exactly all the functionality that was being tested earlier, but uses a real management server and relies on actual events happening instead of internal state.
Once this change is merged, I will send PRs to switch the other watcher tests as well. Then, we will be able to get rid of some complicated test setup logic.
RELEASE NOTES: none