diff --git a/tests/fixtures/config/job-output/git/common-config/playbooks/job-output.yaml b/tests/fixtures/config/job-output/git/common-config/playbooks/job-output.yaml new file mode 100644 index 0000000000..332db87316 --- /dev/null +++ b/tests/fixtures/config/job-output/git/common-config/playbooks/job-output.yaml @@ -0,0 +1,3 @@ +- hosts: all + tasks: + - shell: echo "Standard output test {{ zuul.executor.src_root }}" diff --git a/tests/fixtures/config/job-output/git/common-config/zuul.yaml b/tests/fixtures/config/job-output/git/common-config/zuul.yaml new file mode 100644 index 0000000000..a83f0bc778 --- /dev/null +++ b/tests/fixtures/config/job-output/git/common-config/zuul.yaml @@ -0,0 +1,27 @@ +- pipeline: + name: check + manager: independent + post-review: true + trigger: + gerrit: + - event: patchset-created + success: + gerrit: + Verified: 1 + failure: + gerrit: + Verified: -1 + +- job: + name: base + parent: null + +- job: + parent: base + name: job-output + +- project: + name: org/project + check: + jobs: + - job-output diff --git a/tests/fixtures/config/job-output/git/org_project/README b/tests/fixtures/config/job-output/git/org_project/README new file mode 100644 index 0000000000..9daeafb986 --- /dev/null +++ b/tests/fixtures/config/job-output/git/org_project/README @@ -0,0 +1 @@ +test diff --git a/tests/fixtures/config/job-output/main.yaml b/tests/fixtures/config/job-output/main.yaml new file mode 100644 index 0000000000..208e274b13 --- /dev/null +++ b/tests/fixtures/config/job-output/main.yaml @@ -0,0 +1,8 @@ +- tenant: + name: tenant-one + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py index 98cffcc29a..60a09864db 100755 --- a/tests/unit/test_v3.py +++ b/tests/unit/test_v3.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +import json import os import textwrap @@ -1338,3 +1339,39 @@ class TestSecretLeaks(AnsibleZuulTestCase): # paths. self.executor_server.verbose = True self._test_secret_file_fail() + + +class TestJobOutput(AnsibleZuulTestCase): + tenant_config_file = 'config/job-output/main.yaml' + + def _get_file(self, build, path): + p = os.path.join(build.jobdir.root, path) + with open(p) as f: + return f.read() + + def test_job_output(self): + # Verify that command standard output appears in the job output + + # This currently only verifies we receive output from + # localhost. Notably, it does not verify we receive output + # via zuul_console streaming. + self.executor_server.keep_jobdir = True + A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') + self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) + self.waitUntilSettled() + self.assertHistory([ + dict(name='job-output', result='SUCCESS', changes='1,1'), + ], ordered=False) + + token = 'Standard output test %s' % (self.history[0].jobdir.src_root) + j = json.loads(self._get_file(self.history[0], + 'work/logs/job-output.json')) + self.assertEqual(token, + j[0]['plays'][0]['tasks'][0] + ['hosts']['localhost']['stdout']) + + print(self._get_file(self.history[0], + 'work/logs/job-output.txt')) + self.assertIn(token, + self._get_file(self.history[0], + 'work/logs/job-output.txt')) diff --git a/zuul/ansible/callback/zuul_stream.py b/zuul/ansible/callback/zuul_stream.py index 11da1e55de..1ffeb9cd19 100644 --- a/zuul/ansible/callback/zuul_stream.py +++ b/zuul/ansible/callback/zuul_stream.py @@ -256,8 +256,12 @@ class CallbackModule(default.CallbackModule): is_localhost = True else: task_hostvars = result._task._variable_manager._hostvars[task_host] + # Normally hosts in the inventory will have ansible_host + # or ansible_inventory host defined. The implied + # inventory record for 'localhost' will have neither, so + # default to that if none are supplied. if task_hostvars.get('ansible_host', task_hostvars.get( - 'ansible_inventory_host')) in localhost_names: + 'ansible_inventory_host', 'localhost')) in localhost_names: is_localhost = True if not is_localhost and is_task: