How to use task method in Cypress

Best JavaScript code snippet using cypress

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

test_play_iterator.py

Source: test_play_iterator.py Github

copy
1# (c) 2012-2014, Michael DeHaan <[email protected]>
2#
3# This file is part of Ansible
4#
5# Ansible is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Ansible is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17
18# Make coding more python3-ish
19from __future__ import (absolute_import, division, print_function)
20__metaclass__ = type
21
22from ansible.compat.tests import unittest
23from ansible.compat.tests.mock import patch, MagicMock
24
25from ansible.errors import AnsibleError, AnsibleParserError
26from ansible.executor.play_iterator import HostState, PlayIterator
27from ansible.playbook import Playbook
28from ansible.playbook.task import Task
29from ansible.playbook.play_context import PlayContext
30
31from units.mock.loader import DictDataLoader
32from units.mock.path import mock_unfrackpath_noop
33
34
35class TestPlayIterator(unittest.TestCase):
36
37    def setUp(self):
38        pass
39
40    def tearDown(self):
41        pass
42
43    def test_host_state(self):
44        hs = HostState(blocks=[x for x in range(0, 10)])
45        hs.tasks_child_state = HostState(blocks=[0])
46        hs.rescue_child_state = HostState(blocks=[1])
47        hs.always_child_state = HostState(blocks=[2])
48        hs.__repr__()
49        hs.run_state = 100
50        hs.__repr__()
51        hs.fail_state = 15
52        hs.__repr__()
53
54        for i in range(0, 10):
55            hs.cur_block = i
56            self.assertEqual(hs.get_current_block(), i)
57
58        new_hs = hs.copy()
59
60
61    @patch('ansible.playbook.role.definition.unfrackpath', mock_unfrackpath_noop)
62    def test_play_iterator(self):
63        #import epdb; epdb.st()
64        fake_loader = DictDataLoader({
65            "test_play.yml": """
66            - hosts: all
67              gather_facts: false
68              roles:
69              - test_role
70              pre_tasks:
71              - debug: msg="this is a pre_task"
72              tasks:
73              - debug: msg="this is a regular task"
74              - block:
75                - debug: msg="this is a block task"
76                - block:
77                  - debug: msg="this is a sub-block in a block"
78                rescue:
79                - debug: msg="this is a rescue task"
80                - block:
81                  - debug: msg="this is a sub-block in a rescue"
82                always:
83                - debug: msg="this is an always task"
84                - block:
85                  - debug: msg="this is a sub-block in an always"
86              post_tasks:
87              - debug: msg="this is a post_task"
88            """,
89            '/etc/ansible/roles/test_role/tasks/main.yml': """
90            - name: role task
91              debug: msg="this is a role task"
92            - block:
93              - name: role block task
94                debug: msg="inside block in role"
95              always:
96              - name: role always task
97                debug: msg="always task in block in role"
98            - include: foo.yml
99            - name: role task after include
100              debug: msg="after include in role"
101            - block:
102              - name: starting role nested block 1
103                debug:
104              - block:
105                - name: role nested block 1 task 1
106                  debug:
107                - name: role nested block 1 task 2
108                  debug:
109                - name: role nested block 1 task 3
110                  debug:
111              - name: end of role nested block 1
112                debug:
113              - name: starting role nested block 2
114                debug:
115              - block:
116                - name: role nested block 2 task 1
117                  debug:
118                - name: role nested block 2 task 2
119                  debug:
120                - name: role nested block 2 task 3
121                  debug:
122              - name: end of role nested block 2
123                debug:
124            """,
125            '/etc/ansible/roles/test_role/tasks/foo.yml': """
126            - name: role included task
127              debug: msg="this is task in an include from a role"
128            """
129        })
130
131        mock_var_manager = MagicMock()
132        mock_var_manager._fact_cache = dict()
133        mock_var_manager.get_vars.return_value = dict()
134
135        p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager)
136
137        hosts = []
138        for i in range(0, 10):
139            host = MagicMock()
140            host.name = host.get_name.return_value = 'host%02d' % i
141            hosts.append(host)
142
143        mock_var_manager._fact_cache['host00'] = dict()
144
145        inventory = MagicMock()
146        inventory.get_hosts.return_value = hosts
147        inventory.filter_hosts.return_value = hosts
148
149        play_context = PlayContext(play=p._entries[0])
150
151        itr = PlayIterator(
152            inventory=inventory,
153            play=p._entries[0],
154            play_context=play_context,
155            variable_manager=mock_var_manager,
156            all_vars=dict(),
157        )
158
159        # lookup up an original task
160        target_task = p._entries[0].tasks[0].block[0]
161        task_copy = target_task.copy(exclude_parent=True)
162        found_task = itr.get_original_task(hosts[0], task_copy)
163        self.assertEqual(target_task, found_task)
164
165        bad_task = Task()
166        found_task = itr.get_original_task(hosts[0], bad_task)
167        self.assertIsNone(found_task)
168
169        # pre task
170        (host_state, task) = itr.get_next_task_for_host(hosts[0])
171        self.assertIsNotNone(task)
172        self.assertEqual(task.action, 'debug')
173        # implicit meta: flush_handlers
174        (host_state, task) = itr.get_next_task_for_host(hosts[0])
175        self.assertIsNotNone(task)
176        self.assertEqual(task.action, 'meta')
177        # role task
178        (host_state, task) = itr.get_next_task_for_host(hosts[0])
179        self.assertIsNotNone(task)
180        self.assertEqual(task.action, 'debug')
181        self.assertEqual(task.name, "role task")
182        self.assertIsNotNone(task._role)
183        # role block task
184        (host_state, task) = itr.get_next_task_for_host(hosts[0])
185        self.assertIsNotNone(task)
186        self.assertEqual(task.name, "role block task")
187        self.assertIsNotNone(task._role)
188        # role block always task
189        (host_state, task) = itr.get_next_task_for_host(hosts[0])
190        self.assertIsNotNone(task)
191        self.assertEqual(task.name, "role always task")
192        self.assertIsNotNone(task._role)
193        # role include task
194        #(host_state, task) = itr.get_next_task_for_host(hosts[0])
195        #self.assertIsNotNone(task)
196        #self.assertEqual(task.action, 'debug')
197        #self.assertEqual(task.name, "role included task")
198        #self.assertIsNotNone(task._role)
199        # role task after include
200        (host_state, task) = itr.get_next_task_for_host(hosts[0])
201        self.assertIsNotNone(task)
202        self.assertEqual(task.name, "role task after include")
203        self.assertIsNotNone(task._role)
204        # role nested block tasks
205        (host_state, task) = itr.get_next_task_for_host(hosts[0])
206        self.assertIsNotNone(task)
207        self.assertEqual(task.name, "starting role nested block 1")
208        self.assertIsNotNone(task._role)
209        (host_state, task) = itr.get_next_task_for_host(hosts[0])
210        self.assertIsNotNone(task)
211        self.assertEqual(task.name, "role nested block 1 task 1")
212        self.assertIsNotNone(task._role)
213        (host_state, task) = itr.get_next_task_for_host(hosts[0])
214        self.assertIsNotNone(task)
215        self.assertEqual(task.name, "role nested block 1 task 2")
216        self.assertIsNotNone(task._role)
217        (host_state, task) = itr.get_next_task_for_host(hosts[0])
218        self.assertIsNotNone(task)
219        self.assertEqual(task.name, "role nested block 1 task 3")
220        self.assertIsNotNone(task._role)
221        (host_state, task) = itr.get_next_task_for_host(hosts[0])
222        self.assertIsNotNone(task)
223        self.assertEqual(task.name, "end of role nested block 1")
224        self.assertIsNotNone(task._role)
225        (host_state, task) = itr.get_next_task_for_host(hosts[0])
226        self.assertIsNotNone(task)
227        self.assertEqual(task.name, "starting role nested block 2")
228        self.assertIsNotNone(task._role)
229        (host_state, task) = itr.get_next_task_for_host(hosts[0])
230        self.assertIsNotNone(task)
231        self.assertEqual(task.name, "role nested block 2 task 1")
232        self.assertIsNotNone(task._role)
233        (host_state, task) = itr.get_next_task_for_host(hosts[0])
234        self.assertIsNotNone(task)
235        self.assertEqual(task.name, "role nested block 2 task 2")
236        self.assertIsNotNone(task._role)
237        (host_state, task) = itr.get_next_task_for_host(hosts[0])
238        self.assertIsNotNone(task)
239        self.assertEqual(task.name, "role nested block 2 task 3")
240        self.assertIsNotNone(task._role)
241        (host_state, task) = itr.get_next_task_for_host(hosts[0])
242        self.assertIsNotNone(task)
243        self.assertEqual(task.name, "end of role nested block 2")
244        self.assertIsNotNone(task._role)
245        # regular play task
246        (host_state, task) = itr.get_next_task_for_host(hosts[0])
247        self.assertIsNotNone(task)
248        self.assertEqual(task.action, 'debug')
249        self.assertIsNone(task._role)
250        # block task
251        (host_state, task) = itr.get_next_task_for_host(hosts[0])
252        self.assertIsNotNone(task)
253        self.assertEqual(task.action, 'debug')
254        self.assertEqual(task.args, dict(msg="this is a block task"))
255        # sub-block task
256        (host_state, task) = itr.get_next_task_for_host(hosts[0])
257        self.assertIsNotNone(task)
258        self.assertEqual(task.action, 'debug')
259        self.assertEqual(task.args, dict(msg="this is a sub-block in a block"))
260        # mark the host failed
261        itr.mark_host_failed(hosts[0])
262        # block rescue task
263        (host_state, task) = itr.get_next_task_for_host(hosts[0])
264        self.assertIsNotNone(task)
265        self.assertEqual(task.action, 'debug')
266        self.assertEqual(task.args, dict(msg="this is a rescue task"))
267        # sub-block rescue task
268        (host_state, task) = itr.get_next_task_for_host(hosts[0])
269        self.assertIsNotNone(task)
270        self.assertEqual(task.action, 'debug')
271        self.assertEqual(task.args, dict(msg="this is a sub-block in a rescue"))
272        # block always task
273        (host_state, task) = itr.get_next_task_for_host(hosts[0])
274        self.assertIsNotNone(task)
275        self.assertEqual(task.action, 'debug')
276        self.assertEqual(task.args, dict(msg="this is an always task"))
277        # sub-block always task
278        (host_state, task) = itr.get_next_task_for_host(hosts[0])
279        self.assertIsNotNone(task)
280        self.assertEqual(task.action, 'debug')
281        self.assertEqual(task.args, dict(msg="this is a sub-block in an always"))
282        # implicit meta: flush_handlers
283        (host_state, task) = itr.get_next_task_for_host(hosts[0])
284        self.assertIsNotNone(task)
285        self.assertEqual(task.action, 'meta')
286        # post task
287        (host_state, task) = itr.get_next_task_for_host(hosts[0])
288        self.assertIsNotNone(task)
289        self.assertEqual(task.action, 'debug')
290        # implicit meta: flush_handlers
291        (host_state, task) = itr.get_next_task_for_host(hosts[0])
292        self.assertIsNotNone(task)
293        self.assertEqual(task.action, 'meta')
294        # end of iteration
295        (host_state, task) = itr.get_next_task_for_host(hosts[0])
296        self.assertIsNone(task)
297
298        # host 0 shouldn't be in the failed hosts, as the error
299        # was handled by a rescue block
300        failed_hosts = itr.get_failed_hosts()
301        self.assertNotIn(hosts[0], failed_hosts)
302
303    def test_play_iterator_nested_blocks(self):
304        fake_loader = DictDataLoader({
305            "test_play.yml": """
306            - hosts: all
307              gather_facts: false
308              tasks:
309              - block:
310                - block:
311                  - block:
312                    - block:
313                      - block:
314                        - debug: msg="this is the first task"
315                        - ping:
316                      rescue:
317                      - block:
318                        - block:
319                          - block:
320                            - block:
321                              - debug: msg="this is the rescue task"
322                  always:
323                  - block:
324                    - block:
325                      - block:
326                        - block:
327                          - debug: msg="this is the always task"
328            """,
329        })
330
331        mock_var_manager = MagicMock()
332        mock_var_manager._fact_cache = dict()
333        mock_var_manager.get_vars.return_value = dict()
334
335        p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager)
336
337        hosts = []
338        for i in range(0, 10):
339            host = MagicMock()
340            host.name = host.get_name.return_value = 'host%02d' % i
341            hosts.append(host)
342
343        inventory = MagicMock()
344        inventory.get_hosts.return_value = hosts
345        inventory.filter_hosts.return_value = hosts
346
347        play_context = PlayContext(play=p._entries[0])
348
349        itr = PlayIterator(
350            inventory=inventory,
351            play=p._entries[0],
352            play_context=play_context,
353            variable_manager=mock_var_manager,
354            all_vars=dict(),
355        )
356
357        # implicit meta: flush_handlers
358        (host_state, task) = itr.get_next_task_for_host(hosts[0])
359        self.assertIsNotNone(task)
360        self.assertEqual(task.action, 'meta')
361        self.assertEqual(task.args, dict(_raw_params='flush_handlers'))
362        # get the first task
363        (host_state, task) = itr.get_next_task_for_host(hosts[0])
364        self.assertIsNotNone(task)
365        self.assertEqual(task.action, 'debug')
366        self.assertEqual(task.args, dict(msg='this is the first task'))
367        # fail the host
368        itr.mark_host_failed(hosts[0])
369        # get the resuce task
370        (host_state, task) = itr.get_next_task_for_host(hosts[0])
371        self.assertIsNotNone(task)
372        self.assertEqual(task.action, 'debug')
373        self.assertEqual(task.args, dict(msg='this is the rescue task'))
374        # get the always task
375        (host_state, task) = itr.get_next_task_for_host(hosts[0])
376        self.assertIsNotNone(task)
377        self.assertEqual(task.action, 'debug')
378        self.assertEqual(task.args, dict(msg='this is the always task'))
379        # implicit meta: flush_handlers
380        (host_state, task) = itr.get_next_task_for_host(hosts[0])
381        self.assertIsNotNone(task)
382        self.assertEqual(task.action, 'meta')
383        self.assertEqual(task.args, dict(_raw_params='flush_handlers'))
384        # implicit meta: flush_handlers
385        (host_state, task) = itr.get_next_task_for_host(hosts[0])
386        self.assertIsNotNone(task)
387        self.assertEqual(task.action, 'meta')
388        self.assertEqual(task.args, dict(_raw_params='flush_handlers'))
389        # end of iteration
390        (host_state, task) = itr.get_next_task_for_host(hosts[0])
391        self.assertIsNone(task)
392
393    def test_play_iterator_add_tasks(self):
394        fake_loader = DictDataLoader({
395            'test_play.yml': """
396            - hosts: all
397              gather_facts: no
398              tasks:
399              - debug: msg="dummy task"
400            """,
401        })
402
403        mock_var_manager = MagicMock()
404        mock_var_manager._fact_cache = dict()
405        mock_var_manager.get_vars.return_value = dict()
406
407        p = Playbook.load('test_play.yml', loader=fake_loader, variable_manager=mock_var_manager)
408
409        hosts = []
410        for i in range(0, 10):
411            host = MagicMock()
412            host.name = host.get_name.return_value = 'host%02d' % i
413            hosts.append(host)
414
415        inventory = MagicMock()
416        inventory.get_hosts.return_value = hosts
417        inventory.filter_hosts.return_value = hosts
418
419        play_context = PlayContext(play=p._entries[0])
420
421        itr = PlayIterator(
422            inventory=inventory,
423            play=p._entries[0],
424            play_context=play_context,
425            variable_manager=mock_var_manager,
426            all_vars=dict(),
427        )
428
429        # test the high-level add_tasks() method
430        s = HostState(blocks=[0,1,2])
431        itr._insert_tasks_into_state = MagicMock(return_value=s)
432        itr.add_tasks(hosts[0], [MagicMock(), MagicMock(), MagicMock()])
433        self.assertEqual(itr._host_states[hosts[0].name], s)
434
435        # now actually test the lower-level method that does the work
436        itr = PlayIterator(
437            inventory=inventory,
438            play=p._entries[0],
439            play_context=play_context,
440            variable_manager=mock_var_manager,
441            all_vars=dict(),
442        )
443
444        # iterate past first task
445        _, task = itr.get_next_task_for_host(hosts[0])
446        while(task and task.action != 'debug'):
447            _, task = itr.get_next_task_for_host(hosts[0])
448
449        if task is None:
450            raise Exception("iterated past end of play while looking for place to insert tasks")
451
452        # get the current host state and copy it so we can mutate it
453        s = itr.get_host_state(hosts[0])
454        s_copy = s.copy()
455
456        # assert with an empty task list, or if we're in a failed state, we simply return the state as-is
457        res_state = itr._insert_tasks_into_state(s_copy, task_list=[])
458        self.assertEqual(res_state, s_copy)
459
460        s_copy.fail_state = itr.FAILED_TASKS
461        res_state = itr._insert_tasks_into_state(s_copy, task_list=[MagicMock()])
462        self.assertEqual(res_state, s_copy)
463
464        # but if we've failed with a rescue/always block
465        mock_task = MagicMock()
466        s_copy.run_state = itr.ITERATING_RESCUE
467        res_state = itr._insert_tasks_into_state(s_copy, task_list=[mock_task])
468        self.assertEqual(res_state, s_copy)
469        self.assertIn(mock_task, res_state._blocks[res_state.cur_block].rescue)
470        itr._host_states[hosts[0].name] = res_state
471        (next_state, next_task) = itr.get_next_task_for_host(hosts[0], peek=True)
472        self.assertEqual(next_task, mock_task)
473        itr._host_states[hosts[0].name] = s
474
475        # test a regular insertion
476        s_copy = s.copy()
477        res_state = itr._insert_tasks_into_state(s_copy, task_list=[MagicMock()])
478
Full Screen

