【问题标题】:Remove docker container at the end of each test在每次测试结束时删除 docker 容器
【发布时间】:2016-11-10 17:32:19
【问题描述】:

我正在使用 docker 根据 Jenkins 中收到的请求数量来扩展测试基础架构/浏览器。

创建了一个 python 脚本来识别规范文件的总数和浏览器类型,并启动了许多 docker 容器。 Python 代码具有确定当前使用的节点数、过时节点数以及确定所需容器数的逻辑。

我想在每个规范文件末尾以编程方式删除容器/取消注册 selenium 节点(Docker --rm 标志对我没有帮助)。这样下一次测试将获得一个干净的浏览器和环境。

selenium 网格在 Jenkins 所在的同一个盒子上运行。一旦我调用量角器 protractor.conf.js(第 3 步),selenium 网格将开始将测试分发到第 1 步中创建的容器。

当我说“--rm”没有帮助时,我的意思是在第 3 步之后,通信主要是在 selenium 集线器和节点之间。我发现很难确定 selenium 网格使用哪个节点/容器来执行测试并在网格向容器发送另一个测试之前删除容器。

-- Jenkins 构建阶段-- 壳牌:

   # Step 1
   python ./create_test_machine.py ${no_of_containers} # This will spin-up selenium nodes

   # Step 2
   npm install  # install node modules

   # Step 3
   protractor protractor.conf.js # Run the protractor tests

--启动容器的 Python 代码 - create_test_machine.py--

Python 脚本:

import sys
import docker
import docker.utils
import requests
import json
import time

c = docker.Client(base_url='unix://var/run/docker.sock', version='1.23')
my_envs = {'HUB_PORT_4444_TCP_ADDR' :'172.17.0.1', 'HUB_PORT_4444_TCP_PORT' : 4444}

def check_available_machines(no_of_machines):   
    t = c.containers()
    noof_running_containers = len(t)
    if noof_running_containers == 0:
        print("0 containers running. Creating " + str(no_of_machines) + "new containers...")
        spinup_test_machines(no_of_machines)
    else:       
        out_of_stock = 0
        for obj_container in t:
            print(obj_container)
            container_ip_addr = obj_container['NetworkSettings']['Networks']['bridge']['IPAddress']
            container_state = obj_container['State']        
            res = requests.get('http://' + container_ip_addr + ':5555/wd/hub/sessions')         
            obj = json.loads(res.content)           
            node_inuse = len(obj['value'])
            if node_inuse != 0: 
                noof_running_containers -= 1
        if noof_running_containers < no_of_machines:
            spinup_test_machines(no_of_machines - noof_running_containers)
    return      

def spinup_test_machines(no_of_machines):
    '''
        Parameter : Number of test nodes to spin up 
    '''
    print("Creating " + str(no_of_machines) + " new containers...")
    # my_envs = docker.utils.parse_env_file('docker.env')

    for i in range(0,no_of_machines):
        new_container = c.create_container(image='selenium/node-chrome', environment=my_envs)
        response = c.start(container=new_container.get('Id'))
        print(new_container, response)
    return

if len(sys.argv) - 1 == 1:
    no_of_machines = int(sys.argv[1]) + 2   
    check_available_machines(no_of_machines)
    time.sleep(30)
else:
    print("Invalid number of parameters")

【问题讨论】:

  • 你能详细说明--rm对你没有帮助吗?
  • 错误是什么?你用分离模式启动你的容器?
  • 为我的问题添加了更多信息。是的,容器以分离模式启动
  • 我认为--rm-d不能同时使用。能否请您显示您用于启动的命令和您最近遇到的错误?
  • @Rao,你是对的。我尝试使用 --rm 标志,但它没有用。上面的python代码只在分离模式下创建容器。

标签: docker protractor selenium-chromedriver selenium-grid


【解决方案1】:

docker run-d--rm 的区别可以看得很清楚

使用-doption

C:\Users\apps>docker run -d --name testso alpine /bin/echo 'Hello World'
5d447b558ae6bf58ff6a2147da8bdf25b526bd1c9f39117498fa017f8f71978b

查看日志

C:\Users\apps>docker logs testso
'Hello World'

检查上次运行的容器

C:\Users\apps>docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
5d447b558ae6        alpine              "/bin/echo 'Hello Wor"   35 hours ago        Exited (0) 11 seconds ago                       testso

最后用户必须明确删除它

C:\Users\apps>docker rm -f testso
testso

使用--rm,容器会在进程消失后立即消失,包括其日志 容器内运行完成。再也没有容器的踪迹。

C:\Users\apps>docker run --rm --name testso alpine /bin/echo 'Hello World'
'Hello World'

C:\Users\apps>docker logs testso
Error: No such container: testso

C:\Users\apps>docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

我相信很清楚,如何运行容器并且在容器内部完成处理后不留下任何痕迹。

【讨论】:

    【解决方案2】:

    所以要以分离模式启动容器,请使用 -d=true 或仅使用 -d 选项。按照设计,当用于运行容器的根进程退出时,以分离模式启动的容器退出。处于分离模式的容器在停止时无法自动删除,这意味着您不能将 --rm 选项与 -d 选项一起使用。

    看看这个

    https://docs.docker.com/engine/reference/run/

    【讨论】:

      【解决方案3】:

      您可以使用鼻子测试。对于每个 "def test_xxx()",它将使用 @with_setup decrator 调用 setup 和 teardown 函数。下面是一个例子:

      from nose.tools import *
      
      c = docker.Client(base_url='unix://var/run/docker.sock', version='1.23')
      my_envs = {'HUB_PORT_4444_TCP_ADDR' :'172.17.0.1', 'HUB_PORT_4444_TCP_PORT' : 4444}
      
      my_containers = {}
      
      def setup_docker():
          """ Setup Test Environment, 
              create/start your docker container(s), populate the my_containers dict.
          """
      
      def tear_down_docker():
          """Tear down test environment.
          """
          for container in my_containers.itervalues():
              try:
                  c.stop(container=container.get('Id'))
                  c.remove_container(container=container.get('Id'))
              except Exception as e:
                  print e
      
      @with_setup(setup=setup_docker, teardown=tear_down_docker)
      def test_xxx():
          # do your test here
          # you can call a subprocess to run your selenium
      

      或者,您编写一个单独的 python 脚本来检测您为测试设置的容器,然后执行以下操作:

      for container in my_containers.itervalues():
              try:
                  c.stop(container=container.get('Id'))
                  c.remove_container(container=container.get('Id'))
              except Exception as e:
                  print e
      

      【讨论】:

        猜你喜欢
        • 2021-11-04
        • 2021-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-11
        • 2020-04-22
        • 2021-04-29
        • 1970-01-01
        相关资源
        最近更新 更多