Browse code

ISSUE 25470 - junit report failure on changes

This commit provides an environment option to change the behaviour so
that it's possible to declare any changes shoudl be considered a junit
failure.

This is useful when carrying out idempotent testing to ensure that
multiple runs are safe and any changes should be considered a test
failure.

In a CI test of an ansible role the practice would be to run the role
once without this to configure the test system, and tehn to run a second
time including this environment vairable so that the CI engine
processing the junit report recognise any changes to be a test fail.

James authored on 2017/06/15 20:15:38
Showing 2 changed files
... ...
@@ -115,6 +115,7 @@ Ansible Changes By Release
115 115
 * Update ipaddr Jinja filters to replace existing non RFC compliant ones. Added additional filters for easier use
116 116
   of handling IP addresses. (PR# 26566)
117 117
 * datetime filter updated to use default format of datetime.datetime (ISO8601)
118
+* The junit plugin now has an option to report a junit test failure on changes for idempotent testing.
118 119
 
119 120
 #### New Callbacks:
120 121
 - full_skip
... ...
@@ -58,6 +58,8 @@ class CallbackModule(CallbackBase):
58 58
                                      Default: ~/.ansible.log
59 59
         JUNIT_TASK_CLASS (optional): Configure the output to be one class per yaml file
60 60
                                      Default: False
61
+        JUNIT_FAIL_ON_CHANGE (optional): Consider any tasks reporting "changed" as a junit test failure
62
+                                     Default: False
61 63
 
62 64
     Requires:
63 65
         junit_xml
... ...
@@ -74,6 +76,7 @@ class CallbackModule(CallbackBase):
74 74
 
75 75
         self._output_dir = os.getenv('JUNIT_OUTPUT_DIR', os.path.expanduser('~/.ansible.log'))
76 76
         self._task_class = os.getenv('JUNIT_TASK_CLASS', 'False').lower()
77
+        self._fail_on_change = os.getenv('JUNIT_FAIL_ON_CHANGE', 'False').lower()
77 78
         self._playbook_path = None
78 79
         self._playbook_name = None
79 80
         self._play_name = None
... ...
@@ -129,6 +132,9 @@ class CallbackModule(CallbackBase):
129 129
 
130 130
         task_data = self._task_data[task_uuid]
131 131
 
132
+        if self._fail_on_change == 'true' and status == 'changed':
133
+            status = 'failed'
134
+
132 135
         if status == 'failed' and 'EXPECTED FAILURE' in task_data.name:
133 136
             status = 'ok'
134 137
 
... ...
@@ -224,7 +230,10 @@ class CallbackModule(CallbackBase):
224 224
             self._finish_task('failed', result)
225 225
 
226 226
     def v2_runner_on_ok(self, result):
227
-        self._finish_task('ok', result)
227
+        if result._result.get('changed', False):
228
+            self._finish_task('changed', result)
229
+        else:
230
+            self._finish_task('ok', result)
228 231
 
229 232
     def v2_runner_on_skipped(self, result):
230 233
         self._finish_task('skipped', result)