test_tasks.py

Source: test_tasks.py Github

copy
1from collections import defaultdict
2from datetime import datetime
3import time
4
5from mock import patch, Mock
6
7from kettle.db import session
8from kettle.rollout import Rollout
9from kettle.tasks import Task, DelayTask, SequentialExecTask, ParallelExecTask
10from kettle.tests import KettleTestCase, TestTask, create_task
11
12class TestTasks(KettleTestCase):
13    def setUp(self):
14        self.rollout = Rollout({})
15        self.rollout.save()
16        self.rollout_id = self.rollout.id
17
18    @patch('kettle.tasks.Task._init')
19    def test_init(self, _init):
20        task = TestTask(self.rollout_id)
21        self.assertEqual(task.rollout_id, self.rollout_id)
22        self.assertTrue(TestTask._init.called)
23
24    def test_state(self):
25        class StateTask(Task):
26            def _init(self, cake, pie):
27                self.state['cake'] = cake
28                self.state['pie'] = pie
29
30        task = StateTask(self.rollout_id, 'a pie', 'a lie')
31        task.save()
32
33        session.Session.refresh(task)
34
35        self.assertEqual(task.state['cake'], 'a pie')
36        self.assertEqual(task.state['pie'], 'a lie')
37
38    def test_no_rollout_id(self):
39        task = TestTask(None)
40        self.assertRaises(Exception, task.save)
41
42    def test_run(self):
43        # Datetime at 1 second resolution
44        start = datetime.now().replace(microsecond=0)
45        _run_mock = Mock(return_value=10)
46
47        class RunTask(Task):
48            @classmethod
49            def _run(cls, state, children, abort, term):
50                return _run_mock(cls, state, children, abort, term)
51
52        task = RunTask(self.rollout_id)
53
54        self.assertEqual(task.run_start_dt, None)
55        self.assertEqual(task.run_error, None)
56        self.assertEqual(task.run_error_dt, None)
57        self.assertEqual(task.run_return, None)
58        self.assertEqual(task.run_return_dt, None)
59        self.assertEqual(task.run_traceback, None)
60
61        task.run()
62
63        _run_mock.assert_called_once_with(RunTask, task.state, task.children, None, None)
64
65        self.assertGreaterEqual(task.run_start_dt, start)
66        self.assertEqual(task.run_error, None)
67        self.assertEqual(task.run_error_dt, None)
68        self.assertEqual(task.run_return, str(10))
69        self.assertGreaterEqual(task.run_return_dt, start)
70        self.assertEqual(task.run_traceback, None)
71
72    def test_run_fail(self):
73        # Datetime at 1 second resolution
74        start = datetime.now().replace(microsecond=0)
75        _run_mock = Mock(return_value=10, side_effect=Exception('broken'))
76
77        class RunTaskFail(Task):
78            @classmethod
79            def _run(cls, state, children, abort, term):
80                return _run_mock(cls, state, children)
81
82        task = RunTaskFail(self.rollout_id)
83
84        self.assertEqual(task.run_start_dt, None)
85        self.assertEqual(task.run_error, None)
86        self.assertEqual(task.run_error_dt, None)
87        self.assertEqual(task.run_return, None)
88        self.assertEqual(task.run_return_dt, None)
89        self.assertEqual(task.run_traceback, None)
90
91        self.assertRaises(Exception, task.run)
92
93        _run_mock.assert_called_once_with(RunTaskFail, task.state, task.children)
94
95        self.assertGreaterEqual(task.run_start_dt, start)
96        self.assertEqual(task.run_error, 'broken')
97        self.assertGreaterEqual(task.run_error_dt, start)
98        self.assertEqual(task.run_return, None)
99        self.assertEqual(task.run_return_dt, None)
100        self.assertIn('broken', task.run_traceback)
101
102    def test_run_twice(self):
103        task = TestTask(self.rollout_id)
104
105        task.run()
106        self.assertRaises(Exception, task.run)
107
108    def test_revert_before_run(self):
109        # Reverting without running is not valid
110        _run_mock = Mock()
111
112        class RunlessTask(Task):
113            @classmethod
114            def _run(cls, state, children, abort, term):
115                return _run_mock(cls, state, children, abort, term)
116
117        task = RunlessTask(self.rollout_id)
118        self.assertRaises(Exception, task.revert)
119
120        _run_mock.assert_not_called()
121
122class TestSignals(KettleTestCase):
123    def test_signals(self):
124        rollouts = defaultdict(dict)
125        rollout_ids = defaultdict(dict)
126        tasks = defaultdict(dict)
127        classes = DelayTask, SequentialExecTask, ParallelExecTask
128        signals = ('abort_rollout',), ('term_rollout',), ('skip_rollback', 'term_rollout')
129        for cls in classes:
130            for sigs in signals:
131                rollout = Rollout({})
132                rollout.save()
133                rollouts[cls][sigs] = rollout
134                rollout_ids[cls][sigs] = rollout.id
135
136                if cls is DelayTask:
137                    task = create_task(rollout, DelayTask, seconds=15)
138                    tasks[cls][sigs] = task
139                else:
140                    t1, t2, t3 = [create_task(rollout, DelayTask, seconds=15) for _ in range(3)]
141                    task = create_task(rollout, cls, [t1, t2, t3])
142                    tasks[cls][sigs] = t3
143
144        for cls in classes:
145            for sigs in signals:
146                rollout = rollouts[cls][sigs]
147                rollout.rollout_async()
148
149        # Enough time for rollouts to start
150        time.sleep(0.5)
151
152        for cls in classes:
153            for sigs in signals:
154                id = rollout_ids[cls][sigs]
155                for sig in sigs:
156                    self.assertTrue(Rollout._can_signal(id, sig))
157                    self.assertTrue(Rollout._do_signal(id, sig))
158                    self.assertTrue(Rollout._is_signalling(id, sig))
159
160        # Enough time for rollouts to finish and save to db
161        time.sleep(2)
162
163        for cls in classes:
164            for sigs in signals:
165                rollout_id = rollout_ids[cls][sigs]
166                rollout = Rollout._from_id(rollout_id)
167                self.assertTrue(rollout.rollout_finish_dt, 'Rollout for %s not finished when sent %s' % (cls, sigs))
168                task = tasks[cls][sigs]
169                task = Task._from_id(task.id)
170                # Sequential exec's last task should not have run due to aborts
171                if cls is SequentialExecTask:
172                    self.assertFalse(task.run_start_dt, 'Final task %s run for %s rollout when sent %s' % (task, cls, sigs))
173                else:
174                    self.assertTrue(task.run_start_dt, 'Final task %s not run for %s rollout when sent %s' % (task, cls, sigs))
175
176                # If rollbacks were skipped the root task should not have reverted
177                if 'skip_rollback' in sigs:
178                    self.assertFalse(rollout.root_task.revert_start_dt, 'Rollout for %s rolled back when sent %s' % (cls, sigs))
179                else:
180                    self.assertTrue(rollout.root_task.revert_start_dt, 'Rollout for %s not rolled back when sent %s' % (cls, sigs))
181
Full Screen

