我正在我的 GitHub 运行器中以 CI 方式运行功能测试。 为了正确执行我的测试,我正在构建一个 docker 映像并运行它(一个稍作修改的 mysql 容器)。因为我是从 Dockerfile 构建容器(不仅仅是从注册表中提取它),所以我不使用 GitHub
service
或 container
功能 (https://docs.github.com/en/actions/use-cases -and-examples/using-containerized-services/about-service-containers).
相反,我在 GH 工作流程中专门做了一些步骤来构建容器并像这样运行它
- name: build docker container
run: |
cd tests/functional/olbp/mocked_data/
docker build --no-cache -f my_service.Dockerfile -t my_service_test:latest .
- name: run container
run: docker run --name my_service -d -p 127.0.0.1:3306:3306 my_service_test --sql_mode="NO_ENGINE_SUBSTITUTION"
- name: wait for MySQL to start
run: |
until mysqladmin ping -h 127.0.0.1 --silent; do
echo 'Waiting for MySQL to start...'
sleep 1
done
最后我用 python 调用我的功能测试(pytest)
- name: run the functional tests
run: python -m pytest tests/functional -vv -s --log-cli-level=DEBUG
这工作正常,我的测试可以明显地与 mysql 容器交互。
然而,在这种情况下我很难与 Docker 进行交互。我想生成我的测试的 mysqldump 部分。所以我在测试中写了这个:
dck_exc_output = subprocess.run(
[
"docker",
"exec",
"my_service",
"mysqldump",
"--skip-triggers",
"--skip-extended-insert",
"--compact",
"--no-create-info",
"-uroot",
"-psupersecret",
"my_db",
"my_table",
">",
live_data_dump,
],
capture_output=True,
shell=True,
)
logging.debug(dck_exc_output)
从我的计算机执行时它工作正常,但每当我尝试在 GH Runner 中执行它时(这个 docker 命令甚至是简单的 docker 版本)。我最终得到这个输出:
DEBUG root:my_test.py:246 CompletedProcess(args=['docker', 'version'], returncode=0, stdout=b'', stderr=b'
Usage: docker [OPTIONS] COMMAND
...
')
我已经确认我在子进程和 GH 运行程序命令之间具有相同的用户、相同的权限和相同的环境变量。
我不明白为什么我会收到这个输出。 docker 可执行文件似乎已找到(因为我收到帮助页面,就好像我执行了错误的命令一样),但它不会像我在本地运行测试时那样执行。
您的 Python 代码中有错误。您尝试在
subprocess.run()
的参数中使用 shell i/o 重定向,但是 (a) 您没有设置 shell=True
并且 (b) 您传递的是参数列表而不是字符串。
如果您想使用 shell i/o 重定向(如
somecommand > somefile
),您只能将单个字符串作为参数传递给 subprocess.run
,并且必须设置 shell=True
:
subprocess.run(
f'docker exec my_service mysqldump --skip-triggers --skip-extended-insert --compact --no-create-info -uroot -psupersecret my_db my_table > {live_data_dump}',
shell=True
)
如果您不设置
shell=True
,那么您的命令不会由 shell 执行,并且像 >
这样的内容会按字面意思传递给正在执行的命令。