PACT.Net无法分配请求的地址

时间:2018-06-29 10:24:30

标签: docker pact

我目前正在尝试在docker容器中运行pact.net示例测试,但是出现以下错误:

Starting test execution, please wait...
pact-consumer-tests    | [xUnit.net 00:00:19.9436627]     
pact_consumer.tests.AddConsumerTest.Add_customer [FAIL]
pact-consumer-tests    | Failed   
pact_consumer.tests.AddConsumerTest.Add_customer
pact-consumer-tests    | Error Message:
pact-consumer-tests    |  System.AggregateException : One or more errors 
occurred. (One or more errors occurred. (Cannot assign requested 
address)) (The following constructor parameters did not have matching 
fixture data: ConsumerApiPact data)
pact-consumer-tests    | ---- System.AggregateException : One or more 
errors occurred. (Cannot assign requested address)
pact-consumer-tests    | -------- System.Net.Http.HttpRequestException : 
Cannot assign requested address
pact-consumer-tests    | ------------ System.Net.Sockets.SocketException 
: Cannot assign requested address
pact-consumer-tests    | ---- The following constructor parameters did 
not have matching fixture data: ConsumerApiPact data
pact-consumer-tests    | Stack Trace:
pact-consumer-tests    |
pact-consumer-tests    | ----- Inner Stack Trace #1 
(System.AggregateException) -----
pact-consumer-tests    |    at 
PactNet.Mocks.MockHttpService.Host.RubyHttpHost.Start() in 
C:\projects\pact- 
net\PactNet\Mocks\MockHttpService\Host\RubyHttpHost.cs:line 65
pact-consumer-tests    |    at PactNet.PactBuilder.MockService(Int32 
port, JsonSerializerSettings jsonSerializerSettings, Boolean enableSsl, 
IPAddress host) in C:\projects\pact-net\PactNet\PactBuilder.cs:line 82
pact-consumer-tests    |    at 
pact_consumer.tests.context.ConsumerApiPact..ctor() in /app/pact- 
consumer.tests/context/ConsumerApiPact.cs:line 27
pact-consumer-tests    | ----- Inner Stack Trace -----
pact-consumer-tests    |    at 
System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, 
CancellationToken cancellationToken)
....

无论我发送到主机IPAddress.Any和IpAddress.Loopback的框架中什么,但是我仍然似乎遇到此问题?

我想念什么吗?它运行在没有其他服务运行的docker容器中。

我可以使用dotnet test在OSX上运行它,一切都很好。

非常感谢

理查德

2 个答案:

答案 0 :(得分:1)

System.Net.Sockets.SocketException : Cannot assign requested address肯定看起来系统无法绑定到端口-您确定主机上的端口可用(而不仅仅是Docker容器)吗?

答案 1 :(得分:1)

我在C#中遇到了相同的错误。在红宝石问题上可以使用相同的技术。我遇到了在Docker容器中运行的dotnet应用程序的问题。快速的答案是,它可能正在尝试连接到某物,但没有声音在监听或无法进入,因此您需要在Docker行中启用一些网络挂钩。对于该答案的其余部分,我将说明如何得出该结论。我正在运行从Github下载的EchoBot: https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/02.echo-bot

首先,我们将其构建到容器中并进行部署,然后尝试从机器人仿真器中使用它来重现错误。该模拟器正在我的桌面上运行,并通过端口3978连接到bot。

启动echobot容器,并在模拟器中使用它来查看原始错误:

$ docker run --rm -it --entrypoint=bash -p 3978:3978 myImage
# dotnet EchoBot1.dll
...
info: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
      Sending activity.  ReplyToId: adfa9af0-5f17-11ea-8765-033688f22eac
fail: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
      [OnTurnError] unhandled error : Cannot assign requested address
System.Net.Http.HttpRequestException: Cannot assign requested address ---> System.Net.Sockets.SocketException: Cannot assign requested address
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---

您可以看到存在套接字异常和无法分配套接字错误。我们可以从等式中删除docker,以查看错误是否发生变化。

从图片中删除docker以查看错误

$ dotnet run
...
info: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
      Sending activity.  ReplyToId: 3a427871-5f18-11ea-8765-033688f22eac
fail: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
      [OnTurnError] unhandled error : Connection refused
System.Net.Http.HttpRequestException: Connection refused ---> System.Net.Sockets.SocketException: Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---

您可以看到,相同的代码在docker外部运行时,错误实际上是拒绝连接。那么,我们该怎么做才能看到它的连接位置呢?如果您使用的是Linux,则可以在Windows上运行tcpdump或wireshark。

捕获网络数据包以查看是否存在出站连接

$tcpdump -ilo -n -v  | tee tcpdump-output
...
19:38:45.336179 IP (tos 0x0, ttl 64, id 12504, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.46215 > 127.0.0.1.52148: Flags [S], cksum 0xfe30 (incorrect -> 0xea5f), seq 549373294, win 65495, options [mss 65495,sackOK,TS val 3769835141 ecr 0,nop,wscale 7], length 0

里面会有很多垃圾,所以我将输出整理到一个文件中,然后使用编辑器删除那些分散注意力的行(例如DNS查询),但是您可以看到有些东西正在尝试连接移至端口52148。

事实证明,本地仿真器在同一端口上侦听,因此我需要将该端口连接到运行仿真器的桌面。有很多方法可以做到这一点,但是我更喜欢较旧的SSH方式,这很方便。

建立监听隧道

$ ssh nmishr@104.xxx.xxx.xxx -R 52148:localhost:52148

一旦我将侦听器挂接到本地主机上进行侦听,我们就需要使docker容器与主机对话,错误消失:

使用--network = host

运行docker
$ docker run --rm -it --entrypoint=bash --network=host myImage
# dotnet EchoBot1.dll
...
info: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
      Sending activity.  ReplyToId: c321ebb1-5f1a-11ea-8765-033688f22eac
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method EchoBot1.Controllers.BotController.PostAsync (EchoBot1), returned result Microsoft.AspNetCore.Mvc.EmptyResult in 518.6485ms.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action EchoBot1.Controllers.BotController.PostAsync (EchoBot1) in 550.6136ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 687.9129ms 200