mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Regression tests for playbooks, logging the events they call via callbacks.
This commit is contained in:
parent
b15c8e9cb1
commit
5371a9e497
6 changed files with 259 additions and 13 deletions
|
@ -49,7 +49,7 @@ class PlaybookCallbacks(object):
|
||||||
def on_failed(self, host, results):
|
def on_failed(self, host, results):
|
||||||
print "failed: [%s] => %s\n" % (host, utils.smjson(results))
|
print "failed: [%s] => %s\n" % (host, utils.smjson(results))
|
||||||
|
|
||||||
def on_ok(self, host):
|
def on_ok(self, host, host_result):
|
||||||
print "ok: [%s]\n" % (host)
|
print "ok: [%s]\n" % (host)
|
||||||
|
|
||||||
def on_play_start(self, pattern):
|
def on_play_start(self, pattern):
|
||||||
|
|
|
@ -83,7 +83,6 @@ class PlayBook(object):
|
||||||
# playbook file can be passed in as a path or
|
# playbook file can be passed in as a path or
|
||||||
# as file contents (to support API usage)
|
# as file contents (to support API usage)
|
||||||
|
|
||||||
print "DEBUG: playbook=%s" % playbook
|
|
||||||
self.basedir = os.path.dirname(playbook)
|
self.basedir = os.path.dirname(playbook)
|
||||||
self.playbook = self._parse_playbook(playbook)
|
self.playbook = self._parse_playbook(playbook)
|
||||||
|
|
||||||
|
@ -384,7 +383,7 @@ class PlayBook(object):
|
||||||
else:
|
else:
|
||||||
self.failures[host] = self.failures[host] + 1
|
self.failures[host] = self.failures[host] + 1
|
||||||
else:
|
else:
|
||||||
self.callbacks.on_ok(host)
|
self.callbacks.on_ok(host, results)
|
||||||
if not host in self.invocations:
|
if not host in self.invocations:
|
||||||
self.invocations[host] = 1
|
self.invocations[host] = 1
|
||||||
else:
|
else:
|
||||||
|
@ -418,7 +417,9 @@ class PlayBook(object):
|
||||||
# for this particular pattern group
|
# for this particular pattern group
|
||||||
|
|
||||||
for x in handlers:
|
for x in handlers:
|
||||||
name = x['name']
|
name = x.get('name', None)
|
||||||
|
if name is None:
|
||||||
|
raise errors.AnsibleError('handler is missing a name')
|
||||||
if match_name == name:
|
if match_name == name:
|
||||||
# flag the handler with the list of hosts
|
# flag the handler with the list of hosts
|
||||||
# it needs to be run on, it will be run later
|
# it needs to be run on, it will be run later
|
||||||
|
|
|
@ -385,6 +385,12 @@ class Runner(object):
|
||||||
and then run the async module wrapping the other module
|
and then run the async module wrapping the other module
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# hack to make the 'shell' module keyword really be executed
|
||||||
|
# by the command module
|
||||||
|
if self.module_name == 'shell':
|
||||||
|
self.module_name = 'command'
|
||||||
|
self.module_args.append("#USE_SHELL")
|
||||||
|
|
||||||
async = self._transfer_module(conn, tmp, 'async_wrapper')
|
async = self._transfer_module(conn, tmp, 'async_wrapper')
|
||||||
module = self._transfer_module(conn, tmp, self.module_name)
|
module = self._transfer_module(conn, tmp, self.module_name)
|
||||||
result = self._execute_module(conn, tmp, async, self.module_args,
|
result = self._execute_module(conn, tmp, async, self.module_args,
|
||||||
|
|
|
@ -35,9 +35,12 @@ class TestCallbacks(object):
|
||||||
def on_failed(self, host, results):
|
def on_failed(self, host, results):
|
||||||
self.events.append([ 'failed', [ host, results ]])
|
self.events.append([ 'failed', [ host, results ]])
|
||||||
|
|
||||||
# FIXME: this callback should get results too!
|
def on_ok(self, host, host_result):
|
||||||
def on_ok(self, host):
|
# delete certain info from host_result to make test comparisons easier
|
||||||
self.events.append([ 'ok', [ host ]])
|
for k in [ 'ansible_job_id', 'md5sum', 'delta', 'start', 'end' ]:
|
||||||
|
if k in host_result:
|
||||||
|
del host_result[k]
|
||||||
|
self.events.append([ 'ok', [ host, host_result ]])
|
||||||
|
|
||||||
def on_play_start(self, pattern):
|
def on_play_start(self, pattern):
|
||||||
self.events.append([ 'play start', [ pattern ]])
|
self.events.append([ 'play start', [ pattern ]])
|
||||||
|
@ -46,13 +49,11 @@ class TestCallbacks(object):
|
||||||
self.events.append([ 'async confused', [ msg ]])
|
self.events.append([ 'async confused', [ msg ]])
|
||||||
|
|
||||||
def on_async_poll(self, jid, host, clock, host_result):
|
def on_async_poll(self, jid, host, clock, host_result):
|
||||||
self.events.append([ 'async poll', [ host, jid ]])
|
self.events.append([ 'async poll', [ host ]])
|
||||||
|
|
||||||
def on_dark_host(self, host, msg):
|
def on_dark_host(self, host, msg):
|
||||||
self.events.append([ 'failed/dark', [ host, msg ]])
|
self.events.append([ 'failed/dark', [ host, msg ]])
|
||||||
|
|
||||||
# FIXME: callbacks need to be fired on notifiers as well
|
|
||||||
|
|
||||||
|
|
||||||
class TestRunner(unittest.TestCase):
|
class TestRunner(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -62,6 +63,11 @@ class TestRunner(unittest.TestCase):
|
||||||
self.test_dir = os.path.join(self.cwd, 'test')
|
self.test_dir = os.path.join(self.cwd, 'test')
|
||||||
self.stage_dir = self._prepare_stage_dir()
|
self.stage_dir = self._prepare_stage_dir()
|
||||||
|
|
||||||
|
if os.path.exists('/tmp/ansible_test_data_copy.out'):
|
||||||
|
os.unlink('/tmp/ansible_test_data_copy.out')
|
||||||
|
if os.path.exists('/tmp/ansible_test_data_template.out'):
|
||||||
|
os.unlink('/tmp/ansible_test_data_template.out')
|
||||||
|
|
||||||
def _prepare_stage_dir(self):
|
def _prepare_stage_dir(self):
|
||||||
stage_path = os.path.join(self.test_dir, 'test_data')
|
stage_path = os.path.join(self.test_dir, 'test_data')
|
||||||
if os.path.exists(stage_path):
|
if os.path.exists(stage_path):
|
||||||
|
@ -104,5 +110,10 @@ class TestRunner(unittest.TestCase):
|
||||||
|
|
||||||
def test_one(self):
|
def test_one(self):
|
||||||
pb = os.path.join(self.test_dir, 'playbook1.yml')
|
pb = os.path.join(self.test_dir, 'playbook1.yml')
|
||||||
print utils.bigjson(self._run(pb))
|
expected = os.path.join(self.test_dir, 'playbook1.events')
|
||||||
assert False, "this test works, but we need to check the results values to complete it"
|
expected = utils.json_loads(file(expected).read())
|
||||||
|
actual = self._run(pb)
|
||||||
|
# if different, this will output to screen
|
||||||
|
print utils.bigjson(actual)
|
||||||
|
assert cmp(expected, actual) == 0, "expected events match actual events"
|
||||||
|
|
||||||
|
|
203
test/playbook1.events
Normal file
203
test/playbook1.events
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
{
|
||||||
|
"events": [
|
||||||
|
"start",
|
||||||
|
[
|
||||||
|
"play start",
|
||||||
|
[
|
||||||
|
"all"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"test basic success command",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": [
|
||||||
|
"/bin/true"
|
||||||
|
],
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"test basic success command 2",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": [
|
||||||
|
"/bin/true"
|
||||||
|
],
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"test basic shell",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": "echo $HOME ",
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": "/root"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"test copy",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"group": "root",
|
||||||
|
"mode": 420,
|
||||||
|
"path": "/tmp/ansible_test_data_copy.out",
|
||||||
|
"state": "file",
|
||||||
|
"user": "root"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"test template",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"group": "root",
|
||||||
|
"mode": 420,
|
||||||
|
"path": "/tmp/ansible_test_data_template.out",
|
||||||
|
"state": "file",
|
||||||
|
"user": "root"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"async poll test",
|
||||||
|
false
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"async poll",
|
||||||
|
[
|
||||||
|
"127.0.0.1"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"async poll",
|
||||||
|
[
|
||||||
|
"127.0.0.1"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"async poll",
|
||||||
|
[
|
||||||
|
"127.0.0.1"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": "sleep 5 ",
|
||||||
|
"finished": 1,
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"on change 1",
|
||||||
|
true
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": [
|
||||||
|
"/bin/true"
|
||||||
|
],
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"task start",
|
||||||
|
[
|
||||||
|
"on change 2",
|
||||||
|
true
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ok",
|
||||||
|
[
|
||||||
|
"127.0.0.1",
|
||||||
|
{
|
||||||
|
"cmd": [
|
||||||
|
"/bin/true"
|
||||||
|
],
|
||||||
|
"rc": 0,
|
||||||
|
"stderr": "",
|
||||||
|
"stdout": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"results": {
|
||||||
|
"127.0.0.1": {
|
||||||
|
"changed": 2,
|
||||||
|
"dark": 0,
|
||||||
|
"failed": 0,
|
||||||
|
"resources": 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,19 +16,44 @@
|
||||||
- name: test basic shell
|
- name: test basic shell
|
||||||
action: shell echo $HOME
|
action: shell echo $HOME
|
||||||
|
|
||||||
|
# in the command below, the test file should contain a valid template
|
||||||
|
# and trigger the change handler
|
||||||
|
|
||||||
- name: test copy
|
- name: test copy
|
||||||
action: copy src=sample.j2 dest=/tmp/ansible_test_data_copy.out
|
action: copy src=sample.j2 dest=/tmp/ansible_test_data_copy.out
|
||||||
|
notify:
|
||||||
|
- on change 1
|
||||||
|
|
||||||
|
# this should trigger two change handlers, but the 2nd should
|
||||||
|
# not be triggered twice because it's already triggered
|
||||||
|
|
||||||
- name: test template
|
- name: test template
|
||||||
action: template src=sample.j2 dest=/tmp/ansible_test_data_template.out
|
action: template src=sample.j2 dest=/tmp/ansible_test_data_template.out
|
||||||
|
notify:
|
||||||
|
- on change 1
|
||||||
|
- on change 2
|
||||||
|
|
||||||
|
# there should be various poll events within the range
|
||||||
|
|
||||||
|
- name: async poll test
|
||||||
|
action: shell sleep 5
|
||||||
|
async: 10
|
||||||
|
poll: 3
|
||||||
|
|
||||||
handlers:
|
handlers:
|
||||||
|
|
||||||
|
# in the above test example, this should fire ONCE (at the end)
|
||||||
- name: on change 1
|
- name: on change 1
|
||||||
action: command /bin/true
|
action: command /bin/true
|
||||||
|
|
||||||
|
# in the above test example, this should fire ONCE (at the end)
|
||||||
|
|
||||||
- name: on change 2
|
- name: on change 2
|
||||||
action: command /bin/true
|
action: command /bin/true
|
||||||
- action: on change 3
|
|
||||||
|
# in the above test example, this should NOT FIRE
|
||||||
|
|
||||||
|
- name: on change 3
|
||||||
action: command /bin/true
|
action: command /bin/true
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue