在每次测试结束时删除docker容器

时间:2016-11-10 17:32:20

标签: docker protractor selenium-chromedriver selenium-grid

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

创建一个python脚本来识别spec文件和浏览器类型的总数,然后启动那些许多docker容器。 Python代码具有确定当前正在使用多少节点的逻辑,陈旧并确定所需的容器数量。

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

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

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

- 詹金斯建造阶段 - 壳:

   # 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")

3 个答案:

答案 0 :(得分:1)

docker run -d--rm

时,可以清楚地看到差异

使用-d选项

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

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

答案 1 :(得分:1)

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

看看这个

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

答案 2 :(得分:1)

您可以使用鼻子测试。对于每个“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