def test_insert_line(): with abort('insert_line: must be defined \'before\' or \'after\' argument'): edit_text("text", insert_line("line")) with abort('insert_line: unknown insert_type \'%s\'' % 'xxx'): edit_text("text", insert_line("line", xxx="text")) with abort('insert_line: already defined insert_type \'%s\', unexpected \'%s\'' % ('after', 'before')): edit_text("text", insert_line("line", after="text", before="text")) assert edit_text("text", insert_line("line", before="text")) == "line\ntext" assert edit_text("text\n", insert_line("line", before="text")) == "line\ntext\n" assert edit_text("text", insert_line("line", after="text")) == "text\nline" assert edit_text("text\n", insert_line("line", after="text")) == "text\nline\n" with abort(r'insert_line: anchor pattern \'.*\' not found'): edit_text("test", insert_line("line", after="text")) with abort(r'insert_line: anchor pattern \'.*\' found 2 times, must be only one'): edit_text("test\ntest\n", insert_line("line", after="test"))
def test_read_config_explicit_relative_config_name_not_exists( tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_filename = tmpdir.join("stage.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) with abort('read_config: config \'%s\' not exists' % str(config_filename)): read_config("stage.yaml")
def test_rsync(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) monkeypatch.setitem(env, "host_string", '11.11.11.11') with abort('rsync: files dir \'.*\' not exists in file .* line .*'): rsync("file", "/path/to/remote/file") tmpdir.mkdir("files") with abort('rsync: local path \'.*\' not exists in file .* line .*'): rsync("file", "/path/to/remote/file") local_file = tmpdir.join("files").join("file") local_file.write("content") with abort( 'rsync: remote path \'.*\' must be absolute in file .* line .*'): rsync("file", "remote-file-name") local_state = { r'rsync -aH --stats --force --timeout=600 -e \'ssh -p 2222\' .* -- .* \[email protected]:/path/to/changed': { 'stdout': 'Total transferred file size: 12345 bytes', 'failed': False }, r'rsync -aH --stats --force --timeout=600 -e \'ssh -p 22\' .* -- .* \[email protected]:/path/to/not-changed': { 'stdout': 'Total transferred file size: 0 bytes', 'failed': False }, r'rsync -aH --stats --force --timeout=600 -e \'ssh -p 7723\' .* -- .* \w+@\[fdff::ffff:ffff:ffff\]:/path/to/not-changed-ipv6': { 'stdout': 'Total transferred file size: 0 bytes', 'failed': False }, r'rsync -aH --stats --force --timeout=600 -e \'ssh -p 22 -i /path/to/id_rsa\' .* -- .* \[email protected]:/path/to/not-changed-with-ssh-key': { 'stdout': 'Total transferred file size: 0 bytes', 'failed': False }, } mock_local = mock_local_factory(local_state) monkeypatch.setattr(fabrix.ioutil, 'local', mock_local) monkeypatch.setitem(env, "host_string", '11.11.11.11:2222') assert rsync("file", "/path/to/changed") is True monkeypatch.setitem(env, "host_string", '11.11.11.11') assert rsync("file", "/path/to/not-changed") is False monkeypatch.setitem(env, "host_string", 'root@[fdff::ffff:ffff:ffff]:7723') assert rsync("file", "/path/to/not-changed-ipv6") is False with settings(key_filename="/path/to/id_rsa"): monkeypatch.setitem(env, "host_string", '11.11.11.11') assert rsync("file", "/path/to/not-changed-with-ssh-key") is False
def test__parse_packages(): with abort( '.*: unexpected object \'.*\' in list of packages in file .* line .*' ): _parse_packages(0, False, None) with abort('.*: unexpected empty list of packages in file .* line .*'): _parse_packages(0, False, [[], [[], [[]]]], []) assert _parse_packages( 0, False, """ A B C """, [set("D"), list("E")]) == ['A', 'B', 'C', 'D', 'E']
def test_render_template_failed_if_template_file_not_exists( tmpdir, monkeypatch): fabfile_dir = tmpdir templates_dir = fabfile_dir.mkdir("templates") template_file = templates_dir.join("hello.txt.j2") monkeypatch.setitem(env, "real_fabfile", str(fabfile_dir.join("fabfile.py"))) with abort('render_template: template \'%s\' not exists' % template_file): render_template("hello.txt.j2", name="World")
def test_roles_must_not_be_empty(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: [] """) with abort('read_config: roles must not be empty'): read_config()
def test_systemctl_edit(monkeypatch): with abort('systemctl_edit: override must be string in file .* line .*'): systemctl_edit("mysqld", ['some', 'text']) with abort('systemctl_edit: invalid unit name \'.*\' in file .* line .*'): systemctl_edit('mysql/d', "") monkeypatch.setattr(fabrix.system, 'create_directory', lambda x: True) monkeypatch.setattr(fabrix.system, 'write_file', lambda x, y: True) assert systemctl_edit('mysqld', "[Service]\nLimitNOFILE = 65535") is True assert systemctl_edit('mysqld.service', "[Service]\nLimitNOFILE = 65535") is True monkeypatch.setattr(fabrix.system, 'remove_file', lambda x: True) monkeypatch.setattr(fabrix.system, 'remove_directory', lambda x: True) assert systemctl_edit('mysqld', "") is True monkeypatch.setattr(fabrix.system, 'remove_file', lambda x: True) monkeypatch.setattr(fabrix.system, 'remove_directory', lambda x: True) assert systemctl_edit('mysqld', None) is True monkeypatch.setattr(fabrix.system, 'remove_file', lambda x: False) monkeypatch.setattr(fabrix.system, 'remove_directory', lambda x: False) assert systemctl_edit('mysqld', None) is False
def test_hosts_is_not_list(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: host:172.22.22.99 """) with abort('read_config: hosts must be list type'): read_config()
def test_roles_hosts_required(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: test """) with abort('read_config: role \'%s\' hosts required' % 'test'): read_config()
def test_render(): assert render("Hello, {{ name }}!", name="World") == "Hello, World!\n" assert render(""" Hello, {{ name }}! """, name="World") == "Hello, World!\n" with abort("render: 'zzz' is undefined in file .* line .*"): render("Hello, {{ zzz.name }}!\n")
def test_roles_is_not_list(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: role: test """) with abort('read_config: roles must be list type'): read_config()
def test_hosts_must_be_list_of_strings(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - host: 172.22.22.99 """) with abort('read_config: hosts must be list of strings'): read_config()
def test_read_local_file(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) temp_file = tmpdir.join("file.txt") temp_file.write("text") assert read_local_file(str(temp_file)) == "text" non_existent_file = tmpdir.join("non_existent_file") with abort(r'\[Errno 2\] No such file or directory:.*'): read_local_file(str(non_existent_file)) assert read_local_file(str(non_existent_file), False) is None
def test_hosts_host_cant_be_empty_string(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - "" """) with abort('read_config: hosts host can\'t be empty string'): read_config()
def test_roles_hosts_must_be_list_type(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: test hosts: 10.10.10.10 """) with abort('read_config: role \'%s\' hosts must be list type' % 'test'): read_config()
def test_copy_file(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) with abort('copy_file: files dir \'.*\' not exists in file .* line .*'): copy_file("file", "/path/to/remote/file") tmpdir.mkdir("files") with abort('copy_file: file \'.*\' not exists in file .* line .*'): copy_file("file", "/path/to/remote/file") local_file = tmpdir.join("files").join("file") local_file.write("content") monkeypatch.setattr(fabrix.ioutil, 'read_file', lambda remote_filename, abort_on_error: "old content") with abort('remote filename must be absolute, ".*" given'): copy_file("file", "remote-file-name") monkeypatch.setattr(fabrix.ioutil, 'write_file', lambda remote_filename, new_content: True) assert copy_file("file", "/path/to/remote/file") is True monkeypatch.setattr(fabrix.ioutil, 'write_file', lambda remote_filename, new_content: False) assert copy_file("file", "/path/to/remote/file") is False
def test_hosts_and_roles_not_defined(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" defaults: hosts_defined: False roles_defined: False """) with abort('read_config: hosts or roles must be defined in config'): read_config()
def test_roles_role_required(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - hosts: - 11.11.11.11 """) with abort('read_config: roles role required'): read_config()
def test_role_hosts_must_be_list_of_strings(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: test hosts: - ['10.10.10.10', '11.11.11.11'] """) with abort('read_config: role \'%s\' hosts must be list of strings' % 'test'): read_config()
def test_roles_hosts_host_is_none(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: test hosts: - """) with abort('read_config: role \'%s\' hosts host can\'t be empty string' % 'test'): read_config()
def test_host_already_defined(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - 11.11.11.11 - 10.10.10.10 - 11.11.11.11 """) with abort('read_config: host \'%s\' already defined in hosts list' % '11.11.11.11'): read_config()
def test_roles_role_must_be_string_type(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: ['test'] - hosts: - 11.11.11.11 """) with abort('read_config: roles role must be string type'): read_config()
def test_roles_role_is_none(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: hosts: - 11.11.11.11 """) with abort('read_config: roles role can\'t be empty string'): read_config()
def test__atomic_write_local_file(tmpdir): with abort('local filename must be absolute, "%s" given' % "file.txt"): _atomic_write_local_file("file.txt", "text") regular_file = tmpdir.join("regular-file") regular_file.write("text") symlink = tmpdir.join("symlink") symlink.mksymlinkto(regular_file) with abort('local filename must be regular file, "%s" given' % str(symlink)): _atomic_write_local_file(str(symlink), "text") directory = tmpdir.join("directory") directory.mkdir() with abort('local filename must be regular file, "%s" given' % str(directory)): _atomic_write_local_file(str(directory), "text") regular_file = tmpdir.join("regular-file") regular_file.write("text") hardlink = tmpdir.join("hardlink") hardlink.mklinkto(regular_file) with abort('file "%s" has %d hardlinks, it can\'t be atomically written' % (regular_file, 2)): _atomic_write_local_file(str(regular_file), "text")
def test_host_vars_host_not_defined_in_hosts_list(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - 10.10.10.10 host_vars: - host: 11.11.11.11 vars: {} """) with abort('read_config: host_vars host \'%s\' not defined in hosts list' % '11.11.11.11'): read_config()
def test_error_parsing_yaml(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" roles: - role: test hosts: - 11.11.11.11 host_vars: [] """) with abort('read_config: error parsing config.*'): read_config()
def test_strip_test(): with abort('strip_text: string expected in file .* line .*'): strip_text(list('a')) assert strip_text('') == '' assert strip_text(None) == '' assert strip_text('text') == 'text\n' assert strip_text(""" some text other text """) == "some text\n\nother text\n"
def test_unexpected_entry(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - 11.11.11.11 host_vars: - host: 11.11.11.11 vars: {} lcal_vars: {foo: bar} """) with abort('read_config: unexpected config entry:\n\n%s' % 'lcal_vars: {foo: bar}'): read_config()
def test_local_vars_must_be_list_type(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - 11.11.11.11 host_vars: - host: 11.11.11.11 vars: {} local_vars: [] """) with abort('read_config: local_vars must be dictionary type'): read_config()
def test_hosts_and_roles_defined(tmpdir, monkeypatch): fabfile = tmpdir.join("fabfile.py") config_file = tmpdir.join("fabfile.yaml") monkeypatch.setitem(env, "real_fabfile", str(fabfile)) config_file.write(""" hosts: - 172.22.22.99 roles: - role: test hosts: - 11.11.11.11 """) with abort('read_config: hosts and roles can\'t be simultaneously defined in config'): read_config()