tasks.py

Source: tasks.py Github

copy
1#
2# gdb helper commands and functions for Linux kernel debugging
3#
4#  task & thread tools
5#
6# Copyright (c) Siemens AG, 2011-2013
7#
8# Authors:
9#  Jan Kiszka <[email protected]>
10#
11# This work is licensed under the terms of the GNU GPL version 2.
12#
13
14import gdb
15
16from linux import utils
17
18
19task_type = utils.CachedType("struct task_struct")
20
21
22def task_lists():
23    task_ptr_type = task_type.get_type().pointer()
24    init_task = gdb.parse_and_eval("init_task").address
25    t = g = init_task
26
27    while True:
28        while True:
29            yield t
30
31            t = utils.container_of(t['thread_group']['next'],
32                                   task_ptr_type, "thread_group")
33            if t == g:
34                break
35
36        t = g = utils.container_of(g['tasks']['next'],
37                                   task_ptr_type, "tasks")
38        if t == init_task:
39            return
40
41
42def get_task_by_pid(pid):
43    for task in task_lists():
44        if int(task['pid']) == pid:
45            return task
46    return None
47
48
49class LxTaskByPidFunc(gdb.Function):
50    """Find Linux task by PID and return the task_struct variable.
51
52$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
53return that task_struct variable which PID matches."""
54
55    def __init__(self):
56        super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
57
58    def invoke(self, pid):
59        task = get_task_by_pid(pid)
60        if task:
61            return task.dereference()
62        else:
63            raise gdb.GdbError("No task of PID " + str(pid))
64
65
66LxTaskByPidFunc()
67
68
69class LxPs(gdb.Command):
70    """Dump Linux tasks."""
71
72    def __init__(self):
73        super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)
74
75    def invoke(self, arg, from_tty):
76        for task in task_lists():
77            gdb.write("{address} {pid} {comm}\n".format(
78                address=task,
79                pid=task["pid"],
80                comm=task["comm"].string()))
81
82LxPs()
83
84
85thread_info_type = utils.CachedType("struct thread_info")
86
87ia64_task_size = None
88
89
90def get_thread_info(task):
91    thread_info_ptr_type = thread_info_type.get_type().pointer()
92    if utils.is_target_arch("ia64"):
93        global ia64_task_size
94        if ia64_task_size is None:
95            ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
96        thread_info_addr = task.address + ia64_task_size
97        thread_info = thread_info_addr.cast(thread_info_ptr_type)
98    else:
99        thread_info = task['stack'].cast(thread_info_ptr_type)
100    return thread_info.dereference()
101
102
103class LxThreadInfoFunc (gdb.Function):
104    """Calculate Linux thread_info from task variable.
105
106$lx_thread_info(TASK): Given TASK, return the corresponding thread_info
107variable."""
108
109    def __init__(self):
110        super(LxThreadInfoFunc, self).__init__("lx_thread_info")
111
112    def invoke(self, task):
113        return get_thread_info(task)
114
115
116LxThreadInfoFunc()
117
Full Screen

task.js

Source: task.js Github

copy
1/**
2 * Support for concurrent task management and synchronization in web
3 * applications.
4 *
5 * @author Dave Longley
6 * @author David I. Lehn <dlehn@digitalbazaar.com>
7 *
8 * Copyright (c) 2009-2013 Digital Bazaar, Inc.
9 */
10var forge = require('./forge');
11require('./debug');
12require('./log');
13require('./util');
14
15// logging category
16var cat = 'forge.task';
17
18// verbose level
19// 0: off, 1: a little, 2: a whole lot
20// Verbose debug logging is surrounded by a level check to avoid the
21// performance issues with even calling the logging code regardless if it
22// is actually logged.  For performance reasons this should not be set to 2
23// for production use.
24// ex: if(sVL >= 2) forge.log.verbose(....)
25var sVL = 0;
26
27// track tasks for debugging
28var sTasks = {};
29var sNextTaskId = 0;
30// debug access
31forge.debug.set(cat, 'tasks', sTasks);
32
33// a map of task type to task queue
34var sTaskQueues = {};
35// debug access
36forge.debug.set(cat, 'queues', sTaskQueues);
37
38// name for unnamed tasks
39var sNoTaskName = '?';
40
41// maximum number of doNext() recursions before a context swap occurs
42// FIXME: might need to tweak this based on the browser
43var sMaxRecursions = 30;
44
45// time slice for doing tasks before a context swap occurs
46// FIXME: might need to tweak this based on the browser
47var sTimeSlice = 20;
48
49/**
50 * Task states.
51 *
52 * READY: ready to start processing
53 * RUNNING: task or a subtask is running
54 * BLOCKED: task is waiting to acquire N permits to continue
55 * SLEEPING: task is sleeping for a period of time
56 * DONE: task is done
57 * ERROR: task has an error
58 */
59var READY = 'ready';
60var RUNNING = 'running';
61var BLOCKED = 'blocked';
62var SLEEPING = 'sleeping';
63var DONE = 'done';
64var ERROR = 'error';
65
66/**
67 * Task actions.  Used to control state transitions.
68 *
69 * STOP: stop processing
70 * START: start processing tasks
71 * BLOCK: block task from continuing until 1 or more permits are released
72 * UNBLOCK: release one or more permits
73 * SLEEP: sleep for a period of time
74 * WAKEUP: wakeup early from SLEEPING state
75 * CANCEL: cancel further tasks
76 * FAIL: a failure occured
77 */
78var STOP = 'stop';
79var START = 'start';
80var BLOCK = 'block';
81var UNBLOCK = 'unblock';
82var SLEEP = 'sleep';
83var WAKEUP = 'wakeup';
84var CANCEL = 'cancel';
85var FAIL = 'fail';
86
87/**
88 * State transition table.
89 *
90 * nextState = sStateTable[currentState][action]
91 */
92var sStateTable = {};
93
94sStateTable[READY] = {};
95sStateTable[READY][STOP] = READY;
96sStateTable[READY][START] = RUNNING;
97sStateTable[READY][CANCEL] = DONE;
98sStateTable[READY][FAIL] = ERROR;
99
100sStateTable[RUNNING] = {};
101sStateTable[RUNNING][STOP] = READY;
102sStateTable[RUNNING][START] = RUNNING;
103sStateTable[RUNNING][BLOCK] = BLOCKED;
104sStateTable[RUNNING][UNBLOCK] = RUNNING;
105sStateTable[RUNNING][SLEEP] = SLEEPING;
106sStateTable[RUNNING][WAKEUP] = RUNNING;
107sStateTable[RUNNING][CANCEL] = DONE;
108sStateTable[RUNNING][FAIL] = ERROR;
109
110sStateTable[BLOCKED] = {};
111sStateTable[BLOCKED][STOP] = BLOCKED;
112sStateTable[BLOCKED][START] = BLOCKED;
113sStateTable[BLOCKED][BLOCK] = BLOCKED;
114sStateTable[BLOCKED][UNBLOCK] = BLOCKED;
115sStateTable[BLOCKED][SLEEP] = BLOCKED;
116sStateTable[BLOCKED][WAKEUP] = BLOCKED;
117sStateTable[BLOCKED][CANCEL] = DONE;
118sStateTable[BLOCKED][FAIL] = ERROR;
119
120sStateTable[SLEEPING] = {};
121sStateTable[SLEEPING][STOP] = SLEEPING;
122sStateTable[SLEEPING][START] = SLEEPING;
123sStateTable[SLEEPING][BLOCK] = SLEEPING;
124sStateTable[SLEEPING][UNBLOCK] = SLEEPING;
125sStateTable[SLEEPING][SLEEP] = SLEEPING;
126sStateTable[SLEEPING][WAKEUP] = SLEEPING;
127sStateTable[SLEEPING][CANCEL] = DONE;
128sStateTable[SLEEPING][FAIL] = ERROR;
129
130sStateTable[DONE] = {};
131sStateTable[DONE][STOP] = DONE;
132sStateTable[DONE][START] = DONE;
133sStateTable[DONE][BLOCK] = DONE;
134sStateTable[DONE][UNBLOCK] = DONE;
135sStateTable[DONE][SLEEP] = DONE;
136sStateTable[DONE][WAKEUP] = DONE;
137sStateTable[DONE][CANCEL] = DONE;
138sStateTable[DONE][FAIL] = ERROR;
139
140sStateTable[ERROR] = {};
141sStateTable[ERROR][STOP] = ERROR;
142sStateTable[ERROR][START] = ERROR;
143sStateTable[ERROR][BLOCK] = ERROR;
144sStateTable[ERROR][UNBLOCK] = ERROR;
145sStateTable[ERROR][SLEEP] = ERROR;
146sStateTable[ERROR][WAKEUP] = ERROR;
147sStateTable[ERROR][CANCEL] = ERROR;
148sStateTable[ERROR][FAIL] = ERROR;
149
150/**
151 * Creates a new task.
152 *
153 * @param options options for this task
154 *   run: the run function for the task (required)
155 *   name: the run function for the task (optional)
156 *   parent: parent of this task (optional)
157 *
158 * @return the empty task.
159 */
160var Task = function(options) {
161  // task id
162  this.id = -1;
163
164  // task name
165  this.name = options.name || sNoTaskName;
166
167  // task has no parent
168  this.parent = options.parent || null;
169
170  // save run function
171  this.run = options.run;
172
173  // create a queue of subtasks to run
174  this.subtasks = [];
175
176  // error flag
177  this.error = false;
178
179  // state of the task
180  this.state = READY;
181
182  // number of times the task has been blocked (also the number
183  // of permits needed to be released to continue running)
184  this.blocks = 0;
185
186  // timeout id when sleeping
187  this.timeoutId = null;
188
189  // no swap time yet
190  this.swapTime = null;
191
192  // no user data
193  this.userData = null;
194
195  // initialize task
196  // FIXME: deal with overflow
197  this.id = sNextTaskId++;
198  sTasks[this.id] = this;
199  if(sVL >= 1) {
200    forge.log.verbose(cat, '[%s][%s] init', this.id, this.name, this);
201  }
202};
203
204/**
205 * Logs debug information on this task and the system state.
206 */
207Task.prototype.debug = function(msg) {
208  msg = msg || '';
209  forge.log.debug(cat, msg,
210    '[%s][%s] task:', this.id, this.name, this,
211    'subtasks:', this.subtasks.length,
212    'queue:', sTaskQueues);
213};
214
215/**
216 * Adds a subtask to run after task.doNext() or task.fail() is called.
217 *
218 * @param name human readable name for this task (optional).
219 * @param subrun a function to run that takes the current task as
220 *          its first parameter.
221 *
222 * @return the current task (useful for chaining next() calls).
223 */
224Task.prototype.next = function(name, subrun) {
225  // juggle parameters if it looks like no name is given
226  if(typeof(name) === 'function') {
227    subrun = name;
228
229    // inherit parent's name
230    name = this.name;
231  }
232  // create subtask, set parent to this task, propagate callbacks
233  var subtask = new Task({
234    run: subrun,
235    name: name,
236    parent: this
237  });
238  // start subtasks running
239  subtask.state = RUNNING;
240  subtask.type = this.type;
241  subtask.successCallback = this.successCallback || null;
242  subtask.failureCallback = this.failureCallback || null;
243
244  // queue a new subtask
245  this.subtasks.push(subtask);
246
247  return this;
248};
249
250/**
251 * Adds subtasks to run in parallel after task.doNext() or task.fail()
252 * is called.
253 *
254 * @param name human readable name for this task (optional).
255 * @param subrun functions to run that take the current task as
256 *          their first parameter.
257 *
258 * @return the current task (useful for chaining next() calls).
259 */
260Task.prototype.parallel = function(name, subrun) {
261  // juggle parameters if it looks like no name is given
262  if(forge.util.isArray(name)) {
263    subrun = name;
264
265    // inherit parent's name
266    name = this.name;
267  }
268  // Wrap parallel tasks in a regular task so they are started at the
269  // proper time.
270  return this.next(name, function(task) {
271    // block waiting for subtasks
272    var ptask = task;
273    ptask.block(subrun.length);
274
275    // we pass the iterator from the loop below as a parameter
276    // to a function because it is otherwise included in the
277    // closure and changes as the loop changes -- causing i
278    // to always be set to its highest value
279    var startParallelTask = function(pname, pi) {
280      forge.task.start({
281        type: pname,
282        run: function(task) {
283           subrun[pi](task);
284        },
285        success: function(task) {
286           ptask.unblock();
287        },
288        failure: function(task) {
289           ptask.unblock();
290        }
291      });
292    };
293
294    for(var i = 0; i < subrun.length; i++) {
295      // Type must be unique so task starts in parallel:
296      //    name + private string + task id + sub-task index
297      // start tasks in parallel and unblock when the finish
298      var pname = name + '__parallel-' + task.id + '-' + i;
299      var pi = i;
300      startParallelTask(pname, pi);
301    }
302  });
303};
304
305/**
306 * Stops a running task.
307 */
308Task.prototype.stop = function() {
309  this.state = sStateTable[this.state][STOP];
310};
311
312/**
313 * Starts running a task.
314 */
315Task.prototype.start = function() {
316  this.error = false;
317  this.state = sStateTable[this.state][START];
318
319  // try to restart
320  if(this.state === RUNNING) {
321    this.start = new Date();
322    this.run(this);
323    runNext(this, 0);
324  }
325};
326
327/**
328 * Blocks a task until it one or more permits have been released. The
329 * task will not resume until the requested number of permits have
330 * been released with call(s) to unblock().
331 *
332 * @param n number of permits to wait for(default: 1).
333 */
334Task.prototype.block = function(n) {
335  n = typeof(n) === 'undefined' ? 1 : n;
336  this.blocks += n;
337  if(this.blocks > 0) {
338    this.state = sStateTable[this.state][BLOCK];
339  }
340};
341
342/**
343 * Releases a permit to unblock a task. If a task was blocked by
344 * requesting N permits via block(), then it will only continue
345 * running once enough permits have been released via unblock() calls.
346 *
347 * If multiple processes need to synchronize with a single task then
348 * use a condition variable (see forge.task.createCondition). It is
349 * an error to unblock a task more times than it has been blocked.
350 *
351 * @param n number of permits to release (default: 1).
352 *
353 * @return the current block count (task is unblocked when count is 0)
354 */
355Task.prototype.unblock = function(n) {
356  n = typeof(n) === 'undefined' ? 1 : n;
357  this.blocks -= n;
358  if(this.blocks === 0 && this.state !== DONE) {
359    this.state = RUNNING;
360    runNext(this, 0);
361  }
362  return this.blocks;
363};
364
365/**
366 * Sleep for a period of time before resuming tasks.
367 *
368 * @param n number of milliseconds to sleep (default: 0).
369 */
370Task.prototype.sleep = function(n) {
371  n = typeof(n) === 'undefined' ? 0 : n;
372  this.state = sStateTable[this.state][SLEEP];
373  var self = this;
374  this.timeoutId = setTimeout(function() {
375    self.timeoutId = null;
376    self.state = RUNNING;
377    runNext(self, 0);
378  }, n);
379};
380
381/**
382 * Waits on a condition variable until notified. The next task will
383 * not be scheduled until notification. A condition variable can be
384 * created with forge.task.createCondition().
385 *
386 * Once cond.notify() is called, the task will continue.
387 *
388 * @param cond the condition variable to wait on.
389 */
390Task.prototype.wait = function(cond) {
391  cond.wait(this);
392};
393
394/**
395 * If sleeping, wakeup and continue running tasks.
396 */
397Task.prototype.wakeup = function() {
398  if(this.state === SLEEPING) {
399    cancelTimeout(this.timeoutId);
400    this.timeoutId = null;
401    this.state = RUNNING;
402    runNext(this, 0);
403  }
404};
405
406/**
407 * Cancel all remaining subtasks of this task.
408 */
409Task.prototype.cancel = function() {
410  this.state = sStateTable[this.state][CANCEL];
411  // remove permits needed
412  this.permitsNeeded = 0;
413  // cancel timeouts
414  if(this.timeoutId !== null) {
415    cancelTimeout(this.timeoutId);
416    this.timeoutId = null;
417  }
418  // remove subtasks
419  this.subtasks = [];
420};
421
422/**
423 * Finishes this task with failure and sets error flag. The entire
424 * task will be aborted unless the next task that should execute
425 * is passed as a parameter. This allows levels of subtasks to be
426 * skipped. For instance, to abort only this tasks's subtasks, then
427 * call fail(task.parent). To abort this task's subtasks and its
428 * parent's subtasks, call fail(task.parent.parent). To abort
429 * all tasks and simply call the task callback, call fail() or
430 * fail(null).
431 *
432 * The task callback (success or failure) will always, eventually, be
433 * called.
434 *
435 * @param next the task to continue at, or null to abort entirely.
436 */
437Task.prototype.fail = function(next) {
438  // set error flag
439  this.error = true;
440
441  // finish task
442  finish(this, true);
443
444  if(next) {
445    // propagate task info
446    next.error = this.error;
447    next.swapTime = this.swapTime;
448    next.userData = this.userData;
449
450    // do next task as specified
451    runNext(next, 0);
452  } else {
453    if(this.parent !== null) {
454      // finish root task (ensures it is removed from task queue)
455      var parent = this.parent;
456      while(parent.parent !== null) {
457        // propagate task info
458        parent.error = this.error;
459        parent.swapTime = this.swapTime;
460        parent.userData = this.userData;
461        parent = parent.parent;
462      }
463      finish(parent, true);
464    }
465
466    // call failure callback if one exists
467    if(this.failureCallback) {
468      this.failureCallback(this);
469    }
470  }
471};
472
473/**
474 * Asynchronously start a task.
475 *
476 * @param task the task to start.
477 */
478var start = function(task) {
479  task.error = false;
480  task.state = sStateTable[task.state][START];
481  setTimeout(function() {
482    if(task.state === RUNNING) {
483      task.swapTime = +new Date();
484      task.run(task);
485      runNext(task, 0);
486    }
487  }, 0);
488};
489
490/**
491 * Run the next subtask or finish this task.
492 *
493 * @param task the task to process.
494 * @param recurse the recursion count.
495 */
496var runNext = function(task, recurse) {
497  // get time since last context swap (ms), if enough time has passed set
498  // swap to true to indicate that doNext was performed asynchronously
499  // also, if recurse is too high do asynchronously
500  var swap =
501    (recurse > sMaxRecursions) ||
502    (+new Date() - task.swapTime) > sTimeSlice;
503
504  var doNext = function(recurse) {
505    recurse++;
506    if(task.state === RUNNING) {
507      if(swap) {
508        // update swap time
509        task.swapTime = +new Date();
510      }
511
512      if(task.subtasks.length > 0) {
513        // run next subtask
514        var subtask = task.subtasks.shift();
515        subtask.error = task.error;
516        subtask.swapTime = task.swapTime;
517        subtask.userData = task.userData;
518        subtask.run(subtask);
519        if(!subtask.error) {
520           runNext(subtask, recurse);
521        }
522      } else {
523        finish(task);
524
525        if(!task.error) {
526          // chain back up and run parent
527          if(task.parent !== null) {
528            // propagate task info
529            task.parent.error = task.error;
530            task.parent.swapTime = task.swapTime;
531            task.parent.userData = task.userData;
532
533            // no subtasks left, call run next subtask on parent
534            runNext(task.parent, recurse);
535          }
536        }
537      }
538    }
539  };
540
541  if(swap) {
542    // we're swapping, so run asynchronously
543    setTimeout(doNext, 0);
544  } else {
545    // not swapping, so run synchronously
546    doNext(recurse);
547  }
548};
549
550/**
551 * Finishes a task and looks for the next task in the queue to start.
552 *
553 * @param task the task to finish.
554 * @param suppressCallbacks true to suppress callbacks.
555 */
556var finish = function(task, suppressCallbacks) {
557  // subtask is now done
558  task.state = DONE;
559
560  delete sTasks[task.id];
561  if(sVL >= 1) {
562    forge.log.verbose(cat, '[%s][%s] finish',
563      task.id, task.name, task);
564  }
565
566  // only do queue processing for root tasks
567  if(task.parent === null) {
568    // report error if queue is missing
569    if(!(task.type in sTaskQueues)) {
570      forge.log.error(cat,
571        '[%s][%s] task queue missing [%s]',
572        task.id, task.name, task.type);
573    } else if(sTaskQueues[task.type].length === 0) {
574      // report error if queue is empty
575      forge.log.error(cat,
576        '[%s][%s] task queue empty [%s]',
577        task.id, task.name, task.type);
578    } else if(sTaskQueues[task.type][0] !== task) {
579      // report error if this task isn't the first in the queue
580      forge.log.error(cat,
581        '[%s][%s] task not first in queue [%s]',
582        task.id, task.name, task.type);
583    } else {
584      // remove ourselves from the queue
585      sTaskQueues[task.type].shift();
586      // clean up queue if it is empty
587      if(sTaskQueues[task.type].length === 0) {
588        if(sVL >= 1) {
589          forge.log.verbose(cat, '[%s][%s] delete queue [%s]',
590            task.id, task.name, task.type);
591        }
592        /* Note: Only a task can delete a queue of its own type. This
593         is used as a way to synchronize tasks. If a queue for a certain
594         task type exists, then a task of that type is running.
595         */
596        delete sTaskQueues[task.type];
597      } else {
598        // dequeue the next task and start it
599        if(sVL >= 1) {
600          forge.log.verbose(cat,
601            '[%s][%s] queue start next [%s] remain:%s',
602            task.id, task.name, task.type,
603            sTaskQueues[task.type].length);
604        }
605        sTaskQueues[task.type][0].start();
606      }
607    }
608
609    if(!suppressCallbacks) {
610      // call final callback if one exists
611      if(task.error && task.failureCallback) {
612        task.failureCallback(task);
613      } else if(!task.error && task.successCallback) {
614        task.successCallback(task);
615      }
616    }
617  }
618};
619
620/* Tasks API */
621module.exports = forge.task = forge.task || {};
622
623/**
624 * Starts a new task that will run the passed function asynchronously.
625 *
626 * In order to finish the task, either task.doNext() or task.fail()
627 * *must* be called.
628 *
629 * The task must have a type (a string identifier) that can be used to
630 * synchronize it with other tasks of the same type. That type can also
631 * be used to cancel tasks that haven't started yet.
632 *
633 * To start a task, the following object must be provided as a parameter
634 * (each function takes a task object as its first parameter):
635 *
636 * {
637 *   type: the type of task.
638 *   run: the function to run to execute the task.
639 *   success: a callback to call when the task succeeds (optional).
640 *   failure: a callback to call when the task fails (optional).
641 * }
642 *
643 * @param options the object as described above.
644 */
645forge.task.start = function(options) {
646  // create a new task
647  var task = new Task({
648    run: options.run,
649    name: options.name || sNoTaskName
650  });
651  task.type = options.type;
652  task.successCallback = options.success || null;
653  task.failureCallback = options.failure || null;
654
655  // append the task onto the appropriate queue
656  if(!(task.type in sTaskQueues)) {
657    if(sVL >= 1) {
658      forge.log.verbose(cat, '[%s][%s] create queue [%s]',
659        task.id, task.name, task.type);
660    }
661    // create the queue with the new task
662    sTaskQueues[task.type] = [task];
663    start(task);
664  } else {
665    // push the task onto the queue, it will be run after a task
666    // with the same type completes
667    sTaskQueues[options.type].push(task);
668  }
669};
670
671/**
672 * Cancels all tasks of the given type that haven't started yet.
673 *
674 * @param type the type of task to cancel.
675 */
676forge.task.cancel = function(type) {
677  // find the task queue
678  if(type in sTaskQueues) {
679    // empty all but the current task from the queue
680    sTaskQueues[type] = [sTaskQueues[type][0]];
681  }
682};
683
684/**
685 * Creates a condition variable to synchronize tasks. To make a task wait
686 * on the condition variable, call task.wait(condition). To notify all
687 * tasks that are waiting, call condition.notify().
688 *
689 * @return the condition variable.
690 */
691forge.task.createCondition = function() {
692  var cond = {
693    // all tasks that are blocked
694    tasks: {}
695  };
696
697  /**
698   * Causes the given task to block until notify is called. If the task
699   * is already waiting on this condition then this is a no-op.
700   *
701   * @param task the task to cause to wait.
702   */
703  cond.wait = function(task) {
704    // only block once
705    if(!(task.id in cond.tasks)) {
706       task.block();
707       cond.tasks[task.id] = task;
708    }
709  };
710
711  /**
712   * Notifies all waiting tasks to wake up.
713   */
714  cond.notify = function() {
715    // since unblock() will run the next task from here, make sure to
716    // clear the condition's blocked task list before unblocking
717    var tmp = cond.tasks;
718    cond.tasks = {};
719    for(var id in tmp) {
720      tmp[id].unblock();
721    }
722  };
723
724  return cond;
725};
726
Full Screen

