Skip to content

feat: getGrpcClient in integration TestKit, #568#606

Merged
patriknw merged 6 commits intomainfrom
wip-568-grpc-it-patriknw
Oct 15, 2021
Merged

feat: getGrpcClient in integration TestKit, #568#606
patriknw merged 6 commits intomainfrom
wip-568-grpc-it-patriknw

Conversation

@patriknw
Copy link
Copy Markdown
Contributor

References #568

@patriknw
Copy link
Copy Markdown
Contributor Author

I haven't updated Scala samples yet because waiting for #592 to be merged first

@raboof
Copy link
Copy Markdown
Contributor

raboof commented Oct 12, 2021

I haven't updated Scala samples yet because waiting for #592 to be merged first

Now merged!

@patriknw
Copy link
Copy Markdown
Contributor Author

thanks, then I'll continue

| * Use the generated gRPC client to call the service through the Akka Serverless proxy.
| */
| private final ${serviceName}Client client;
| private final $serviceName client;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OK, so we lose the information that this is a client, which I think means we lose access to the 'power api' for the client - seems like a bit of a shame but perhaps was tricky to do otherwise?

Copy link
Copy Markdown
Contributor Author

@patriknw patriknw Oct 12, 2021

Choose a reason for hiding this comment

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

That is what we have for the client from the Context too. It was intentionally done like that because we thought too much "power" shouldn't leak to the users. If you see a use case where the client is needed you can create an issue about it (maybe we can support both and detect what kind of class that is passed in).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One use case would be to pass metadata/headers I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added issue #619

| public ${testClassName}() {
| client = ${serviceName}Client.create(testKit.getGrpcClientSettings(), testKit.getActorSystem());
| public $testClassName() {
| client = testKit.getGrpcClient($serviceName.class, "$serviceName");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it intentional to have both the class and the service name here? It looks like the 'serviceName' is passed in to find the 'right' implementation of this API from the config, which could be either an external (intra-service) one or the implementation in 'this' service. Since we always want to test the local implementation, perhaps it would be nice if we could have a getGrpcClient method that infers the 'local' service name, instead of requiring it here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While ${serviceName}Client.create(testKit.getGrpcClientSettings(), testKit.getActorSystem()); was rather verbose, I did like the "no tricks up our sleeve" aspect of it. What advantage does getGrpcClient have here? Caching the clients I think?

Copy link
Copy Markdown
Contributor Author

@patriknw patriknw Oct 12, 2021

Choose a reason for hiding this comment

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

The intention is to have the same API from integration tests as they are "used to" from the ActionContext.

For IntegrationTest the service name is not used. I can try to remove it from the testkit.

Since we always want to test the local implementation

Well, I was actually thinking that it could be possible to test a remote service in the same way (with different config), but that is maybe too advanced.

Copy link
Copy Markdown
Contributor Author

@patriknw patriknw Oct 13, 2021

Choose a reason for hiding this comment

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

I have removed the serviceName parameter, in TestKit

Comment on lines +30 to +33
private final CustomerService client;

public CustomerEntityIntegrationTest() {
client = CustomerServiceClient.create(testkit.getGrpcClientSettings(), testkit.getActorSystem());
client = testKit.getGrpcClient(CustomerService.class, "CustomerService");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I didn't think about this before, but since this method is not returning a client, but the service trait, maybe a more intuitive name would be: getService or serviceInstance.

The fact that is a gRPC client becomes irrelevant. I just want an implementation of CustomerService that will magically do the trick for me.

Sure, the users will get the sense that this is a client calling some remote API, but we may want to reserve that name (ie getGrpcClient) to use for the power API. In that case, we make it more explicitly that what is returned is an akka grpc client. WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For the record: In the main sources it is called getGrpcClient since it is also a way to re-use/manage lifecycle of any gRPC client you'd want to use, also for a non akkasls service somewhere.

@patriknw patriknw force-pushed the wip-568-grpc-it-patriknw branch 2 times, most recently from fb40195 to b8eb5eb Compare October 13, 2021 14:46
client.increase(IncreaseValue(counterId, 42)).flatMap { _ =>
client.decrease(DecreaseValue(counterId, 32))
)).futureValue
}.futureValue
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@raboof I'm not sure we can guarantee the order from two such "current" client.increase calls (there could be many async boundaries on the way), so I change it to sequential

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure we can guarantee the order from two such "current" client.increase calls

I agree we can't. I had assumed they'd end at 10 in whatever order they're applied though - though I'll admit I haven't checked, and perhaps that makes this a bad example :)

@@ -16,8 +16,11 @@

package com.akkaserverless.scalasdk.testkit
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@raboof this is the scalasdk AkkaServerlessTestKit changes if you would like to take a second look

@patriknw patriknw force-pushed the wip-568-grpc-it-patriknw branch from 59fb21f to 37d2b05 Compare October 14, 2021 10:00

override def materializer(): Materializer = Materializer(system)
override def materializer(): Materializer =
SystemMaterializer(system).materializer
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@johanandren note this change. If I'm not mistaken Materializer.apply(system) creates a new Materializer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, indeed, this is what was intended.

javaClient.closed().asScala
case scalaClient: AkkaGrpcScalaClient => scalaClient.close()
case scalaClient: AkkaGrpcScalaClient =>
scalaClient.closed
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks to @raboof for spotting this bug

@patriknw patriknw requested a review from johanandren October 15, 2021 06:39
Copy link
Copy Markdown
Contributor

@johanandren johanandren left a comment

Choose a reason for hiding this comment

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

LGTM but I wonder about all those empty unit tests

// ActionResult<Empty> result = testKit.decrease(CounterTopicApi.Decreased.newBuilder()...build());
}

}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we really check in the stub unit tests? It sort of makes it look like something actually is tested in the samples in the CI pr validation and also if we change how the code is generated we'll need to delete and re-check in for it to get up to date with codegen.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ok, I can remove, but it's difficult to "see" that it shouldn't be added when fiddling with the samples

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

eh, we already have many many of those added
leaving that as a separate cleanup if your find it important

@patriknw patriknw merged commit e08af33 into main Oct 15, 2021
@patriknw patriknw deleted the wip-568-grpc-it-patriknw branch October 15, 2021 09:06
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.

4 participants