Example #1
0
 def can_clone_into_a_subclass(self):
     orig = Call(self.task)
     class MyCall(Call):
         pass
     clone = orig.clone(into=MyCall)
     eq_(clone, orig)
     ok_(isinstance(clone, MyCall))
Example #2
0
        def can_clone_into_a_subclass(self):
            orig = Call(self.task)

            class MyCall(Call):
                pass

            clone = orig.clone(into=MyCall)
            assert clone == orig
            assert isinstance(clone, MyCall)
Example #3
0
        def can_clone_into_a_subclass(self):
            orig = Call(self.task)

            class MyCall(Call):
                pass

            clone = orig.clone(into=MyCall)
            assert clone == orig
            assert isinstance(clone, MyCall)
Example #4
0
        def can_clone_into_a_subclass(self):
            orig = Call(self.task)

            class MyCall(Call):
                pass

            clone = orig.clone(into=MyCall)
            eq_(clone, orig)
            ok_(isinstance(clone, MyCall))
Example #5
0
        def can_be_given_extra_kwargs_to_clone_with(self):
            orig = Call(self.task)

            class MyCall(Call):
                def __init__(self, *args, **kwargs):
                    self.hooray = kwargs.pop("hooray")
                    super(MyCall, self).__init__(*args, **kwargs)

            clone = orig.clone(into=MyCall, with_={"hooray": "woo"})
            assert clone.hooray == "woo"
Example #6
0
        def can_be_given_extra_kwargs_to_clone_with(self):
            orig = Call(self.task)

            class MyCall(Call):
                def __init__(self, *args, **kwargs):
                    self.hooray = kwargs.pop("hooray")
                    super(MyCall, self).__init__(*args, **kwargs)

            clone = orig.clone(into=MyCall, with_={"hooray": "woo"})
            assert clone.hooray == "woo"
Example #7
0
 def expand_calls(self, calls, parent=None):
     ret = []
     for call in calls:
         if isinstance(call, Task):
             call = Call(task=call)
         call.parent = parent
         ret.extend(self.expand_calls(call.pre, call))
         ret.append(call)
         ret.extend(self.expand_calls(call.post, call))
     return ret
Example #8
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
Example #9
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
Example #10
0
 def includes_args_and_kwargs(self):
     call = Call(
         self.task,
         args=("posarg1", "posarg2"),
         # Single-key dict to avoid dict ordering issues
         kwargs={"kwarg1": "val1"},
     )
     expected = "<Call 'mytask', args: ('posarg1', 'posarg2'), kwargs: {'kwarg1': 'val1'}>"  # noqa
     assert str(call) == expected
Example #11
0
 def always_generates_ConnectionCall_with_host_attr(self):
     task, executor = _get_executor(hosts_flag="host1,host2,host3")
     calls = executor.expand_calls(calls=[Call(task)])
     assert len(calls) == 3
     assert all(isinstance(x, ConnectionCall) for x in calls)
     assert [x.init_kwargs["host"] for x in calls] == [
         "host1",
         "host2",
         "host3",
     ]
Example #12
0
 def includes_args_and_kwargs(self):
     call = Call(
         self.task,
         args=('posarg1', 'posarg2'),
         # Single-key dict to avoid dict ordering issues
         kwargs={'kwarg1': 'val1'},
     )
     assert str(
         call
     ) == "<Call 'mytask', args: ('posarg1', 'posarg2'), kwargs: {'kwarg1': 'val1'}>"  # noqa
Example #13
0
 def defaults_to_empty_dict(self):
     eq_(Call(_).kwargs, dict())
Example #14
0
 def may_be_given(self):
     eq_(Call(_, args=(1, 2, 3)).args, (1, 2, 3))
Example #15
0
 def defaults_to_empty_tuple(self):
     eq_(Call(_).args, tuple())
Example #16
0
 def may_be_given(self):
     eq_(Call(_, called_as='foo').called_as, 'foo')
Example #17
0
 def defaults_to_empty_tuple(self):
     assert Call(_).args == tuple()
Example #18
0
 def returns_new_but_equivalent_object(self):
     orig = Call(self.task)
     clone = orig.clone()
     ok_(clone is not orig)
     ok_(clone == orig)
Example #19
0
 def requires_config_argument(self):
     Call(_).make_context()
Example #20
0
 def includes_aka_if_explicit_name_given(self):
     call = Call(self.task, called_as='notmytask')
     eq_(str(
         call
     ), "<Call 'mytask' (called as: 'notmytask'), args: (), kwargs: {}>"
         )  # noqa
Example #21
0
 def may_be_given(self):
     eq_(Call(_, kwargs={'foo': 'bar'}).kwargs, {'foo': 'bar'})
Example #22
0
 def requires_config_argument(self):
     with raises(TypeError):
         Call(_).make_context()
Example #23
0
 def includes_task_name(self):
     call = Call(self.task)
     assert str(call) == "<Call 'mytask', args: (), kwargs: {}>"
Example #24
0
 def may_be_given(self):
     assert Call(_, kwargs={'foo': 'bar'}).kwargs == {'foo': 'bar'}
Example #25
0
 def defaults_to_empty_dict(self):
     assert Call(_).kwargs == dict()
Example #26
0
 def may_be_given(self):
     assert Call(_, args=(1, 2, 3)).args == (1, 2, 3)
Example #27
0
 def includes_task_name(self):
     call = Call(self.task)
     eq_(str(call), "<Call 'mytask', args: (), kwargs: {}>")
Example #28
0
 def is_required(self):
     Call()
Example #29
0
 def skips_aka_if_explicit_name_same_as_task_name(self):
     call = Call(self.task, called_as='mytask')
     eq_(str(call), "<Call 'mytask', args: (), kwargs: {}>")
Example #30
0
 def is_first_posarg(self):
     ok_(Call(_).task is _)
Example #31
0
 def creates_a_new_Context_from_given_config(self):
     conf = Config(defaults={'foo': 'bar'})
     ctx = Call(_).make_context(conf)
     ok_(isinstance(ctx, Context))
     eq_(ctx.foo, 'bar')
Example #32
0
 def defaults_to_None(self):
     eq_(Call(_).called_as, None)
Example #33
0
 def creates_a_new_Context_from_given_config(self):
     conf = Config(defaults={'foo': 'bar'})
     c = Call(_).make_context(conf)
     assert isinstance(c, Context)
     assert c.foo == 'bar'
Example #34
0
 def returns_new_but_equivalent_object(self):
     orig = Call(self.task)
     clone = orig.clone()
     ok_(clone is not orig)
     ok_(clone == orig)