【发布时间】:2021-06-02 14:24:28
【问题描述】:
当我以交互模式在本地运行 Docker 映像然后手动进行测试时,它可以工作。但是当我推送到 GitHub 时,Jenkins 会拉取并运行测试,然后在尝试启动 Firefox 浏览器时超时。
我尝试了不同的 Docker 基础镜像。我尝试将 executable_path 提供给本地文件,也没有(在添加系统路径时)。
我是 Docker 和 Jenkins 的新手,我不确定自己做错了什么。 提前感谢您的帮助。
码头文件:
FROM ubuntu:bionic
COPY BS_PM2021_TEAM_27/requirements.txt requirements.txt
RUN apt-get update
RUN su -
RUN apt-get install sudo -y
RUN sudo apt-get install -y xvfb
RUN sudo apt-get install -y firefox
RUN sudo apt-get install -y wget
RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz
RUN tar -xvzf geckodriver*
RUN chmod +x geckodriver
RUN sudo mv geckodriver /usr/local/bin/
RUN export GECKODRIVER=$PATH:/user/local/bin/geckodriver
RUN sudo apt-get install -y python3.8
RUN sudo apt-get install -y python3-pip
RUN pip3 install -r requirements.txt
RUN Xvfb &
RUN export DISPLAY=localhost:0.0
WORKDIR .
COPY . .
requirements.txt:
asgiref==3.3.4
Django==3.2.3
EasyProcess==0.3
filter-profanity==1.0.9
pytz==2021.1
PyVirtualDisplay==2.2
selenium==3.141.0
sqlparse==0.4.1
urllib3==1.26.5
Jenkins 文件:
pipeline {
environment {
OUTPUT1 = "foo"
OUTPUT2 = 'bar'
}
agent {
dockerfile true
}
triggers {
githubPush()
}
stages {
stage('Build') {
steps {
sh """
cd BS_PM2021_TEAM_27
chmod 555 geckodriver-linux64
python3 manage.py makemigrations
python3 manage.py migrate
"""
}
}
stage('Run Unit Tests') {
steps {
dir("BS_PM2021_TEAM_27"){
script{
try{
sh(returnStdout: true, script: "python3 manage.py test Preschool_Play.tests_integration.TestIntegrationWithSelenium.test_login_then_add_and_delete_new_child 2>&1 | xargs echo > out1.txt")
}finally{
OUTPUT1 = sh(returnStdout: true, script: "cat out1.txt")
OUTPUT2 = sh(returnStdout: true, script: "tail -4 geckodriver.log")
}
}
}
}
}
}
post{
always{
echo 'Sending test report email...'
dir("BS_PM2021_TEAM_27"){
sh """
python3 manage.py email_report -s "Tests Report" -b "${OUTPUT1}"
python3 manage.py email_report -s "Log" -b '${OUTPUT2}'
"""
}
echo 'Email sent.'
}
}
}
测试文件:
import time
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test.utils import override_settings
from selenium import webdriver
from selenium.webdriver import FirefoxOptions
from .models import *
import os
from pyvirtualdisplay import Display
class TestIntegrationWithSelenium(StaticLiveServerTestCase):
def setUp(self):
if os.name != 'nt':
opts = FirefoxOptions()
opts.add_argument("--headless")
opts.add_argument('--disable-gpu')
self.display = Display(visible=False, size=(800, 600))
self.display.start()
self.browser = webdriver.Firefox(executable_path='./geckodriver-linux64', options=opts)
else:
self.browser = webdriver.Firefox(executable_path='./win-geckodriver.exe')
...
def tearDown(self):
self.browser.close()
self.display.stop()
@override_settings(DEBUG=True)
def test_login_then_add_and_delete_new_child(self):
...
Jenkins 构建控制台输出:
Started by user eilonco
Obtained BS_PM2021_TEAM_27/Jenkinsfile from git https://github.com/RotemLibrati/BS_PM2021_TEAM_27
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/Team_27/Team27Pipe
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
No credentials specified
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url https://github.com/RotemLibrati/BS_PM2021_TEAM_27 # timeout=10
Fetching upstream changes from https://github.com/RotemLibrati/BS_PM2021_TEAM_27
> git --version # timeout=10
> git fetch --tags --progress -- https://github.com/RotemLibrati/BS_PM2021_TEAM_27 +refs/heads/*:refs/remotes/origin/* # timeout=10
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision bbd3426db88b2b6c0f463462d047c5dd5dac5053 (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f bbd3426db88b2b6c0f463462d047c5dd5dac5053 # timeout=10
Commit message: "ubuntu2"
> git rev-list --no-walk bbd3426db88b2b6c0f463462d047c5dd5dac5053 # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Agent Setup)
[Pipeline] isUnix
[Pipeline] readFile
[Pipeline] sh
+ docker build -t 13639d9ab6390428bae282a0c7bbd0a0cdd1b696 -f Dockerfile .
Sending build context to Docker daemon 97.69MB
Step 1/20 : FROM ubuntu:bionic
---> 81bcf752ac3d
Step 2/20 : COPY BS_PM2021_TEAM_27/requirements.txt requirements.txt
---> Using cache
---> b848b4fa92dc
Step 3/20 : RUN apt-get update
---> Using cache
---> bae0ca787abd
Step 4/20 : RUN su -
---> Using cache
---> f301a6b617a1
Step 5/20 : RUN apt-get install sudo -y
---> Using cache
---> 3e273f710455
Step 6/20 : RUN sudo apt-get install -y xvfb
---> Using cache
---> 9d9a38840300
Step 7/20 : RUN sudo apt-get install -y firefox
---> Using cache
---> 434e2720c7a4
Step 8/20 : RUN sudo apt-get install -y wget
---> Using cache
---> 81e448f0eda5
Step 9/20 : RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz
---> Using cache
---> 02e07299c327
Step 10/20 : RUN tar -xvzf geckodriver*
---> Using cache
---> 0371bbbf3016
Step 11/20 : RUN chmod +x geckodriver
---> Using cache
---> d23fe7800069
Step 12/20 : RUN sudo mv geckodriver /usr/local/bin/
---> Using cache
---> b63dd57bc1eb
Step 13/20 : RUN export GECKODRIVER=$PATH:/user/local/bin/geckodriver
---> Using cache
---> ee6e81e81a6a
Step 14/20 : RUN sudo apt-get install -y python3.8
---> Using cache
---> 9b61093b0eb9
Step 15/20 : RUN sudo apt-get install -y python3-pip
---> Using cache
---> 7a647ad74b43
Step 16/20 : RUN pip3 install -r requirements.txt
---> Using cache
---> 0d17d8da547e
Step 17/20 : RUN Xvfb &
---> Using cache
---> 201fb5ca7b65
Step 18/20 : RUN export DISPLAY=localhost:0.0
---> Using cache
---> c0fab92bf6d6
Step 19/20 : WORKDIR .
---> Using cache
---> 7738a4afa668
Step 20/20 : COPY . .
---> 7fea506200d5
Successfully built 7fea506200d5
Successfully tagged 13639d9ab6390428bae282a0c7bbd0a0cdd1b696:latest
[Pipeline] }
[Pipeline] // stage
[Pipeline] isUnix
[Pipeline] sh
+ docker inspect -f . 13639d9ab6390428bae282a0c7bbd0a0cdd1b696
.
[Pipeline] withDockerContainer
Jenkins seems to be running inside container 1b8310761f551fe6f780ed06f030c1bfa7f8f94aaec42df21ceb958a5f8a9417
$ docker run -t -d -u 1000:1000 -w /var/jenkins_home/workspace/Team_27/Team27Pipe --volumes-from 1b8310761f551fe6f780ed06f030c1bfa7f8f94aaec42df21ceb958a5f8a9417 -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** 13639d9ab6390428bae282a0c7bbd0a0cdd1b696 cat
$ docker top 00492076b546b5a216713f20e47a2399bd87b3186226bbc8cb53abdba42c6f4f -eo pid,comm
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] sh
+ cd BS_PM2021_TEAM_27
+ chmod 555 geckodriver-linux64
+ python3 manage.py makemigrations
No changes detected
+ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
No migrations to apply.
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Run Unit Tests)
[Pipeline] dir
Running in /var/jenkins_home/workspace/Team_27/Team27Pipe/BS_PM2021_TEAM_27
[Pipeline] {
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ python3 manage.py test Preschool_Play.tests_integration.TestIntegrationWithSelenium.test_login_then_add_and_delete_new_child
+ xargs echo
[Pipeline] sh
+ cat out1.txt
[Pipeline] sh
+ tail -4 geckodriver.log
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // dir
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] echo
Sending test report email...
[Pipeline] dir
Running in /var/jenkins_home/workspace/Team_27/Team27Pipe/BS_PM2021_TEAM_27
[Pipeline] {
[Pipeline] sh
+ python3 manage.py email_report -s Tests Report -b Creating test database for alias default... System check identified no issues (0 silenced). E ====================================================================== ERROR: test_login_then_add_and_delete_new_child (Preschool_Play.tests_integration.TestIntegrationWithSelenium) ---------------------------------------------------------------------- Traceback (most recent call last): File /var/jenkins_home/workspace/Team_27/Team27Pipe/BS_PM2021_TEAM_27/Preschool_Play/tests_integration.py, line 20, in setUp self.browser = webdriver.Firefox(executable_path=./geckodriver-linux64, options=opts) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/firefox/webdriver.py, line 174, in __init__ keep_alive=True) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py, line 157, in __init__ self.start_session(capabilities, browser_profile) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py, line 252, in start_session response = self.execute(Command.NEW_SESSION, parameters) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py, line 321, in execute self.error_handler.check_response(response) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/errorhandler.py, line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: Connection refused (os error 111) ---------------------------------------------------------------------- Ran 1 test in 61.588s FAILED (errors=1) Destroying test database for alias default...
+ python3 manage.py email_report -s Log -b [GFX1-]: glxtest: libpci missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer, no dt
[Pipeline] }
[Pipeline] // dir
[Pipeline] echo
Email sent.
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
$ docker stop --time=1 00492076b546b5a216713f20e47a2399bd87b3186226bbc8cb53abdba42c6f4f
$ docker rm -f 00492076b546b5a216713f20e47a2399bd87b3186226bbc8cb53abdba42c6f4f
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Django 控制台输出:
Creating test database for alias default...
System check identified no issues (0 silenced).
E ======================================================================
ERROR: test_login_then_add_and_delete_new_child (Preschool_Play.tests_integration.TestIntegrationWithSelenium)
----------------------------------------------------------------------
Traceback (most recent call last): File /var/jenkins_home/workspace/Team_27/Team27Pipe/BS_PM2021_TEAM_27/Preschool_Play/tests_integration.py,
line 20, in setUp self.browser = webdriver.Firefox(executable_path=./geckodriver-linux64, options=opts)
File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/firefox/webdriver.py,
line 174, in __init__ keep_alive=True) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py,
line 157, in __init__ self.start_session(capabilities, browser_profile) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py,
line 252, in start_session response = self.execute(Command.NEW_SESSION, parameters) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py,
line 321, in execute self.error_handler.check_response(response) File /usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/errorhandler.py,
line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message: Connection refused (os error 111)
----------------------------------------------------------------------
Ran 1 test in 61.588s FAILED (errors=1)
Destroying test database for alias default...
geckodriver.log:
[GFX1-]: glxtest: libpci missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: RenderCompositorSWGL failed mapping default framebuffer, no dt
当我在本地容器上运行时,测试通过并且 geckodriver.log 是:
# cat geckodriver.log
1622651926935 mozrunner::runner INFO Running command: "/usr/bin/firefox" "-marionette" "--headless" "--disable-gpu" "-foreground" "-no-remote" "-profile" "/tmp/rust_mozprofile.jh7CncJfRv6O"
*** You are running in headless mode.
[GFX1-]: glxtest: libpci missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: glxtest: Unable to open a connection to the X server
[GFX1-]: glxtest: libEGL missing
[GFX1-]: No GPUs detected via PCI
1622651927369 Marionette INFO Marionette enabled
(/usr/lib/firefox/firefox:81): GLib-GObject-CRITICAL **: 16:38:47.908: g_object_set: assertion 'G_IS_OBJECT (object)' failed
(/usr/lib/firefox/firefox:101): GLib-GObject-CRITICAL **: 16:38:47.998: g_object_set: assertion 'G_IS_OBJECT (object)' failed
console.warn: SearchSettings: "get: No settings file exists, new profile?" (new Error("", "(unknown module)"))
1622651929513 Marionette INFO Listening on port 45265
(/usr/lib/firefox/firefox:163): GLib-GObject-CRITICAL **: 16:38:49.575: g_object_set: assertion 'G_IS_OBJECT (object)' failed
1622651929580 Marionette WARN TLS certificate errors will be ignored for this session
1622651936233 Marionette INFO Stopped listening on port 45265
这里我在Ubuntu服务器上运行也成功了:
ubuntu@primary:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
ubuntu@primary:~$ docker container start -a -i eager_cartwright
root@68abe3dfecd3:/# cd BS_PM2021_TEAM_27/
root@68abe3dfecd3:/BS_PM2021_TEAM_27# rm geckodriver.log
root@68abe3dfecd3:/BS_PM2021_TEAM_27# python3 manage.py test Preschool_Play.tests_integration.TestIntegrationWithSelenium.test_login_then_add_and_delete_new_child
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
Not Found: /favicon.ico
Not Found: /favicon.ico
[<Child: Name: kid2. Parent: parent>]
.
----------------------------------------------------------------------
Ran 1 test in 14.417s
OK
Destroying test database for alias 'default'...
root@68abe3dfecd3:/BS_PM2021_TEAM_27#
root@68abe3dfecd3:/BS_PM2021_TEAM_27# cat geckodriver.log
1622660833134 geckodriver INFO Listening on 127.0.0.1:32959
1622660834143 mozrunner::runner INFO Running command: "/usr/bin/firefox" "--marionette" "--headless" "--disable-gpu" "-foreground" "-no-remote" "-profile" "/tmp/rust_mozprofilePskEQC"
*** You are running in headless mode.
[GFX1-]: glxtest: libpci missing
[GFX1-]: glxtest: libEGL missing
[GFX1-]: glxtest: Unable to open a connection to the X server
[GFX1-]: glxtest: libEGL missing
[GFX1-]: No GPUs detected via PCI
1622660834624 Marionette INFO Marionette enabled
(/usr/lib/firefox/firefox:73): GLib-GObject-CRITICAL **: 19:07:15.322: g_object_set: assertion 'G_IS_OBJECT (object)' failed
(/usr/lib/firefox/firefox:88): GLib-GObject-CRITICAL **: 19:07:15.523: g_object_set: assertion 'G_IS_OBJECT (object)' failed
console.warn: SearchSettings: "get: No settings file exists, new profile?" (new Error("", "(unknown module)"))
1622660838023 Marionette INFO Listening on port 45137
1622660838185 Marionette WARN TLS certificate errors will be ignored for this session
(/usr/lib/firefox/firefox:151): GLib-GObject-CRITICAL **: 19:07:18.187: g_object_set: assertion 'G_IS_OBJECT (object)' failed
1622660846356 Marionette INFO Stopped listening on port 45137
更新:我怀疑我大学的服务器没有显示选项,也没有 GPU,这就是 Selenium 找不到任何 GPU 的原因。但是我不知道它仍然可以在没有 GUI 的 Ubuntu 服务器上运行的原因。也许是因为 Ubuntu 服务器仍然可以识别我的笔记本电脑 GPU。
【问题讨论】:
标签: python django docker jenkins selenium-webdriver