-
Notifications
You must be signed in to change notification settings - Fork 3.9k
core: add strongly-typed ServiceConfigProto class for test #4369
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
Conversation
f8df92e
to
51e2873
Compare
Not sure how I feel about this. SC was intentionally designed to have full flexibility in representation, with the good and the bad. By making our tests not match what real data will be sent in, we run the risk of blinding ourselves. I understand this is test only code, and it would make testing easier. I don't know if it is a long term solution, as it doesn't match gRFC semantics. It would be nice to have static runtime checks that the data is valid, though. |
51e2873
to
614c0ed
Compare
@carl-mastrangelo I agree that SC was intentionally designed to have full flexibility in representation, |
d83a9f9
to
f368434
Compare
f97a853
to
26ab6ec
Compare
26ab6ec
to
9f4b51c
Compare
9f4b51c
to
dd33de8
Compare
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'm fine with using protobuf to construct the JSON, but I don't see what the gain as written is; the code seems like it would have been clearer with just big JSON literals. It looks like there's a drive to avoid duplication, but it seems to have a negative impact to the test clarity.
@@ -0,0 +1,227 @@ | |||
// Copyright 2015, gRPC Authors |
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.
Where did this file come from?
|
||
Name.Builder name1 = Name.newBuilder().setService("fooService1").setMethod("barMethod1.1"); | ||
methodConfigBuilder.addName(name1); | ||
expectedNames.add(protobufToJson(name1)); |
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 see this pattern frequently here. But forming up input and expected values simultaneously makes it harder to see what both are. Duplicating the contents would probably be much more clear and would actually be shorter. Copying+pasting between input and output is not a bad thing for tests.
public class ServiceConfigUtilTest { | ||
|
||
@Test | ||
public void getMethodConfigFromServiceConfig() throws Exception { |
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 is this method so huge? Isn't it just testing a basic getter? The method being tested doesn't even care about the contents of the individual configs. It seems like it should just have a simple assertSame()
and mostly ignore the configs themselves.
// TODO(zdapeng): getRetryThrottling from service config | ||
|
||
@Test | ||
public void getNameListFromMethodConfig() throws Exception { |
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 unnecessarily long as well.
|
||
@Test | ||
public void getMethodFromName() throws Exception { | ||
String service = "fooService"; |
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 is this a variable?
@Test | ||
public void getMethodFromName() throws Exception { | ||
String service = "fooService"; | ||
String method = "barMethod"; |
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.
Inlining this seems like it'd be so much more clear:
Map<String, Object> name1Json = protobufToJson(
Name.newBuilder().setService("fooService").setMethod("barMethod"));
assertEquals("barMethod", ServiceConfigUtil.getMethodFromName(name1Json));
Just to point out, the JSON version seems pretty obvious:
Map<String, Object> name1Json = parse("{\"service\":\"fooService\",\"method\":\"barMethod\"}");
assertEquals("barMethod", ServiceConfigUtil.getMethodFromName(name1Json));
All the backslashes are annoying; I'd probably make parse() include a replace("'", "\"")
so that I could write the literal as "{'service':'fooService','method':'barMethod'}"
.
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.
Will inline them.
These (proto version and JSON version) are two different tests. The former is to guarantee ServiceConfigUtil
consistent with service_config.proto
, whereas the latter emphasizes on logic correctness of ServiceConfigUtil
.
Maybe I should rename the test class to ServiceConfigProtoConsistencyTest
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.
:-/. Do we really need per-field checks for consistency between proto and JSON? Especially given that isn't a "blessed" proto. Also, it's not clear that's actually what the point of this test was. Why wouldn't the test have only set the method; why did it bother setting the service name?
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.
Otherwise what test would find inconsistency like b/78345359 ?
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.
So should that test be internal then? I see no reason to believe this proto would be kept up-to-date, as nothing uses it. I'd be happy to have a proto schema that would be deemed equivalent to the JSON spec, but at present this proto isn't it (and would need modifications before that was possible).
Also, again, the tests are doing lots of things more than checking whether the field names match. It isn't at all clear what is being tested.
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.
That makes sense. Removed the test.
…h service config proto" This reverts commit dd33de8.
closing the PR because it's not convincing that service config proto is helpful for test. |
Add service_config.proto in test module.
This can generate strongly-typed service config object for testing.
The added test did find a bug that some keys in the proto did not match the json keys in the spec (b/78345359).