currentTask.js

Source: currentTask.js Github

copy
1//constants
2import NOTIFICATIONS from '../../../constants/notifications';
3import { CURRENT_TASK, MODALS } from '../constants';
4
5//actions
6import {
7    addSuccessNotification,
8    addErrorNotification,
9} from '../../shared/actions/notifications';
10import { startRequest, endRequest } from '../../shared/actions/requests';
11import { closeModal } from '../actions/activeModals';
12
13//services
14import { getTask, updateTask, deleteTask } from '../services/tasks';
15import { createTask } from '../services/projects';
16
17const getCurrentTaskSuccess = (task) => ({
18    type: CURRENT_TASK.GET_SUCCESS,
19    payload: { task },
20});
21
22const getCurrentTaskError = () => ({ type: CURRENT_TASK.GET_ERROR });
23
24const getCurrentTask = (id) => async (dispatch) => {
25    dispatch(startRequest(CURRENT_TASK.GET));
26
27    try {
28        const { task } = await getTask(id);
29        dispatch(getCurrentTaskSuccess(task));
30    } catch (err) {
31        dispatch(getCurrentTaskError());
32    }
33
34    dispatch(endRequest(CURRENT_TASK.GET));
35};
36
37const createTaskSuccess = (task) => ({
38    type: CURRENT_TASK.CREATE_SUCCESS,
39    payload: { task },
40});
41
42const _createTask = ({ title, description, projectId, parentTask }) => async (
43    dispatch
44) => {
45    dispatch(startRequest(CURRENT_TASK.CREATE));
46
47    try {
48        const { task } = await createTask({
49            title,
50            description,
51            projectId,
52            parentTask,
53        });
54        dispatch(createTaskSuccess(task));
55        dispatch(addSuccessNotification(NOTIFICATIONS.TASK.CREATE_SUCCESS));
56    } catch {
57        dispatch(addErrorNotification(NOTIFICATIONS.TASK.CREATE_ERROR));
58    }
59
60    dispatch(endRequest(CURRENT_TASK.CREATE));
61    dispatch(closeModal(MODALS.TASK_CREATE));
62};
63
64const deleteCurrentTaskSuccess = () => ({
65    type: CURRENT_TASK.DELETE_SUCCESS,
66});
67
68const deleteCurrentTask = (id) => async (dispatch) => {
69    dispatch(startRequest(CURRENT_TASK.DELETE));
70
71    let error = null;
72    try {
73        await deleteTask(id);
74        dispatch(deleteCurrentTaskSuccess());
75        dispatch(addSuccessNotification(NOTIFICATIONS.TASK.DELETE_SUCCESS));
76    } catch (err) {
77        dispatch(addErrorNotification(NOTIFICATIONS.TASK.DELETE_ERROR));
78        error = err;
79    }
80
81    dispatch(endRequest(CURRENT_TASK.DELETE));
82    return error;
83};
84
85const updateCurrentTaskSuccess = (task) => ({
86    type: CURRENT_TASK.UPDATE_SUCCESS,
87    payload: { task },
88});
89
90const updateCurrentTask = ({ taskId, updates }) => async (dispatch) => {
91    dispatch(startRequest(CURRENT_TASK.UPDATE));
92
93    let error = null;
94    try {
95        const { task } = await updateTask({ taskId, updates });
96        dispatch(updateCurrentTaskSuccess(task));
97        dispatch(addSuccessNotification(NOTIFICATIONS.TASK.UPDATE_SUCCESS));
98    } catch (err) {
99        dispatch(addErrorNotification(NOTIFICATIONS.TASK.UPDATE_ERROR));
100        erorr = err;
101    }
102
103    dispatch(endRequest(CURRENT_TASK.UPDATE));
104    return error;
105};
106
107const clearCurrentTask = () => ({
108    type: CURRENT_TASK.CLEAR,
109});
110
111export {
112    getCurrentTask,
113    clearCurrentTask,
114    _createTask as createTask,
115    deleteCurrentTask,
116    updateCurrentTask,
117};
118
Full Screen

