docker compose jest集成测试无法生成容器内http请求RequestError:错误:getaddrinfo ENOTFOUND

docker compose jest集成测试无法生成容器内http请求RequestError:错误:getaddrinfo ENOTFOUND,http,docker,docker-compose,axios,jestjs,Http,Docker,Docker Compose,Axios,Jestjs,我有一个docker compose堆栈和几个容器。这两个问题是一个扩展的python:3-onbuild容器(参见基本图片),其中falcon Web服务器正在运行,而一个基本的节点:8.11-alpine容器正在尝试向python Web服务器发出post请求。python Web服务器正在对postgres:alpine容器进行数据库调用。这是我的docker compose.yml文件的简化版本: 版本:“3.6” 服务: 应用程序:#python:3-onbuild 端口: - 500

我有一个docker compose堆栈和几个容器。这两个问题是一个扩展的
python:3-onbuild
容器(参见基本图片),其中falcon Web服务器正在运行,而一个基本的
节点:8.11-alpine
容器正在尝试向python Web服务器发出post请求。python Web服务器正在对
postgres:alpine
容器进行数据库调用。这是我的
docker compose.yml
文件的简化版本:

版本:“3.6”
服务:
应用程序:#python:3-onbuild
端口:
- 5000
建造:
上下文:..//
dockerfile:infra/docker/app.dockerfile
lambda:#节点:8.11-1
端口:
- 10000
建造:
上下文:..//
dockerfile:infra/docker/lambda.dockerfile
取决于:
-应用程序
db:#博士后:阿尔卑斯山
端口:
- 5432:5432
建造:
上下文:..//
dockerfile:infra/docker/db.dockerfile
我有一套集成测试要通过。当我使用外部世界的端点运行测试时(https python服务器运行与
app
服务相同的代码),所有测试都通过了。当我试图从我的
docker compose
堆栈中对
app
服务发出这些请求时,问题就出现了,特别是从
lambda
服务到
app
服务

我不认为这是一个时间问题。在我的jest套件的
beforeAll
函数中,我轮询python服务器100秒,每10秒轮询一次,如下所示:

在我的玩笑测试中

beforeAll(异步()=>{
const endpointUrl=getEndpointUrl();
const status=等待检查状态(endpointUrl,10);
//注意:永远不要到达此行,在5分钟超时之前开始测试
log(`[integration.test]:status=${status}`);
}, 5 * 60 * 1000); // 异步功能的5分钟超时
其中定义了
checkStatus()

/**
*每10秒检查一次后端的状态,n次
*@param{string}endpointUrl
*@param{number}n
*/
导出函数checkStatus(endpointUrl:string,n:number):承诺{
log(`[lib][checkStatus]:超时日期之前=${date()}`);
返回新承诺((解决、拒绝)=>{
checkStatusHelper(endpointUrl、n、解析、拒绝);
});
}
函数checkStatusHelper(endpointUrl,n,resolve,reject):void{
如果(n==0)拒绝();
设置超时(()=>{
log(`[lib][checkStatus]:超时日期之后${n}=${date()}`);
rp.get(`${endpointUrl}/status`)
。然后(res=>{
log(`[lib][checkStatus]:请求日期之后=${date()}`);
log(`[lib][checkStatus]:res=${res}`);
决心(“成功”);
})
.catch(错误=>{
log(`[lib][checkStatus]:err=${err}`);
checkStatusHelper(端点URL,n-1,解析,拒绝);
});
}, 10 * 1000);
}
我得到如下输出(使用
request promise native
):

console.log src/lib.ts:30
[lib][checkStatus]:超时日期之前=2018年5月11日星期五01:54:10 GMT+0000(UTC)
console.log src/lib.ts:39
[lib][checkStatus]:超时日期后10=2018年5月11日星期五01:54:20 GMT+0000(UTC)
console.log src/lib.ts:47
[lib][checkStatus]:err=RequestError:Error:getaddrinfo ENOTFOUND应用程序:5000
console.log src/lib.ts:39
[lib][checkStatus]:超时日期9=2018年5月11日星期五01:54:31 GMT+0000(UTC)后
console.log src/lib.ts:47
[lib][checkStatus]:err=RequestError:Error:getaddrinfo ENOTFOUND应用程序:5000
#等等。。。
使用
axios
而不是
request promise native

  console.log src/lib.ts:30
    [lib][checkStatus]: before timeout date = Fri May 11 2018 01:56:57 GMT+0000 (UTC)

  console.log src/lib.ts:39
    [lib][checkStatus]: after timeout date 10 = Fri May 11 2018 01:57:07 GMT+0000 (UTC)

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Error: getaddrinfo ENOTFOUND app app:5000
        at Object.dispatchError (/Halloo/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:65:19)
        at Request.client.on.err (/Halloo/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:676:20)
        at emitOne (events.js:121:20)
        at Request.emit (events.js:211:7)
        at Request.onRequestError (/Halloo/node_modules/request/request.js:878:8)
        at emitOne (events.js:116:13)
        at ClientRequest.emit (events.js:211:7)
        at Socket.socketErrorListener (_http_client.js:387:9)
        at emitOne (events.js:116:13)
        at Socket.emit (events.js:211:7) undefined

  console.log src/lib.ts:47
    [lib][checkStatus]: err = Error: Network Error

  console.log src/lib.ts:39
    [lib][checkStatus]: after timeout date 9 = Fri May 11 2018 01:57:18 GMT+0000 (UTC)

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Error: getaddrinfo ENOTFOUND app app:5000
        at Object.dispatchError (/Halloo/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:65:19)
        at Request.client.on.err (/Halloo/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:676:20)
        at emitOne (events.js:121:20)
        at Request.emit (events.js:211:7)
        at Request.onRequestError (/Halloo/node_modules/request/request.js:878:8)
        at emitOne (events.js:116:13)
        at ClientRequest.emit (events.js:211:7)
        at Socket.socketErrorListener (_http_client.js:387:9)
        at emitOne (events.js:116:13)
        at Socket.emit (events.js:211:7) undefined

  console.log src/lib.ts:47
    [lib][checkStatus]: err = Error: Network Error

# etc ...
我也不认为这不是一个网络问题。如果我注释掉我的测试步骤并让
lambda
服务正常启动,我可以使用ssh连接到lambda容器中,并使用
axios
request promise native
测试连接。此
/status
端点仅返回数据库中的所有表名,以确保数据库容器也正常运行。这几乎能在瞬间起作用,而且远不到100秒

$node
>常量axios=require('axios')
未定义
>axios.get()http://app:5000/status,然后(res=>console.log(res.data));
允诺{
,
域:
领域{
域:空,
_事件:{error:[函数:debugDomainError]},
_事件提示:1,
_maxListeners:未定义,
成员:[]}
>[['表0'],
[‘表1’],
[‘表2’],
[‘表3’],
[‘表4’],
['表5']]

我想也许我不能将jest用于这些目的,但我觉得我可以,因为当我将url更改为在aws中运行的生产https端点,并注释掉jest套件中的
beforeAll()
步骤时,一切都会完美无瑕地工作。

我的jest配置出现问题

Jest中的默认环境是通过jsdom的类似浏览器的环境。如果要构建节点服务,则可以使用节点选项来使用类似节点的环境

要解决此问题,我必须将其添加到jest.config.js文件中:

{
  // ...
  testEnvironment: 'node'
  // ...
}
资料来源: