通过bash脚本运行dotnet集成测试卡在启动状态问题求助
问题根因
两种启动方式的核心差异是dotnet test的进程运行上下文:
- 直接将ENTRYPOINT设为dotnet命令时,dotnet进程为容器的PID 1进程,直接继承容器的标准输入输出、信号处理规则,运行环境和本地测试完全一致
- 通过shell脚本启动时,shell进程为PID 1,dotnet test是shell的子进程,shell中间层会改变终端属性、默认不转发控制信号,极易导致dotnet test运行异常
解决方案
1. 优先修改启动脚本,用exec替换shell进程
修改startup.sh,在dotnet test命令前加exec,让dotnet进程直接替换当前shell成为PID 1,和直接ENTRYPOINT的运行环境完全一致:
#!/bin/sh sleep 10 echo "Slept 10 seconds - executing command" exec dotnet test --verbosity "normal" --logger "trx;LogFileName=integration_tests.trx" --results-directory "/results/integration"
90%以上的同类问题都可以通过这个修改解决。
2. 禁用交互模式与输出缓冲
如果修改后仍有问题,可添加参数强制禁用dotnet的交互逻辑、关闭输出缓冲,避免输出被缓冲导致误判为卡住:
#!/bin/sh sleep 10 # 禁用输出缓冲 export DOTNET_SYSTEM_CONSOLE_DISABLE_OUTPUT_REDIRECTION=1 echo "Slept 10 seconds - executing command" # 加--non-interactive参数强制非交互模式 exec dotnet test --non-interactive --verbosity "normal" --logger "trx;LogFileName=integration_tests.trx" --results-directory "/results/integration"
3. 高阶排查方案
如果以上修改仍未解决,可在测试卡住时执行以下命令定位具体卡住的位置:
- 查看容器内进程状态,获取dotnet进程ID:
docker exec integrationtest ps aux - 追踪dotnet进程的系统调用,看卡在哪个操作上:
docker exec integrationtest strace -p <替换为上一步获取的dotnet进程ID>
可选优化点
你当前的depends_on配置仅保证依赖容器启动,不保证服务就绪,可将sleep逻辑替换为服务可用性检测,避免固定休眠时间不足或者过长的问题:
#!/bin/sh # 等待RabbitMQ端口就绪 while ! nc -z rabbitmq 5672; do echo "等待RabbitMQ启动..." sleep 1 done # 等待RavenDB端口就绪 while ! nc -z test.viewdb 8080; do echo "等待RavenDB启动..." sleep 1 done echo "所有依赖服务就绪,开始执行测试" exec dotnet test --non-interactive --verbosity "normal" --logger "trx;LogFileName=integration_tests.trx" --results-directory "/results/integration"
内容的提问来源于stack exchange,提问作者Help123
相关产品推荐
相关产品推荐

