Skip to content

MCS connection scaling interop tests for Java#12651

Open
kannanjgithub wants to merge 16 commits intogrpc:masterfrom
kannanjgithub:mcs-interop-tests
Open

MCS connection scaling interop tests for Java#12651
kannanjgithub wants to merge 16 commits intogrpc:masterfrom
kannanjgithub:mcs-interop-tests

Conversation

@kannanjgithub
Copy link
Contributor

No description provided.

}


case MCS_CS: {
Copy link
Member

Choose a reason for hiding this comment

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

If there's a new test, then that should be defined in https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do in the PR on the core repo.

try {
@SuppressWarnings("unchecked")
Map<String, ?> serviceConfigMap = (Map<String, ?>) JsonParser.parse(
"{\"connection_scaling\":{\"max_connections_per_subchannel\": 2}}");
Copy link
Member

Choose a reason for hiding this comment

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

We don't support connection scaling yet. So this test has never succeeded?

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, added a comment on the failing assertion now.

channelBuilder.overrideAuthority(serverHostOverride);
}
if (serviceConfig != null) {
if (testCase.equals(MCS_CS.toString())) {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of hacking up this method, can we create the channel within the scope of the test, like GOOGLE_DEFAULT_CREDENTIALS?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

.setOrcaOobReport(answer2)
.addResponseParameters(ResponseParameters.newBuilder().setSize(1).build()).build());
assertThat(queue.take()).isInstanceOf(StreamingOutputCallResponse.class);
assertThat(streamingOutputCallResponseObserver.isCompleted).isTrue();
Copy link
Member

Choose a reason for hiding this comment

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

I don't see how this is an okay transformation. Previously we were asserting there was a message. Why would we stop doing that?

Note that using isCompleted is weaker than what was there before.

  1. Because it is racy; take() was waiting until events occurred
  2. Because it doesn't verify that extra messages weren't received
  3. It should always fail, because streamObserver.onCompleted(); caused the server to close the stream.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some statements got messed up unintentionally regarding asserting message and stream completion.

Restored the blocking queue.take() approach for determining stream completion to avoid race.


class StreamingOutputCallResponseObserver implements
StreamObserver<StreamingOutputCallResponse> {
private final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
Copy link
Member

Choose a reason for hiding this comment

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

The only reason this held Object was to store lastItem in it. I do think we want to preserve that approach, but if we didn't, we should change this to BlockingQueue<StreamingOutputCallResponse>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Preserved the existing approach to identify rpc completion.

return;
}
if (new String(request.getPayload().getBody().toByteArray(), UTF_8)
.equals(MCS_CS.description())) {
Copy link
Member

Choose a reason for hiding this comment

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

Please no. There's two regular approaches we use for tweaking the server's behavior:

  1. A field in the request proto (e.g., fill_username)
  2. Header metadata. I don't think we actually use this approach in the vanilla interop today, but we do do it for psm interop

(fill_username and the like are because of mistakes in the past where grpc-java verified the result message exactly. That means you can't add new fields to have them be ignored. We did want to verify the result was what we expected, but it would have probably been better to just verify the payload. But the behavior hasn't been changed, so we still need these knobs that enable result fields.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added new fields in request and response for setting the client socket address.

StreamingOutputCallResponse.newBuilder();
responseBuilder.setPayload(
Payload.newBuilder()
.setBody(payload));
Copy link
Member

Choose a reason for hiding this comment

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

We should store the result in a new field of the proto or in metadata.

The server shouldn't know what specific test is being run. It should just be told what to do and do it. And we want to allow mixing-and-matching the things the server can be told to do (e.g., if you want fill_username and fill_client_address (made up example) at the same time, you can)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

usage = true;
break;
}
} else if ("use_mcs".equals(key)) {
Copy link
Member

Choose a reason for hiding this comment

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

How about we let this be --mcs=2 (or not abbreviated, since mcs isn't clear without context), where the caller can specify what to limit the concurrency limit to.

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'd considered specifying the count as a value, but any value other than 2 would cause the test to fail, that's why I set the value in the server code.

usage = true;
break;
}
} else if ("use_mcs".equals(key)) {
Copy link
Member

Choose a reason for hiding this comment

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

Update usage output for the new argument

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}
} else if ("use_mcs".equals(key)) {
useMcs = Boolean.parseBoolean(value);
addressType = Util.AddressType.IPV4; // To use NettyServerBuilder
Copy link
Member

Choose a reason for hiding this comment

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

That's unfortunate. We really do want to support IPv6; IPv6-only is increasingly common. Also, it'd be good to stop hard-coding Netty for IPv4/IPv6. When this was done we only had the Netty server, but now we have the OkHttp server as well.

But it also looks pretty hard to fix in a "cleaner" way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a TODO to fix Netty server builder usage to work with either IPv4/6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants