Beispiel #1
0
 def _call_objs(self, contextualized):
     # Setup
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body, contextualized=contextualized)
     t2 = Task(post_body, contextualized=contextualized)
     t3 = Task(
         Mock(),
         pre=[call(t1, 5, foo='bar')],
         post=[call(t2, 7, biz='baz')],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute('t3')
     # Pre-task asserts
     args, kwargs = pre_body.call_args
     eq_(kwargs, {'foo': 'bar'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 5)
     else:
         eq_(args, (5, ))
     # Post-task asserts
     args, kwargs = post_body.call_args
     eq_(kwargs, {'biz': 'baz'})
     if contextualized:
         assert isinstance(args[0], Context)
         eq_(args[1], 7)
     else:
         eq_(args, (7, ))
Beispiel #2
0
 def calls_default_to_empty_args_always(self):
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(Mock(), pre=[t1], post=[t2])
     e = Executor(collection=Collection(t1=t1, t2=t2, t3=t3))
     e.execute(('t3', {'something': 'meh'}))
     for body in (pre_body, post_body):
         eq_(body.call_args, tuple())
Beispiel #3
0
 def deduping_treats_different_calls_to_same_task_differently(self):
     body = Mock()
     t1 = Task(body)
     pre = [call(t1, 5), call(t1, 7), call(t1, 5)]
     t2 = Task(Mock(), pre=pre)
     c = Collection(t1=t1, t2=t2)
     e = Executor(collection=c)
     e.execute('t2')
     # Does not call the second t1(5)
     body.assert_has_calls([mock_call(5), mock_call(7)])
Beispiel #4
0
 def calls_default_to_empty_args_always(self):
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(Mock(), pre=[t1], post=[t2])
     e = Executor(collection=Collection(t1=t1, t2=t2, t3=t3))
     e.execute(('t3', {'something': 'meh'}))
     for body in (pre_body, post_body):
         args = body.call_args[0]
         assert len(args) == 1
         assert isinstance(args[0], Context)
Beispiel #5
0
 def calls_default_to_empty_args_always(self):
     dep_body, followup_body = Mock(), Mock()
     t1 = Task(dep_body)
     t2 = Task(followup_body)
     t3 = Task(Mock(), depends_on=[t1], afterwards=[t2])
     e = Executor(collection=Collection(t1=t1, t2=t2, t3=t3))
     e.execute(('t3', {'something': 'meh'}))
     for body in (dep_body, followup_body):
         args = body.call_args[0]
         eq_(len(args), 1)
         ok_(isinstance(args[0], Context))
Beispiel #6
0
 def setup(self):
     self.task1 = Task(Mock(return_value=7))
     self.task2 = Task(Mock(return_value=10), pre=[self.task1])
     self.task3 = Task(Mock(), pre=[self.task1])
     self.task4 = Task(Mock(return_value=15), post=[self.task1])
     self.contextualized = Task(Mock())
     coll = Collection()
     coll.add_task(self.task1, name='task1')
     coll.add_task(self.task2, name='task2')
     coll.add_task(self.task3, name='task3')
     coll.add_task(self.task4, name='task4')
     coll.add_task(self.contextualized, name='contextualized')
     self.executor = Executor(collection=coll)
Beispiel #7
0
 def deduping_treats_different_calls_to_same_task_differently(self):
     body = Mock()
     t1 = Task(body)
     pre = [call(t1, 5), call(t1, 7), call(t1, 5)]
     t2 = Task(Mock(), pre=pre)
     c = Collection(t1=t1, t2=t2)
     e = Executor(collection=c)
     e.execute('t2')
     # Does not call the second t1(5)
     param_list = []
     for body_call in body.call_args_list:
         assert isinstance(body_call[0][0], Context)
         param_list.append(body_call[0][1])
     assert set(param_list) == {5, 7}
Beispiel #8
0
 def graph_treats_different_calls_to_same_task_differently(self):
     body = Mock()
     t1 = Task(body)
     dep = [call(t1, 5), call(t1, 7), call(t1, 5)]
     t2 = Task(Mock(), depends_on=dep)
     c = Collection(t1=t1, t2=t2)
     e = Executor(collection=c)
     e.execute('t2')
     # Does not call the second t1(5)
     param_list = []
     for body_call in body.call_args_list:
         ok_(isinstance(body_call[0][0], Context))
         param_list.append(body_call[0][1])
     ok_(set(param_list) == set((5, 7)))
Beispiel #9
0
 def setup(self):
     s = super(Executor_, self)
     s.setup()
     self.task1 = Task(Mock(return_value=7))
     self.task2 = Task(Mock(return_value=10), depends_on=[self.task1])
     self.task3 = Task(Mock(), requires=[self.task1])
     self.task4 = Task(Mock(return_value=15), afterwards=[self.task1])
     self.contextualized = Task(Mock())
     coll = Collection()
     coll.add_task(self.task1, name='task1')
     coll.add_task(self.task2, name='task2')
     coll.add_task(self.task3, name='task3')
     coll.add_task(self.task4, name='task4')
     coll.add_task(self.contextualized, name='contextualized')
     self.executor = Executor(collection=coll)
Beispiel #10
0
 def non_null_namespace_does_not_trigger_task_related_args(self):
     for arg in Program().task_args():
         expect(
             "--help",
             out=arg.name,
             program=Program(namespace=Collection(mytask=Task(Mock()))),
             test=assert_not_contains,
         )
Beispiel #11
0
 def default_tasks_called_when_no_tasks_specified(self):
     # NOTE: when no tasks AND no default, Program will print global
     # help. We just won't do anything at all, which is fine for now.
     task = Task(Mock('default-task'))
     coll = Collection()
     coll.add_task(task, name='mytask', default=True)
     executor = Executor(collection=coll)
     executor.execute()
     task.body.assert_called_with()
Beispiel #12
0
 def bundled_namespace_help_includes_subcommand_listing(self):
     t1, t2 = Task(Mock()), Task(Mock())
     coll = Collection(task1=t1, task2=t2)
     p = Program(namespace=coll)
     # Spot checks for expected bits, so we don't have to change
     # this every time core args change.
     for expected in (
             # Usage line changes somewhat
             "Usage: myapp [--core-opts] <subcommand> [--subcommand-opts] ...\n",  # noqa
             # Core options are still present
             "Core options:\n",
             "--echo",
             # Subcommands are listed
             "Subcommands:\n",
             "  task1",
             "  task2",
     ):
         stdout, _ = run("myapp --help", program=p, invoke=False)
         assert expected in stdout
Beispiel #13
0
 def default_tasks_called_when_no_tasks_specified(self):
     # NOTE: when no tasks AND no default, Program will print global
     # help. We just won't do anything at all, which is fine for now.
     task = Task(Mock('default-task'))
     coll = Collection()
     coll.add_task(task, name='mytask', default=True)
     executor = Executor(collection=coll)
     executor.execute()
     args = task.body.call_args[0]
     assert isinstance(args[0], Context)
     assert len(args) == 1
Beispiel #14
0
    def expand_calls(self, calls, apply_hosts=True):
        # Generate new call list with per-host variants & Connections inserted
        ret = []
        cli_hosts = []
        
        host_str = self.core[0].args.hosts.value
        if apply_hosts and host_str:
            cli_hosts = host_str.split(",")
        
        config_hosts = self.config.hosts
        
        for call in calls:
            if isinstance(call, Task):
                call = Call(task=call)
            # TODO: expand this to allow multiple types of execution plans,
            # pending outcome of invoke#461 (which, if flexible enough to
            # handle intersect of dependencies+parameterization, just becomes
            # 'honor that new feature of Invoke')
            # TODO: roles, other non-runtime host parameterizations, etc
            # Pre-tasks get added only once, not once per host.
            ret.extend(self.expand_calls(call.pre, apply_hosts=False))
            # Determine final desired host list based on CLI and task values
            # (with CLI, being closer to runtime, winning) and normalize to
            # Connection-init kwargs.
            call_hosts = getattr(call, "hosts", None)
            cxn_params = self.normalize_hosts(cli_hosts or config_hosts or call_hosts)
            # Main task, per host/connection
            for init_kwargs in cxn_params:
                ret.append(self.parameterize(call, init_kwargs))
            # Deal with lack of hosts list (acts same as `inv` in that case)
            # TODO: no tests for this branch?
            if not cxn_params:
                ret.append(call)
            # Post-tasks added once, not once per host.
            ret.extend(self.expand_calls(call.post, apply_hosts=False))
        # Add remainder as anonymous task
        if self.core.remainder:
            # TODO: this will need to change once there are more options for
            # setting host lists besides "-H or 100% within-task"
            if not cli_hosts:
                raise NothingToDo(
                    "Was told to run a command, but not given any hosts to run it on!"  # noqa
                )

            def anonymous(c):
                c.run(self.core.remainder)

            anon = Call(Task(body=anonymous))
            # TODO: see above TODOs about non-parameterized setups, roles etc
            # TODO: will likely need to refactor that logic some more so it can
            # be used both there and here.
            for init_kwargs in self.normalize_hosts(cli_hosts):
                ret.append(self.parameterize(anon, init_kwargs))
        return ret
Beispiel #15
0
 def call_objs_play_well_with_context_args(self):
     # Setup
     dep_body, followup_body = Mock(), Mock()
     t1 = Task(dep_body)
     t2 = Task(followup_body)
     t3 = Task(Mock(),
         depends_on=[call(t1, 5, foo='bar')],
         afterwards=[call(t2, 7, biz='baz')],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute('t3')
     # Dependency asserts
     args, kwargs = dep_body.call_args
     eq_(kwargs, {'foo': 'bar'})
     assert isinstance(args[0], Context)
     eq_(args[1], 5)
     # Followup asserts
     args, kwargs = followup_body.call_args
     eq_(kwargs, {'biz': 'baz'})
     assert isinstance(args[0], Context)
     eq_(args[1], 7)
Beispiel #16
0
 def _call_objs(self):
     # Setup
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(
         Mock(),
         pre=[call(t1, 5, foo='bar')],
         post=[call(t2, 7, biz='baz')],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute('t3')
     # Pre-task asserts
     args, kwargs = pre_body.call_args
     assert kwargs == {'foo': 'bar'}
     assert isinstance(args[0], Context)
     assert args[1] == 5
     # Post-task asserts
     args, kwargs = post_body.call_args
     assert kwargs == {'biz': 'baz'}
     assert isinstance(args[0], Context)
     assert args[1] == 7
Beispiel #17
0
 def _call_objs(self):
     # Setup
     pre_body, post_body = Mock(), Mock()
     t1 = Task(pre_body)
     t2 = Task(post_body)
     t3 = Task(
         Mock(),
         pre=[call(t1, 5, foo="bar")],
         post=[call(t2, 7, biz="baz")],
     )
     c = Collection(t1=t1, t2=t2, t3=t3)
     e = Executor(collection=c)
     e.execute("t3")
     # Pre-task asserts
     args, kwargs = pre_body.call_args
     assert kwargs == {"foo": "bar"}
     assert isinstance(args[0], Context)
     assert args[1] == 5
     # Post-task asserts
     args, kwargs = post_body.call_args
     assert kwargs == {"biz": "baz"}
     assert isinstance(args[0], Context)
     assert args[1] == 7
Beispiel #18
0
    def expand_calls(self, calls, apply_hosts=True):
        # Generate new call list with per-host variants & Connections inserted
        ret = []
        # TODO: mesh well with Invoke list-type args helper (inv #132)
        hosts = []
        host_str = self.core[0].args.hosts.value
        if apply_hosts and host_str:
            hosts = host_str.split(",")
        for call in calls:
            if isinstance(call, Task):
                call = Call(task=call)
            # TODO: expand this to allow multiple types of execution plans,
            # pending outcome of invoke#461 (which, if flexible enough to
            # handle intersect of dependencies+parameterization, just becomes
            # 'honor that new feature of Invoke')
            # TODO: roles, other non-runtime host parameterizations, etc
            # Pre-tasks get added only once, not once per host.
            ret.extend(self.expand_calls(call.pre, apply_hosts=False))
            # Main task, per host
            for host in hosts:
                ret.append(self.parameterize(call, host))
            # Deal with lack of hosts arg (acts same as `inv` in that case)
            # TODO: no tests for this branch?
            if not hosts:
                ret.append(call)
            # Post-tasks added once, not once per host.
            ret.extend(self.expand_calls(call.post, apply_hosts=False))
        # Add remainder as anonymous task
        if self.core.remainder:
            # TODO: this will need to change once there are more options for
            # setting host lists besides "-H or 100% within-task"
            if not hosts:
                raise NothingToDo(
                    "Was told to run a command, but not given any hosts to run it on!"  # noqa
                )

            def anonymous(c):
                # TODO: how to make all our tests configure in_stream=False?
                c.run(self.core.remainder, in_stream=False)

            anon = Call(Task(body=anonymous))
            # TODO: see above TODOs about non-parameterized setups, roles etc
            # TODO: will likely need to refactor that logic some more so it can
            # be used both there and here.
            for host in hosts:
                ret.append(self.parameterize(anon, host))
        return ret
Beispiel #19
0
 def name_defaults_to_body_name(self):
     assert Task(_func).name == '_func'
Beispiel #20
0
 def non_null_namespace_does_not_trigger_task_related_args(self):
     for arg in Program().task_args():
         program = Program(namespace=Collection(mytask=Task(Mock())))
         stdout, _ = run("--help", program=program)
         assert arg.name not in stdout
Beispiel #21
0
 def setup(self):
     self.task = Task(Mock(__name__='mytask'))
Beispiel #22
0
 def can_override_name(self):
     eq_(Task(_func, name='foo').name, 'foo')
Beispiel #23
0
 def name_defaults_to_body_name(self):
     eq_(Task(_func).name, '_func')
Beispiel #24
0
 def has_default_flag(self):
     eq_(Task(_func).is_default, False)
Beispiel #25
0
 def equality_testing(self):
     t1 = Task(_func, name='foo')
     t2 = Task(_func, name='foo')
     eq_(t1, t2)
     t3 = Task(_func, name='bar')
     assert t1 != t3
Beispiel #26
0
 def has_useful_repr(self):
     i = repr(Task(_func))
     assert '_func' in i, "'func' not found in {0!r}".format(i)
     e = repr(Task(_func, name='funky'))
     assert 'funky' in e, "'funky' not found in {0!r}".format(e)
     assert '_func' not in e, "'_func' unexpectedly seen in {0!r}".format(e)
Beispiel #27
0
 def can_override_name(self):
     assert Task(_func, name="foo").name == "foo"
Beispiel #28
0
 def setup(self):
     self.task = Task(Mock(__name__="mytask"))
Beispiel #29
0
 def can_override_name(self):
     assert Task(_func, name='foo').name == 'foo'
Beispiel #30
0
 def has_default_flag(self):
     assert Task(_func).is_default is False