def test_should_pass_through_args_kwargs(self): """ should pass in any additional args, kwargs to the given task. """ task = (Fake(callable=True, expect_call=True).with_args('foo', biz='baz')) execute(task, 'foo', biz='baz')
def test_should_look_up_task_name(self): """ should also be able to handle task name strings """ name = 'task1' commands = {name: Fake(callable=True, expect_call=True)} with patched_context(fabric.state, 'commands', commands): execute(name)
def test_should_not_abort_if_task_name_not_found_with_skip(self): """ should not abort if given an invalid task name and skip_unknown_tasks in env """ env.skip_unknown_tasks = True execute('thisisnotavalidtaskname') del env['skip_unknown_tasks']
def test_should_pass_through_args_kwargs(self): """ should pass in any additional args, kwargs to the given task. """ task = ( Fake(callable=True, expect_call=True) .with_args('foo', biz='baz') ) execute(task, 'foo', biz='baz')
def test_should_work_with_Task_subclasses(self): """ should work for Task subclasses, not just WrappedCallableTask """ class MyTask(Task): name = "mytask" run = Fake(callable=True, expect_call=True) mytask = MyTask() execute(mytask)
def test_should_not_print_executing_line_for_singletons(self): """ should not print "Executing" line for non-networked tasks """ def task(): pass with settings(hosts=[]): # protect against really odd test bleed :( execute(task) self.assertEqual(sys.stdout.getvalue(), "")
def test_should_set_env_command_to_string_arg(self): """ should set env.command to any string arg, if given """ name = "foo" def command(): self.assert_(env.command, name) task = Fake(callable=True, expect_call=True).calls(command) with patched_context(fabric.state, 'commands', {name: task}): execute(name)
def test_should_set_env_command_to_name_attr(self): """ should set env.command to TaskSubclass.name if possible """ name = "foo" def command(): self.assertEqual(env.command, name) task = (Fake(callable=True, expect_call=True).has_attr(name=name).calls(command)) execute(task)
def test_should_honor_hosts_decorator(self): """ should honor @hosts on passed-in task objects """ # Make two full copies of a host list hostlist = ['a', 'b', 'c'] @hosts(*hostlist[:]) def task(): self.assertEqual(env.host_string, hostlist.pop(0)) with hide('running'): execute(task)
def test_should_honor_roles_decorator(self): """ should honor @roles on passed-in task objects """ # Make two full copies of a host list roledefs = {'role1': ['a', 'b', 'c']} role_copy = roledefs['role1'][:] @roles('role1') def task(): self.assertEqual(env.host_string, role_copy.pop(0)) with settings(hide('running'), roledefs=roledefs): execute(task)
def test_should_print_executing_line_per_host(self): """ should print "Executing" line once per host """ state.output.running = True def task(): pass execute(task, hosts=['host1', 'host2']) self.assertEqual(sys.stdout.getvalue(), """[host1] Executing task 'task' [host2] Executing task 'task' """)
def test_abort_in_serial_should_not_raise_error(self): """ base exception should call error """ fabric.state.env.warn_only = False @serial @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): fabric.utils.abort('aborting') with hide('everything'): execute(task)
def test_should_handle_name_of_Task_object(self): """ handle corner case of Task object referrred to by name """ name = 'task2' class MyTask(Task): run = Fake(callable=True, expect_call=True) mytask = MyTask() mytask.name = name commands = {name: mytask} with patched_context(fabric.state, 'commands', commands): execute(name)
def test_should_print_executing_line_per_host(self): """ should print "Executing" line once per host """ state.output.running = True def task(): pass execute(task, hosts=['host1', 'host2']) self.assertEqual( sys.stdout.getvalue(), """[host1] Executing task 'task' [host2] Executing task 'task' """)
def test_should_honor_roles_decorator(self): """ should honor @roles on passed-in task objects """ # Make two full copies of a host list roledefs = {'role1': ['a', 'b', 'c'], 'role2': ['d', 'e']} role_copy = roledefs['role1'][:] @roles('role1') def task(): self.assertEqual(env.host_string, role_copy.pop(0)) with settings(hide('running'), roledefs=roledefs): execute(task)
def test_should_set_env_command_to_name_attr(self): """ should set env.command to TaskSubclass.name if possible """ name = "foo" def command(): self.assertEqual(env.command, name) task = ( Fake(callable=True, expect_call=True) .has_attr(name=name) .calls(command) ) execute(task)
def test_should_honor_hosts_kwarg(self): """ should use hosts kwarg to set run list """ # Make two full copies of a host list hostlist = ['a', 'b', 'c'] hosts = hostlist[:] # Side-effect which asserts the value of env.host_string when it runs def host_string(): self.assertEqual(env.host_string, hostlist.pop(0)) task = Fake(callable=True, expect_call=True).calls(host_string) with hide('everything'): execute(task, hosts=hosts)
def test_should_return_dict_for_base_case(self): """ Non-network-related tasks should return a dict w/ special key """ def task(): return "foo" self.assertEqual(execute(task), {'<local-only>': 'foo'})
def test_should_set_all_hosts(self): """ should set env.all_hosts to its derived host list """ hosts = ['a', 'b'] roledefs = {'r1': ['c', 'd']} roles = ['r1'] exclude_hosts = ['a'] def command(): self.assertEqual(set(env.all_hosts), set(['b', 'c', 'd'])) task = Fake(callable=True, expect_call=True).calls(command) with settings(hide('everything'), roledefs=roledefs): execute( task, hosts=hosts, roles=roles, exclude_hosts=exclude_hosts )
def test_should_preserve_None_for_non_returning_tasks( self, log_mock, run_mock): """ Tasks which don't return anything should still show up in the dict """ def local_task(): pass def remote_task(): with hide('everything'): run_mock.return_value = 'hello' fabric.api.run('a command') self.assertEqual(execute(local_task), {'<local-only>': None}) with hide('everything'): self.assertEqual(execute(remote_task, hosts=['host']), {'host': None})
def test_parallel_network_error(self, error_mock): """ network error should call error """ network_error = NetworkError('Network message') fabric.state.env.warn_only = False @parallel @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): raise network_error with hide('everything'): execute(task) error_mock.assert_called_with('Network message', exception=network_error.wrapped, func=fabric.utils.abort)
def test_should_preserve_None_for_non_returning_tasks(self, log_mock, run_mock): """ Tasks which don't return anything should still show up in the dict """ def local_task(): pass def remote_task(): with hide('everything'): run_mock.return_value = 'hello' fabric.api.run('a command') self.assertEqual(execute(local_task), {'<local-only>': None}) with hide('everything'): self.assertEqual( execute(remote_task, hosts=['host']), {'host': None} )
def test_should_set_all_hosts(self): """ should set env.all_hosts to its derived host list """ hosts = ['a', 'b'] roledefs = {'r1': ['c', 'd']} roles = ['r1'] exclude_hosts = ['a'] def command(): self.assertEqual(set(env.all_hosts), set(['b', 'c', 'd'])) task = Fake(callable=True, expect_call=True).calls(command) with settings(hide('everything'), roledefs=roledefs): execute(task, hosts=hosts, roles=roles, exclude_hosts=exclude_hosts)
def test_base_exception_error(self, error_mock): """ base exception should call error """ value_error = ValueError('error message') fabric.state.env.warn_only = True @parallel @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): raise value_error with hide('everything'): execute(task) # self.assertTrue(error_mock.is_called) args = error_mock.call_args self.assertEqual(args[0], ('error message',)) self.assertEqual(type(args[1]['exception']), type(value_error)) self.assertEqual(args[1]['exception'].args, value_error.args)
def test_should_use_sentinel_for_tasks_that_errored(self): """ Tasks which errored but didn't abort should contain an eg NetworkError """ def task(): fabric.api.run("whoops") host_string = 'localhost:1234' with settings(hide('everything'), skip_bad_hosts=True): retval = execute(task, hosts=[host_string]) assert isinstance(retval[host_string], NetworkError)
def test_base_exception_error(self, error_mock): """ base exception should call error """ value_error = ValueError('error message') fabric.state.env.warn_only = True @parallel @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): raise value_error with hide('everything'): execute(task) # self.assertTrue(error_mock.is_called) args = error_mock.call_args self.assertEqual(args[0], ('error message', )) self.assertEqual(type(args[1]['exception']), type(value_error)) self.assertEqual(args[1]['exception'].args, value_error.args)
def test_parallel_return_values(self): """ Parallel mode should still return values as in serial mode """ @parallel @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): return env.host_string.split(':')[1] with hide('everything'): retval = execute(task) self.assertEqual(retval, {'127.0.0.1:2200': '2200', '127.0.0.1:2201': '2201'})
def test_should_return_dict_for_serial_use_case(self): """ Networked but serial tasks should return per-host-string dict """ ports = [2200, 2201] hosts = map(lambda x: '127.0.0.1:%s' % x, ports) @serial def task(): return "foo" with hide('everything'): self.assertEqual(execute(task, hosts=hosts), { '127.0.0.1:2200': 'foo', '127.0.0.1:2201': 'foo' })
def test_parallel_return_values(self): """ Parallel mode should still return values as in serial mode """ @parallel @hosts('127.0.0.1:2200', '127.0.0.1:2201') def task(): return env.host_string.split(':')[1] with hide('everything'): retval = execute(task) self.assertEqual(retval, { '127.0.0.1:2200': '2200', '127.0.0.1:2201': '2201' })
def test_calls_task_function_objects(self): """ should execute the passed-in function object """ execute(Fake(callable=True, expect_call=True))