summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/fixtures/config/mqtt-driver/git/common-config/zuul.d/config.yaml4
-rw-r--r--tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml14
-rw-r--r--tests/remote/test_remote_zuul_stream.py48
-rw-r--r--tests/unit/test_connection.py14
-rw-r--r--tests/unit/test_inventory.py6
-rw-r--r--tests/unit/test_scheduler.py11
6 files changed, 91 insertions, 6 deletions
diff --git a/tests/fixtures/config/mqtt-driver/git/common-config/zuul.d/config.yaml b/tests/fixtures/config/mqtt-driver/git/common-config/zuul.d/config.yaml
index c842e9424..1cee46f5c 100644
--- a/tests/fixtures/config/mqtt-driver/git/common-config/zuul.d/config.yaml
+++ b/tests/fixtures/config/mqtt-driver/git/common-config/zuul.d/config.yaml
@@ -7,11 +7,15 @@
start:
mqtt:
topic: "{tenant}/zuul_start/{pipeline}/{project}/{branch}"
+ # This doesn't make sense here -- there should be no return
+ # data yet, which is why we include it in this test.
+ include-returned-data: True
success:
gerrit:
Verified: 1
mqtt:
topic: "{tenant}/zuul_buildset/{pipeline}/{project}/{branch}"
+ include-returned-data: True
failure:
gerrit:
Verified: -1
diff --git a/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml b/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml
index d737a1a9b..539db80b7 100644
--- a/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml
+++ b/tests/fixtures/config/remote-zuul-stream/git/org_project/playbooks/command.yaml
@@ -114,3 +114,17 @@
- name: Command Not Found
command: command-not-found
failed_when: false
+
+- hosts: compute1
+ tasks:
+
+ - name: Debug raw variable in msg
+ debug:
+ msg: '{{ ansible_version }}'
+
+ - name: Debug raw variable in a loop
+ debug:
+ msg: '{{ ansible_version }}'
+ loop:
+ - 1
+ - 2
diff --git a/tests/remote/test_remote_zuul_stream.py b/tests/remote/test_remote_zuul_stream.py
index bb2b54a21..b84c4b0d8 100644
--- a/tests/remote/test_remote_zuul_stream.py
+++ b/tests/remote/test_remote_zuul_stream.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import io
+import logging
import os
import re
import textwrap
@@ -31,6 +33,12 @@ class FunctionalZuulStreamMixIn:
self.executor_server.log_console_port = self.log_console_port
self.wait_timeout = 180
self.fake_nodepool.remote_ansible = True
+ # This catches the Ansible output; rather than the callback
+ # output captured in the job log. For example if the callback
+ # fails, there will be an error output in this stream.
+ self.logger = logging.getLogger('zuul.AnsibleJob')
+ self.console_output = io.StringIO()
+ self.logger.addHandler(logging.StreamHandler(self.console_output))
ansible_remote = os.environ.get('ZUUL_REMOTE_IPV4')
self.assertIsNotNone(ansible_remote)
@@ -92,14 +100,20 @@ class FunctionalZuulStreamMixIn:
with open(path) as f:
return f.read()
- def assertLogLine(self, line, log):
- pattern = (r'^\d\d\d\d-\d\d-\d\d \d\d:\d\d\:\d\d\.\d\d\d\d\d\d \| %s$'
- % line)
+ def _assertLogLine(self, line, log, full_match=True):
+ pattern = (r'^\d\d\d\d-\d\d-\d\d \d\d:\d\d\:\d\d\.\d\d\d\d\d\d \| %s%s'
+ % (line, '$' if full_match else ''))
log_re = re.compile(pattern, re.MULTILINE)
m = log_re.search(log)
if m is None:
raise Exception("'%s' not found in log" % (line,))
+ def assertLogLineStartsWith(self, line, log):
+ self._assertLogLine(line, log, full_match=False)
+
+ def assertLogLine(self, line, log):
+ self._assertLogLine(line, log, full_match=True)
+
def _getLogTime(self, line, log):
pattern = (r'^(\d\d\d\d-\d\d-\d\d \d\d:\d\d\:\d\d\.\d\d\d\d\d\d)'
r' \| %s\n'
@@ -120,7 +134,21 @@ class FunctionalZuulStreamMixIn:
build = self.history[-1]
self.assertEqual(build.result, 'SUCCESS')
+ console_output = self.console_output.getvalue()
+ # This should be generic enough to match any callback
+ # plugin failures, which look something like
+ #
+ # [WARNING]: Failure using method (v2_runner_on_ok) in \
+ # callback plugin
+ # (<ansible.plugins.callback.zuul_stream.CallbackModule object at'
+ # 0x7f89f72a20b0>): 'dict' object has no attribute 'startswith'"
+ # Callback Exception:
+ # ...
+ #
+ self.assertNotIn('[WARNING]: Failure using method', console_output)
+
text = self._get_job_output(build)
+
self.assertLogLine(
r'RUN START: \[untrusted : review.example.com/org/project/'
r'playbooks/command.yaml@master\]', text)
@@ -186,6 +214,20 @@ class FunctionalZuulStreamMixIn:
self.assertLess((time2 - time1) / timedelta(milliseconds=1),
9000)
+ # This is from the debug: msg='{{ ansible_version }}'
+ # testing raw variable output. To make it version
+ # agnostic, match just the start of
+ # compute1 | ok: {'string': '2.9.27'...
+
+ # NOTE(ianw) 2022-08-24 : I don't know why the callback
+ # for debug: msg= doesn't put the hostname first like
+ # other output. Undetermined if bug or feature.
+ self.assertLogLineStartsWith(
+ r"""\{'string': '\d.""", text)
+ # ... handling loops is a different path, and that does
+ self.assertLogLineStartsWith(
+ r"""compute1 \| ok: \{'string': '\d.""", text)
+
def test_module_exception(self):
job = self._run_job('module_failure_exception')
with self.jobLog(job):
diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py
index b4c155240..bae4ff258 100644
--- a/tests/unit/test_connection.py
+++ b/tests/unit/test_connection.py
@@ -681,9 +681,13 @@ class TestMQTTConnection(ZuulTestCase):
'type': 'container_image'
}}
self.executor_server.returnData(
- "test", A, {"zuul": {"log_url": "some-log-url",
- 'artifacts': [artifact],
- }}
+ "test", A, {
+ "zuul": {
+ "log_url": "some-log-url",
+ 'artifacts': [artifact],
+ },
+ 'foo': 'bar',
+ }
)
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
@@ -703,6 +707,9 @@ class TestMQTTConnection(ZuulTestCase):
'test')
self.assertNotIn('result', mqtt_payload['buildset']['builds'][0])
self.assertNotIn('artifacts', mqtt_payload['buildset']['builds'][0])
+ builds = mqtt_payload['buildset']['builds']
+ test_job = [b for b in builds if b['job_name'] == 'test'][0]
+ self.assertNotIn('returned_data', test_job)
self.assertEquals(success_event.get('topic'),
'tenant-one/zuul_buildset/check/org/project/master')
@@ -720,6 +727,7 @@ class TestMQTTConnection(ZuulTestCase):
self.assertEquals(test_job['dependencies'], [])
self.assertEquals(test_job['artifacts'], [artifact])
self.assertEquals(test_job['log_url'], 'some-log-url/')
+ self.assertEquals(test_job['returned_data'], {'foo': 'bar'})
build_id = test_job["uuid"]
self.assertEquals(
test_job["web_url"],
diff --git a/tests/unit/test_inventory.py b/tests/unit/test_inventory.py
index 1e96372ed..83a62a0e7 100644
--- a/tests/unit/test_inventory.py
+++ b/tests/unit/test_inventory.py
@@ -104,6 +104,7 @@ class TestInventoryGithub(TestInventoryBase):
z_vars = inventory['all']['vars']['zuul']
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
+ self.assertIn('ansible_version', z_vars)
self.assertIn('job', z_vars)
self.assertIn('event_id', z_vars)
self.assertEqual(z_vars['job'], 'single-inventory')
@@ -137,6 +138,7 @@ class TestInventoryPythonPath(TestInventoryBase):
z_vars = inventory['all']['vars']['zuul']
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
+ self.assertIn('ansible_version', z_vars)
self.assertIn('job', z_vars)
self.assertEqual(z_vars['job'], 'single-inventory')
self.assertEqual(z_vars['message'], 'QQ==')
@@ -167,6 +169,7 @@ class TestInventoryShellType(TestInventoryBase):
z_vars = inventory['all']['vars']['zuul']
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
+ self.assertIn('ansible_version', z_vars)
self.assertIn('job', z_vars)
self.assertEqual(z_vars['job'], 'single-inventory')
self.assertEqual(z_vars['message'], 'QQ==')
@@ -195,6 +198,7 @@ class TestInventoryAutoPython(TestInventoryBase):
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
self.assertIn('job', z_vars)
+ self.assertEqual(z_vars['ansible_version'], '2.8')
self.assertEqual(z_vars['job'], 'ansible-version28-inventory')
self.assertEqual(z_vars['message'], 'QQ==')
@@ -219,6 +223,7 @@ class TestInventoryAutoPython(TestInventoryBase):
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
self.assertIn('job', z_vars)
+ self.assertEqual(z_vars['ansible_version'], '2.9')
self.assertEqual(z_vars['job'], 'ansible-version29-inventory')
self.assertEqual(z_vars['message'], 'QQ==')
@@ -243,6 +248,7 @@ class TestInventoryAutoPython(TestInventoryBase):
self.assertIn('executor', z_vars)
self.assertIn('src_root', z_vars['executor'])
self.assertIn('job', z_vars)
+ self.assertEqual(z_vars['ansible_version'], '5')
self.assertEqual(z_vars['job'], 'ansible-version5-inventory')
self.assertEqual(z_vars['message'], 'QQ==')
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index 978bc00a4..3445e9dc6 100644
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -5372,6 +5372,17 @@ For CI problems and help debugging, contact ci@example.org"""
'database'].getBuildsets())
if buildsets:
break
+ # Stop queuing timer triggered jobs so that the assertions
+ # below don't race against more jobs being queued.
+ self.commitConfigUpdate('org/common-config', 'layouts/no-timer.yaml')
+ self.scheds.execute(lambda app: app.sched.reconfigure(app.config))
+ self.waitUntilSettled()
+ # If APScheduler is in mid-event when we remove the job, we
+ # can end up with one more event firing, so give it an extra
+ # second to settle.
+ time.sleep(3)
+ self.waitUntilSettled()
+
self.assertEqual(buildsets[0].result, 'CONFIG_ERROR')
self.assertIn('Job project-test2 depends on project-test1 '
'which was not run', buildsets[0].message)