2017-10-17 52 views
1

將TestInfra與Ansible後端一起使用以用於測試目的。除了在運行測試在testinfra中使用Ansible變量

test.py

import pytest 
def test_zabbix_agent_package(host): 
    package = host.package("zabbix-agent") 
    assert package.is_installed 
    package_version = host.ansible("debug", "msg={{ zabbix_agent_version }}")["msg"] 
    (...) 

其中zabbix_agent_version是group_vars的Ansible使用可變Ansible本身一切順利。它可以通過運行這個劇本

- hosts: all 
    become: true 
    tasks: 
    - name: debug 
    debug: msg={{ zabbix_agent_version }} 

命令執行測試

pytest --connection=ansible --ansible-inventory=inventory --hosts=$hosts -v test.py 

ansible.cfg獲得

[defaults] 
timeout = 10 
host_key_checking = False 
library=library/ 
retry_files_enabled = False 
roles_path=roles/ 
pipelining=true 
ConnectTimeout=60 
remote_user=deploy 
private_key_file=/opt/jenkins/.ssh/deploy 

輸出我得到的是

self = <ansible>, module_name = 'debug', module_args = 'msg={{ zabbix_agent_version }}', check = True, kwargs = {} 
result = {'failed': True, 'msg': "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'zabbix_agent_version' is undefined"} 

    def __call__(self, module_name, module_args=None, check=True, **kwargs): 
     if not self._host.backend.HAS_RUN_ANSIBLE: 
      raise RuntimeError((
       "Ansible module is only available with ansible " 
       "connection backend")) 
     result = self._host.backend.run_ansible(
      module_name, module_args, check=check, **kwargs) 
     if result.get("failed", False) is True: 
>   raise AnsibleException(result) 
E   AnsibleException: Unexpected error: {'failed': True, 
E   'msg': u"the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'zabbix_agent_version' is undefined"} 

/usr/lib/python2.7/site-packages/testinfra/modules/ansible.py:70: AnsibleException 

知道爲什麼Ansible在什麼時候看不到這個變量運行testinfra的Ansible模塊,同時它可以在單獨運行Ansible時看到它?

+0

Ansible版本2.2.1.0 Python版本2.7.5 Testinfra版本1.6.4 Pytest版本3.1.3 – FRC

+0

凡'zabbix_agent_version'定義,當你手動運行Ansible?這是來自遠程主機上的自定義事實,還是設置在本地變量文件中? – larsks

+0

zabbix_agent_version是在group_vars中定義的。當運行一個檢查這個事實的劇本(debug:msg = {{zabbix_agent_version}})時,它可以通過Ansible獲得。 – FRC

回答

1

如果zabbix_agent_version是使用group_vars設置的變量,那麼您似乎應該使用host.ansible.get_variables()訪問它,而不是運行debug任務。無論如何,兩者都應該工作。如果我有,在我的當前目錄:

test_myvar.py 
group_vars/ 
    all.yml 
group_vars/all.yml

而且我有:

myvar: value 

而在test_myvar.py我:

def test_myvar_using_get_variables(host): 
    all_variables = host.ansible.get_variables() 
    assert 'myvar' in all_variables 
    assert all_variables['myvar'] == 'myvalue' 


def test_myvar_using_debug_var(host): 
    result = host.ansible("debug", "var=myvar") 
    assert 'myvar' in result 
    assert result['myvar'] == 'myvalue' 


def test_myvar_using_debug_msg(host): 
    result = host.ansible("debug", "msg={{ myvar }}") 
    assert 'msg' in result 
    assert result['msg'] == 'myvalue' 

然後,所有測試都通過了:

$ py.test --connection=ansible --ansible-inventory=hosts -v 
test_myvar.py 
============================= test session starts ============================== 
platform linux2 -- Python 2.7.13, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 -- /home/lars/env/common/bin/python2 
cachedir: .cache 
rootdir: /home/lars/tmp/testinfra, inifile: 
plugins: testinfra-1.8.1.dev2 
collected 3 items                

test_myvar.py::test_myvar_using_get_variables[ansible://localhost] PASSED 
test_myvar.py::test_myvar_using_debug_var[ansible://localhost] PASSED 
test_myvar.py::test_myvar_using_debug_msg[ansible://localhost] PASSED 

=========================== 3 passed in 1.77 seconds =========================== 

您能否確認我們的文件佈局(尤其是您的group_vars目錄相對於您的測試的位置)與我在此處顯示的內容相匹配?

+0

是的,我的佈局與您演示的佈局相同。當進行進一步的測試時,奇怪的是,當我試圖獲得Ansible內置的一些事實時(比如ansible_ssh_host),testinfra可以毫無問題地發現它,但是當我嘗試一些由我的group_vars設置的東西時,它無法找到它雖然運行調試Ansible可以看到它。 – FRC

0

我追了幾天的答案。這是最後爲我工作的。基本上你使用testinfra的Ansible模塊來訪問Ansible的include_vars功能。

import pytest 

@pytest.fixture() 
def AnsibleVars(host): 
ansible_vars = host.ansible(
    "include_vars", "file=./group_vars/all/vars.yml") 
return ansible_vars["ansible_facts"] 

然後在我的測試中,我包括函數作爲參數:

def test_something(host, AnsibleVars): 

該溶液部分取自https://github.com/metacloud/molecule/issues/151

我有,我試圖包括一個有趣的問題變量從我的主要劇本和我收到錯誤「必須存儲爲字典/散列」,當包括playbook.yml文件。將變量分隔到group_vars/all/vars.yml文件中可以解決該錯誤。