man-group / dapr-sidekick-dotnet

Dapr Sidekick for .NET - a lightweight lifetime management component for Dapr
Apache License 2.0
175 stars 21 forks source link

Use dapr sidekick with an integration test #51

Open BartNetJS opened 1 year ago

BartNetJS commented 1 year ago

I try to use the dapr sidekick with an integration test (Using Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory).

I can see in the output log:

Dapr Process Status Change: Stopped -> Initializing
Host application is initializing, waiting to start Dapr process...
Host application ready, starting Dapr process
Stopping Process "daprd" PID:null
Dapr Process Status Change: Initializing -> Stopping
Dapr Process Status Change: Stopping -> Stopped
Dapr Process Status Change: Stopped -> Initializing
Dapr expected process name set to "daprd"
Dapr initial directory: "C:\Users\[myname]\.dapr"
Dapr runtime directory: "C:\Users\[myname]\.dapr"
Dapr process binary: "C:\Users\[myname]\.dapr\bin\daprd.exe"
Dapr Process Status Change: Initializing -> Starting
Environment variable "DAPR_GRPC_PORT" set to 50002
Environment variable "DAPR_HTTP_PORT" set to 3501
Starting Process "C:\Users\[myname]\.dapr\bin\daprd.exe" with arguments '"--app-id jp-core --app-port 8500 --dapr-grpc-port 50002 --dapr-http-port 3501 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users\[myname]\.dapr\config.yaml --components-path C:\Users\[myname]\.dapr\components"'

I also wait for IDaprSidecarHost.CheckHealthAsync() to be true

What I noted while debugging is the the dapr http port from the daprclient is set to 3500, and not 3501 as logged above.

Any idea how I achieve this?

Note: when i start my api, the sidecar it is started fine:

[18:13:31 INF] Dapr Process Status Change: Stopped -> Initializing

[18:13:31 INF] Host application is initializing, waiting to start Dapr process... [18:13:31 INF] Host application ready, starting Dapr process [18:13:32 INF] AppId not specified, assigning default value: core-api [18:13:32 INF] Dapr expected process name set to daprd [18:13:32 INF] Dapr initial directory: C:\Users[myname].dapr [18:13:32 INF] Dapr runtime directory: C:\Users[myname].dapr [18:13:32 INF] Dapr process binary: C:\Users[myname].dapr\bin\daprd.exe [18:13:32 INF] Dapr Process Status Change: Initializing -> Starting [18:13:32 INF] Environment variable DAPR_GRPC_PORT set to 50002 [18:13:32 INF] Environment variable DAPR_HTTP_PORT set to 3501 [18:13:32 INF] Starting Process C:\Users[myname].dapr\bin\daprd.exe with arguments '--app-id core-api --app-port 5088 --dapr-grpc-port 50002 --dapr-http-port 3501 --log-as-json --log-level debug --metrics-port 9090 --placement-host-address 127.0.0.1:6050 --config C:\Users[myname].dapr\config.yaml --components-path C:\Users[myname].dapr\components' [18:13:32 INF] Process daprd PID:48396 started successfully [18:13:33 INF] starting Dapr Runtime -- version 1.10.2 -- commit d02fb79c051f8d7d45097d5eb06b3153ce4a3a24 [18:13:33 INF] log level set to: debug [18:13:33 INF] metrics server started on :9090/ [18:13:33 INF] Resiliency configuration loaded. [18:13:33 INF] standalone mode configured

badgeratu commented 1 year ago

Hi can you please upload a test solution demonstrating the issue?

BartNetJS commented 1 year ago

I've uploaded a sample here https://github.com/BartNetJS/dapr-sidekick-sample

edwardschipper commented 1 year ago

The main reason why your integration test is not working is due to the fact that WebApplicationFactory (TestServer) is not creating a real network socket. The HttpClient that WebApplicationFactory provides does not do actual networking. So also Dapr sidecar (started by Dapr SideKick) is not able to connect to your test application. And therefor the health checks will fail.

I have been able to work around this by starting a proxy server (e.g. AspNetCore.Proxy) in the startup phase of the integration test. This proxy is listening to a real network port and routes all http calls to the HttpClient associated with the WebApplicationFactory. The Dapr Sidecar will be configured to communicate through the proxyserver with the application. The setup routine is conceptually as follows:

AndreasKim commented 1 year ago

Hallo. Thank you for the information about this! I was giving it a try, but Im getting stuck at porting all calls from the proxy to the HttpClient. How do I get AspNetCore.Proxy to do this kind of routing? Do you maybe have a working code sample of your solution?