task.spec.js

Source: task.spec.js Github

copy
1import { expect } from 'chai';
2
3import {
4    request,
5    data,
6    seedUsers,
7    seedTasks,
8    seedProjects,
9    db,
10    ROUTES,
11    login,
12} from './config';
13
14//models
15import { User, Project, Task } from '../models';
16
17before(async () => {
18    await db.connect();
19});
20
21after(async () => {
22    await db.disconnect();
23});
24
25afterEach(async () => {
26    await User.deleteMany({});
27    await Project.deleteMany({});
28    await Task.deleteMany({});
29});
30
31describe('task API', () => {
32    describe('GET /api/tasks/:task_id', () => {
33        const task = data.tasks[0];
34
35        beforeEach(async () => {
36            await seedUsers();
37            await seedProjects();
38            await seedTasks();
39        });
40
41        it('should return task when user has access to it', async () => {
42            const { username, password } = data.users[2];
43
44            await login(username, password);
45            const res = await request.get(`${ROUTES.TASK.ROOT}/${task._id}`);
46
47            expect(res.body.task._id).to.equal(task._id);
48        });
49
50        it('should not return task when user does not have access to it', async () => {
51            const { username, password } = data.users[0];
52
53            await login(username, password);
54            const res = await request.get(`${ROUTES.TASK.ROOT}/${task._id}`);
55            expect(res.body.task).to.not.be.ok;
56        });
57
58        it('should not return task when task doesnt exist', async () => {
59            const { username, password } = data.users[2];
60
61            await login(username, password);
62            const res = await request.get(
63                `${ROUTES.TASK.ROOT}/bdbdf88028e375d81dccee42`
64            );
65            expect(res.body.task).to.not.be.ok;
66        });
67    });
68
69    describe('PATCH /api/tasks/:task_id', () => {
70        const task = data.tasks[0];
71
72        beforeEach(async () => {
73            await seedUsers();
74            await seedProjects();
75            await seedTasks();
76        });
77
78        it('should update when user is member and updates are valid', async () => {
79            const description = 'New description';
80            const isCompleted = true;
81            const { username, password } = data.users[2];
82
83            await login(username, password);
84            await request
85                .patch(`${ROUTES.TASK.ROOT}/${task._id}`)
86                .send({ description, isCompleted });
87
88            const $task = await Task.findById(task._id);
89            expect($task.description).to.equal(description);
90        });
91
92        it('should not update when user is member and updates are not valid', async () => {
93            const description = 'New description';
94            const milk = 'Invalid';
95            const { username, password } = data.users[2];
96
97            await login(username, password);
98            await request
99                .patch(`${ROUTES.TASK.ROOT}/${task._id}`)
100                .send({ description, milk });
101
102            const $task = await Task.findById(task._id);
103            expect($task.description).to.not.equal(description);
104        });
105
106        it('should not update when user is not a member and updates are valid', async () => {
107            const description = 'New description';
108            const isCompleted = true;
109            const { username, password } = data.users[0];
110
111            await login(username, password);
112            await request
113                .patch(`${ROUTES.TASK.ROOT}/${task._id}`)
114                .send({ description, isCompleted });
115
116            const $task = await Task.findById(task._id);
117            expect($task.description).to.not.equal(description);
118        });
119
120        it('should return updated task when its updated', async () => {
121            const description = 'New description';
122            const isCompleted = true;
123            const { username, password } = data.users[2];
124
125            await login(username, password);
126            const res = await request
127                .patch(`${ROUTES.TASK.ROOT}/${task._id}`)
128                .send({ description, isCompleted });
129
130            expect(res.body.task.description).to.equal(description);
131        });
132    });
133
134    describe('DELETE /api/tasks/:task_id', () => {
135        beforeEach(async () => {
136            await seedUsers();
137            await seedProjects();
138            await seedTasks();
139        });
140
141        it('should delete task when user is a project member', async () => {
142            const { username, password } = data.users[1];
143            const task = data.tasks[0];
144
145            await login(username, password);
146            await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);
147
148            const $task = await Task.findById(task._id);
149            expect($task).to.not.be.ok;
150        });
151
152        it('should delete child tasks when parent task is deleted', async () => {
153            const { username, password } = data.users[1];
154            const taskParent = data.tasks[0];
155            const task = data.tasks[1];
156
157            await login(username, password);
158            await request.delete(`${ROUTES.TASK.ROOT}/${taskParent._id}`);
159
160            const $task = await Task.findById(task._id);
161            expect($task).to.not.be.ok;
162        });
163
164        it('should remove task from project tasks when task is deleted', async () => {
165            const { username, password } = data.users[1];
166            const task = data.tasks[0];
167            const project = data.projects[0];
168
169            await login(username, password);
170            await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);
171
172            const $project = await Project.findById(project._id);
173            const isTaskIncluded = $project.tasks.includes(task._id);
174            expect(isTaskIncluded).to.equal(false);
175        });
176
177        it('should remove task from parent task when child task is deleted', async () => {
178            const { username, password } = data.users[1];
179            const taskParent = data.tasks[0];
180            const task = data.tasks[1];
181
182            await login(username, password);
183            await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);
184
185            const $task = await Task.findById(taskParent._id);
186            const isTaskIncluded = $task.tasks.includes(task._id);
187            expect(isTaskIncluded).to.equal(false);
188        });
189
190        it('should not remove task when user is not a project member', async () => {
191            const { username, password } = data.users[0];
192            const task = data.tasks[0];
193
194            await login(username, password);
195            await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);
196
197            const $task = await Task.findById(task._id);
198            expect($task).to.be.ok;
199        });
200    });
201});
202
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Cypress on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)