def test_sudo_prompt_kills_capturing(self): """ Sudo prompts shouldn't screw up output capturing """ cmd = "ls /simple" with hide('everything'): eq_(sudo(cmd), RESPONSES[cmd])
def test_get_relative_remote_dir_uses_home(self): """ get('relative/path') should use remote $HOME """ with hide('everything'): # Another if-it-doesn't-error-out-it-passed test; meh. eq_(get('.bashrc', self.path()), [self.path('.bashrc')])
def test_flat_alias(self): f = fabfile("flat_alias.py") with path_prefix(f): docs, funcs = load_fabfile(f) eq_(len(funcs), 2) ok_("foo" in funcs) ok_("foo_aliased" in funcs)
def test_reads_double_under_doc_from_callable(self): def foo(): pass foo.__doc__ = "Some random __doc__: %d" % random.randint(1000, 2000) task = WrappedCallableTask(foo) eq_(task.__doc__, foo.__doc__)
def _prompt_display(display_output): env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY output.output = display_output with password_response( (CLIENT_PRIVKEY_PASSPHRASE, PASSWORDS[env.user]), silent=False): sudo('oneliner') if display_output: expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': \n[%(prefix)s] out: sudo password: [%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: \n[%(prefix)s] out: result """ % { 'prefix': env.host_string, 'user': env.user } else: # Note lack of first sudo prompt (as it's autoresponded to) and of # course the actual result output. expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': \n[%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: """ % { 'prefix': env.host_string, 'user': env.user } eq_(expected[1:], sys.stdall.getvalue())
def test_nonword_character_in_username(self): """ normalize() will accept non-word characters in the username part """ eq_( normalize('*****@*****.**')[0], 'user-with-hyphens')
def test_prompt_appends_space(): """ prompt() appends a single space when no default is given """ s = "This is my prompt" prompt(s) eq_(sys.stdout.getvalue(), s + ' ')
def test_consecutive_sudos_should_not_have_blank_line(self): """ Consecutive sudo() calls should not incur a blank line in-between """ env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY with password_response((CLIENT_PRIVKEY_PASSPHRASE, PASSWORDS[USER]), silent=False): sudo('oneliner') sudo('twoliner') expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': \n[%(prefix)s] out: sudo password: [%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: \n[%(prefix)s] out: result [%(prefix)s] sudo: twoliner [%(prefix)s] out: sudo password: [%(prefix)s] out: result1 [%(prefix)s] out: result2 """ % { 'prefix': env.host_string, 'user': env.user } eq_(sys.stdall.getvalue(), expected[1:])
def test_silent_commands_should_not_have_blank_line(self): """ Silent commands should not generate an extra trailing blank line After the move to interactive I/O, it was noticed that while run/sudo commands which had non-empty stdout worked normally (consecutive such commands were totally adjacent), those with no stdout (i.e. silent commands like ``test`` or ``mkdir``) resulted in spurious blank lines after the "run:" line. This looks quite ugly in real world scripts. """ env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY with password_response(CLIENT_PRIVKEY_PASSPHRASE, silent=False): run('normal') run('silent') run('normal') with hide('everything'): run('normal') run('silent') expected = """ [%(prefix)s] run: normal [%(prefix)s] Login password for '%(user)s': \n[%(prefix)s] out: foo [%(prefix)s] run: silent [%(prefix)s] run: normal [%(prefix)s] out: foo """ % { 'prefix': env.host_string, 'user': env.user } eq_(expected[1:], sys.stdall.getvalue())
def test_put_returns_list_of_remote_paths_with_stringio(self): """ put() should return a one-item iterable when uploading from a StringIO """ f = 'uploaded.txt' with hide('everything'): eq_(put(StringIO('contents'), f), [f])
def test_passes_all_regular_args_to_run(self): def foo(*args): return args random_args = tuple( [random.randint(1000, 2000) for i in range(random.randint(1, 5))] ) task = WrappedCallableTask(foo) eq_(random_args, task(*random_args))
def test_escaped_task_arg_split(): """ Allow backslashes to escape the task argument separator character """ argstr = r"foo,bar\,biz\,baz,what comes after baz?" eq_(_escape_split(',', argstr), ['foo', 'bar,biz,baz', 'what comes after baz?'])
def test_should_return_dict_for_base_case(self): """ Non-network-related tasks should return a dict w/ special key """ def task(): return "foo" eq_(execute(task), {'<local-only>': 'foo'})
def test_multiline_docstring_indented_correctly(self): """ display_command() should properly indent docstr for old style task methods """ def mytask(arg1): """ This is a multi line docstring. For reals. """ try: with patched_context(fabric.state, 'commands', {'mytask': mytask}): display_command('mytask') except SystemExit: # ugh pass eq_( sys.stdout.getvalue(), """Displaying detailed information for task 'mytask': This is a multi line docstring. For reals. Arguments: arg1 """ )
def test_shell_wrap_escapes_command_if_shell_is_true(): """ _shell_wrap() escapes given command if shell=True """ cmd = "cd \"Application Support\"" eq_(_shell_wrap(cmd, shell_escape=True, shell=True), '%s "%s"' % (env.shell, _shell_escape(cmd)))
def test_consecutive_sudos_should_not_have_blank_line(self): """ Consecutive sudo() calls should not incur a blank line in-between """ env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY with password_response( (CLIENT_PRIVKEY_PASSPHRASE, PASSWORDS[USER]), silent=False ): sudo('oneliner') sudo('twoliner') expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': [%(prefix)s] out: sudo password: [%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: [%(prefix)s] out: result [%(prefix)s] sudo: twoliner [%(prefix)s] out: sudo password: [%(prefix)s] out: result1 [%(prefix)s] out: result2 """ % {'prefix': env.host_string, 'user': env.user} eq_(sys.stdall.getvalue(), expected[1:])
def test_silent_commands_should_not_have_blank_line(self): """ Silent commands should not generate an extra trailing blank line After the move to interactive I/O, it was noticed that while run/sudo commands which had non-empty stdout worked normally (consecutive such commands were totally adjacent), those with no stdout (i.e. silent commands like ``test`` or ``mkdir``) resulted in spurious blank lines after the "run:" line. This looks quite ugly in real world scripts. """ env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY with password_response(CLIENT_PRIVKEY_PASSPHRASE, silent=False): run('normal') run('silent') run('normal') with hide('everything'): run('normal') run('silent') expected = """ [%(prefix)s] run: normal [%(prefix)s] Login password for '%(user)s': [%(prefix)s] out: foo [%(prefix)s] run: silent [%(prefix)s] run: normal [%(prefix)s] out: foo """ % {'prefix': env.host_string, 'user': env.user} eq_(expected[1:], sys.stdall.getvalue())
def _prompt_display(display_output): env.password = None env.no_agent = env.no_keys = True env.key_filename = CLIENT_PRIVKEY output.output = display_output with password_response( (CLIENT_PRIVKEY_PASSPHRASE, PASSWORDS[env.user]), silent=False ): sudo('oneliner') if display_output: expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': [%(prefix)s] out: sudo password: [%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: [%(prefix)s] out: result """ % {'prefix': env.host_string, 'user': env.user} else: # Note lack of first sudo prompt (as it's autoresponded to) and of # course the actual result output. expected = """ [%(prefix)s] sudo: oneliner [%(prefix)s] Login password for '%(user)s': [%(prefix)s] out: Sorry, try again. [%(prefix)s] out: sudo password: """ % { 'prefix': env.host_string, 'user': env.user } eq_(expected[1:], sys.stdall.getvalue())
def test_at_symbol_in_username(self): """ normalize() should allow '@' in usernames (i.e. last '@' is split char) """ parts = normalize('[email protected]@www.example.com') eq_(parts[0], '*****@*****.**') eq_(parts[1], 'www.example.com')
def dict_contains(superset, subset): """ Assert that all key/val pairs in dict 'subset' also exist in 'superset' """ for key, value in list(subset.items()): ok_(key in superset) eq_(superset[key], value)
def test_name_is_the_name_of_the_wrapped_callable(self): def foo(): pass foo.__name__ = "random_name_%d" % random.randint(1000, 2000) task = WrappedCallableTask(foo) eq_(task.name, foo.__name__)
def dict_contains(superset, subset): """ Assert that all key/val pairs in dict 'subset' also exist in 'superset' """ for key, value in subset.iteritems(): ok_(key in superset) eq_(superset[key], value)
def test_just_ssh_config(self): """ No env.key_filename + valid ssh_config = ssh value """ with settings(use_ssh_config=True, ssh_config_path=support("ssh_config")): for val in ["", []]: with settings(key_filename=val): eq_(key_filenames(), ["foobar.pub"])
def test_nonword_character_in_username(self): """ normalize() will accept non-word characters in the username part """ eq_( normalize('*****@*****.**')[0], 'user-with-hyphens' )
def test_get_file_from_relative_path_with_spaces(self): """ get('file') should work when the remote path contains spaces """ # from nose.tools import set_trace; set_trace() with hide('everything'): with cd('/base/dir with spaces'): eq_(get('file', self.path()), [self.path('file')])
def test_parallel(self): """ Want to do a simple call and respond """ env.pool_size = 10 cmd = "ls /simple" with hide('everything'): eq_(run(cmd), RESPONSES[cmd])
def test_normalization_without_port(self): """ normalize() and join_host_strings() omit port if omit_port given """ eq_( join_host_strings(*normalize('user@localhost', omit_port=True)), 'user@localhost' )
def test_passes_all_keyword_args_to_run(self): def foo(**kwargs): return kwargs random_kwargs = {} for i in range(random.randint(1, 5)): random_key = ("foo", "bar", "baz", "foobar", "barfoo")[i] random_kwargs[random_key] = random.randint(1000, 2000) task = WrappedCallableTask(foo) eq_(random_kwargs, task(**random_kwargs))
def test_get_should_not_use_windows_slashes_in_remote_paths(self): """ sftp.glob() should always use Unix-style slashes. """ with hide('everything'): path = "/tree/file1.txt" sftp = SFTP(env.host_string) eq_(sftp.glob(path), [path])
def test_nested_alias(self): f = fabfile("nested_alias.py") with path_prefix(f): docs, funcs = load_fabfile(f) ok_("nested" in funcs) eq_(len(funcs["nested"]), 2) ok_("foo" in funcs["nested"]) ok_("foo_aliased" in funcs["nested"])
def test_prompt_with_default(): """ prompt() appends given default value plus one space on either side """ s = "This is my prompt" d = "default!" prompt(s, default=d) eq_(sys.stdout.getvalue(), "%s [%s] " % (s, d))
def test_sudo_prefix_with_group(): """ _sudo_prefix() returns prefix plus -g flag for nonempty group """ eq_( _sudo_prefix(user=None, group="foo"), "%s -g \"foo\" " % (env.sudo_prefix % env) )
def test_shell_wrap_does_not_escape_command_if_shell_is_true_and_shell_escape_is_false( ): """ _shell_wrap() does no escaping if shell=True and shell_escape=False """ cmd = "cd \"Application Support\"" eq_(_shell_wrap(cmd, shell_escape=False, shell=True), '%s "%s"' % (env.shell, cmd))
def test_sudo_prefix_with_user(): """ _sudo_prefix() returns prefix plus -u flag for nonempty user """ eq_( _sudo_prefix(user="******", group=None), "%s -u \"foo\" " % (env.sudo_prefix % env) )
def test_dispatches_to_wrapped_callable_on_run(self): random_value = "some random value %d" % random.randint(1000, 2000) def foo(): return random_value task = WrappedCallableTask(foo) eq_(random_value, task())
def test_sudo_prefix_with_user_and_group(): """ _sudo_prefix() returns prefix plus -u and -g for nonempty user and group """ eq_( _sudo_prefix(user="******", group="bar"), "%s -u \"foo\" -g \"bar\" " % (env.sudo_prefix % env) )
def test_calling_the_object_is_the_same_as_run(self): random_return = random.randint(1000, 2000) def foo(): return random_return task = WrappedCallableTask(foo) eq_(task(), task.run())
def test_put_return_value_failed_attribute(self): """ put()'s return value should indicate any paths which failed to upload. """ with settings(hide('everything'), warn_only=True): f = StringIO('contents') retval = put(f, '/nonexistent/directory/structure') eq_(["<StringIO>"], retval.failed) assert not retval.succeeded
def test_local_false_global_true(self): """ combine_stderr: False kwarg => overrides global True value """ output.everything = False env.combine_stderr = True r = run("both_streams", combine_stderr=False) eq_("stdout", r.stdout) eq_("stderr", r.stderr)
def test_get_return_value_failed_attribute(self): """ get()'s return value should indicate any paths which failed to download. """ with settings(hide('everything'), warn_only=True): retval = get('/doesnt/exist', self.path()) eq_(['/doesnt/exist'], retval.failed) assert not retval.succeeded
def test_get_returns_list_of_local_paths(self): """ get() should return an iterable of the local files it created. """ d = self.path() with hide('everything'): retval = get('tree', d) files = ['file1.txt', 'file2.txt', 'subfolder/file3.txt'] eq_(map(lambda x: os.path.join(d, 'tree', x), files), retval)
def test_get_should_accept_file_like_objects(self): """ get()'s local_path arg should take file-like objects too """ fake_file = StringIO() target = '/file.txt' with hide('everything'): get(target, fake_file) eq_(fake_file.getvalue(), FILES[target])