summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--changelogs/fragments/delay_type.yml2
-rw-r--r--lib/ansible/playbook/task.py2
-rw-r--r--test/units/playbook/test_task.py67
3 files changed, 46 insertions, 25 deletions
diff --git a/changelogs/fragments/delay_type.yml b/changelogs/fragments/delay_type.yml
new file mode 100644
index 0000000000..03b44dc098
--- /dev/null
+++ b/changelogs/fragments/delay_type.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - delay keyword is now a float, matching the underlying 'time' API and user expectations.
diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py
index 4ff105c5db..431501b4af 100644
--- a/lib/ansible/playbook/task.py
+++ b/lib/ansible/playbook/task.py
@@ -72,7 +72,7 @@ class Task(Base, Conditional, Taggable, CollectionSearch, Notifiable, Delegatabl
async_val = NonInheritableFieldAttribute(isa='int', default=0, alias='async')
changed_when = NonInheritableFieldAttribute(isa='list', default=list)
- delay = NonInheritableFieldAttribute(isa='int', default=5)
+ delay = NonInheritableFieldAttribute(isa='float', default=5)
failed_when = NonInheritableFieldAttribute(isa='list', default=list)
loop = NonInheritableFieldAttribute(isa='list')
loop_control = NonInheritableFieldAttribute(isa='class', class_type=LoopControl, default=LoopControl)
diff --git a/test/units/playbook/test_task.py b/test/units/playbook/test_task.py
index 6eb3bf2210..f00485cbc3 100644
--- a/test/units/playbook/test_task.py
+++ b/test/units/playbook/test_task.py
@@ -1,28 +1,15 @@
-# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-
+# Copyright: (c) Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import unittest
+
from unittest.mock import patch
+
+from ansible import errors
+from ansible.parsing.yaml import objects
from ansible.playbook.task import Task
from ansible.plugins.loader import init_plugin_loader
-from ansible.parsing.yaml import objects
-from ansible import errors
basic_command_task = dict(
@@ -42,7 +29,7 @@ kv_bad_args_ds = {'apk': 'sdfs sf sdf 37'}
class TestTask(unittest.TestCase):
def setUp(self):
- pass
+ self._task_base = {'name': 'test', 'action': 'debug'}
def tearDown(self):
pass
@@ -62,7 +49,7 @@ class TestTask(unittest.TestCase):
def test_load_task_simple(self):
t = Task.load(basic_command_task)
assert t is not None
- self.assertEqual(t.name, basic_command_task['name'])
+ self.assertEqual(t.get_name(), basic_command_task['name'])
self.assertEqual(t.action, 'command')
self.assertEqual(t.args, dict(_raw_params='echo hi'))
@@ -91,9 +78,41 @@ class TestTask(unittest.TestCase):
self.assertEqual(cm.exception.message.count('The error appears to be in'), 1)
def test_task_auto_name(self):
- assert 'name' not in kv_command_task
- Task.load(kv_command_task)
- # self.assertEqual(t.name, 'shell echo hi')
+ self.assertNotIn('name', kv_command_task)
+ t = Task.load(kv_command_task)
+ self.assertEqual(t.get_name(), 'command')
+
+ def test_delay(self):
+ good_params = [
+ (0, 0),
+ (0.1, 0.1),
+ ('0.3', 0.3),
+ ('0.03', 0.03),
+ ('12', 12),
+ (12, 12),
+ (1.2, 1.2),
+ ('1.2', 1.2),
+ ('1.0', 1),
+ ]
+ for delay, expected in good_params:
+ with self.subTest(f'type "{type(delay)}" was not cast to float', delay=delay, expected=expected):
+ p = dict(delay=delay)
+ p.update(self._task_base)
+ t = Task().load_data(p)
+ self.assertEqual(t.get_validated_value('delay', t.fattributes.get('delay'), delay, None), expected)
+
+ bad_params = [
+ ('E', ValueError),
+ ('1.E', ValueError),
+ ('E.1', ValueError),
+ ]
+ for delay, expected in bad_params:
+ with self.subTest(f'type "{type(delay)} was cast to float w/o error', delay=delay, expected=expected):
+ p = dict(delay=delay)
+ p.update(self._task_base)
+ t = Task().load_data(p)
+ with self.assertRaises(expected):
+ dummy = t.get_validated_value('delay', t.fattributes.get('delay'), delay, None)
def test_task_auto_name_with_role(self):
pass