diff options
-rw-r--r-- | ipalib/plugins/automount.py | 4 | ||||
-rw-r--r-- | tests/test_xmlrpc/test_automount_plugin.py | 229 |
2 files changed, 224 insertions, 9 deletions
diff --git a/ipalib/plugins/automount.py b/ipalib/plugins/automount.py index ac9c9769f..dda14cc78 100644 --- a/ipalib/plugins/automount.py +++ b/ipalib/plugins/automount.py @@ -349,7 +349,7 @@ class automountlocation_tofiles(LDAPQuery): textui.print_plain(_('maps not connected to /etc/auto.master:')) for m in orphanmaps: textui.print_plain('---------------------------') - textui.print_plain('/etc/%s: ' % m['automountmapname']) + textui.print_plain('/etc/%s:' % m['automountmapname']) for k in orphankeys: if len(k) == 0: continue dn = DN(k[0]['dn']) @@ -391,7 +391,7 @@ class automountlocation_import(LDAPQuery): reason=_('File %(file)s not found') % {'file': filename} ) else: - raise e + raise return map def forward(self, *args, **options): diff --git a/tests/test_xmlrpc/test_automount_plugin.py b/tests/test_xmlrpc/test_automount_plugin.py index 0dd65d870..d6c289979 100644 --- a/tests/test_xmlrpc/test_automount_plugin.py +++ b/tests/test_xmlrpc/test_automount_plugin.py @@ -22,14 +22,90 @@ Test the `ipalib/plugins/automount.py' module. """ import sys -from nose.tools import raises, assert_raises # pylint: disable=E0611 +import textwrap +import tempfile +import shutil -from xmlrpc_test import XMLRPC_test, assert_attr_equal from ipalib import api from ipalib import errors +from ipalib.dn import DN - -class test_automount(XMLRPC_test): +from nose.tools import raises, assert_raises # pylint: disable=E0611 +from xmlrpc_test import XMLRPC_test, assert_attr_equal +from tests.util import assert_deepequal + + +class MockTextui(list): + """Collects output lines""" + # Extend the mock object if other textui methods are called + def print_plain(self, line): + self.append(unicode(line)) + + +class AutomountTest(XMLRPC_test): + """Provides common functionality for automount tests""" + def check_tofiles(self): + """Check automountlocation_tofiles output against self.tofiles_output + """ + res = api.Command['automountlocation_tofiles'](self.locname) + + mock_ui = MockTextui() + command = api.Command['automountlocation_tofiles'] + command.output_for_cli(mock_ui, res, self.locname) + expected_output = self.tofiles_output + assert_deepequal(expected_output, u'\n'.join(mock_ui)) + + def check_import_roundtrip(self): + """Check automountlocation_tofiles/automountlocation_import roundtrip + + Loads self.tofiles_output (which should correspond to + automountlocation_tofiles output), then checks the resulting map + against tofiles_output again. + Do not use this if the test creates maps that aren't connected to + auto.master -- these can't be imported successfully. + """ + conf_directory = tempfile.mkdtemp() + + # Parse the tofiles_output into individual files, replace /etc/ by + # our temporary directory name + current_file = None + for line in self.tofiles_output.splitlines(): + line = line.replace('/etc/', '%s/' % conf_directory) + if line.startswith(conf_directory) and line.endswith(':'): + current_file = open(line.rstrip(':'), 'w') + elif '--------' in line: + current_file.close() + elif line.startswith('maps not connected to '): + break + else: + current_file.write(line + '\n') + current_file.close() + + self.failsafe_add(api.Object.automountlocation, self.locname) + + try: + # Feed the files to automountlocation_import & check + master_file = u'%s/auto.master' % conf_directory + automountlocation_import = api.Command['automountlocation_import'] + res = automountlocation_import(self.locname, master_file) + assert_deepequal(dict( + result=dict( + keys=lambda k: k, + maps=lambda m: m, + skipped=(), + duplicatemaps=(), + duplicatekeys=(), + )), res) + self.check_tofiles() + finally: + res = api.Command['automountlocation_del'](self.locname)['result'] + assert res + assert_attr_equal(res, 'failed', '') + + # Success; delete the temporary directory + shutil.rmtree(conf_directory) + +class test_automount(AutomountTest): """ Test the `automount` plugin. """ @@ -45,6 +121,18 @@ class test_automount(XMLRPC_test): key_kw = {'automountkey': keyname, 'automountinformation': info, 'raw': True} key_kw2 = {'automountkey': keyname2, 'automountinformation': info, 'raw': True} + tofiles_output = textwrap.dedent(u""" + /etc/auto.master: + /-\t/etc/auto.direct + --------------------------- + /etc/auto.direct: + + maps not connected to /etc/auto.master: + --------------------------- + /etc/testmap: + testkey2\tro + """).strip() + def test_0_automountlocation_add(self): """ Test adding a location `xmlrpc.automountlocation_add` method. @@ -141,6 +229,59 @@ class test_automount(XMLRPC_test): assert res assert_attr_equal(res, 'description', 'new description') + def test_a2_automountmap_tofiles(self): + """ + Test the `automountlocation_tofiles` command. + """ + res = api.Command['automountlocation_tofiles'](self.locname) + assert_deepequal(dict( + result=dict( + keys={'auto.direct': ()}, + orphanmaps=(dict( + dn=lambda dn: DN(dn) == DN( + ('automountmapname', self.mapname), + ('cn', self.locname), + ('cn', 'automount'), api.env.basedn), + description=(u'description of map',), + automountmapname=(u'testmap',)),), + orphankeys=[( + dict( + dn=lambda dn: DN(dn) == DN( + ('description', self.keyname2), + ('automountmapname', 'testmap'), + ('cn', self.locname), + ('cn', 'automount'), api.env.basedn), + automountkey=(self.keyname2,), + description=(self.keyname2,), + automountinformation=(u'ro',), + ), + dict( + dn=lambda dn: DN(dn) == DN( + ('description', self.keyname_rename), + ('automountmapname', 'testmap'), + ('cn', self.locname), + ('cn', 'automount'), api.env.basedn), + automountkey=(self.keyname_rename,), + description=(self.keyname_rename,), + automountinformation=(u'rw',), + ))], + maps=( + dict( + dn=lambda dn: DN(dn) == DN( + ('description', '/- auto.direct'), + ('automountmapname', 'auto.master'), + ('cn', self.locname), + ('cn', 'automount'), api.env.basedn), + automountkey=(u'/-',), + description=(u'/- auto.direct',), + automountinformation=(u'auto.direct',) + ), + ))), res) + + # Also check the CLI output + + self.check_tofiles() + def test_b_automountkey_del(self): """ Test the `xmlrpc.automountkey_del` method. @@ -175,7 +316,8 @@ class test_automount(XMLRPC_test): with assert_raises(errors.NotFound): api.Command['automountkey_show'](self.locname, self.mapname, **key_kw) -class test_automount_direct(XMLRPC_test): + +class test_automount_direct(AutomountTest): """ Test the `automount` plugin indirect map functionality. """ @@ -184,6 +326,18 @@ class test_automount_direct(XMLRPC_test): keyname = u'/-' direct_kw = { 'key' : keyname } + tofiles_output = textwrap.dedent(u""" + /etc/auto.master: + /-\t/etc/auto.direct + /-\t/etc/auto.direct2 + --------------------------- + /etc/auto.direct: + --------------------------- + /etc/auto.direct2: + + maps not connected to /etc/auto.master: + """).strip() + def test_0_automountlocation_add(self): """ Test adding a location. @@ -207,6 +361,10 @@ class test_automount_direct(XMLRPC_test): """ res = api.Command['automountmap_add_indirect'](self.locname, self.mapname, **self.direct_kw)['result'] + def test_2a_automountmap_tofiles(self): + """Test the `automountmap_tofiles` command""" + self.check_tofiles() + def test_3_automountlocation_del(self): """ Remove the location. @@ -219,7 +377,13 @@ class test_automount_direct(XMLRPC_test): with assert_raises(errors.NotFound): api.Command['automountlocation_show'](self.locname) -class test_automount_indirect(XMLRPC_test): + def test_z_import_roundtrip(self): + """Check automountlocation_tofiles/automountlocation_import roundtrip + """ + self.check_import_roundtrip() + + +class test_automount_indirect(AutomountTest): """ Test the `automount` plugin indirect map functionality. """ @@ -230,6 +394,18 @@ class test_automount_indirect(XMLRPC_test): map_kw = {'key': keyname, 'parentmap': parentmap, 'raw': True} key_kw = {'automountkey': keyname, 'automountinformation': mapname} + tofiles_output = textwrap.dedent(u""" + /etc/auto.master: + /-\t/etc/auto.direct + /home\t/etc/auto.home + --------------------------- + /etc/auto.direct: + --------------------------- + /etc/auto.home: + + maps not connected to /etc/auto.master: + """).strip() + def test_0_automountlocation_add(self): """ Test adding a location. @@ -261,6 +437,10 @@ class test_automount_indirect(XMLRPC_test): assert res assert_attr_equal(res, 'automountmapname', self.mapname) + def test_2a_automountmap_tofiles(self): + """Test the `automountmap_tofiles` command""" + self.check_tofiles() + def test_3_automountkey_del(self): """ Remove the indirect key /home. @@ -297,16 +477,38 @@ class test_automount_indirect(XMLRPC_test): with assert_raises(errors.NotFound): api.Command['automountlocation_show'](self.locname) + def test_z_import_roundtrip(self): + """Check automountlocation_tofiles/automountlocation_import roundtrip + """ + self.check_import_roundtrip() -class test_automount_indirect_no_parent(XMLRPC_test): +class test_automount_indirect_no_parent(AutomountTest): """ Test the `automount` plugin Indirect map function. """ locname = u'testlocation' mapname = u'auto.home' keyname = u'/home' + mapname2 = u'auto.direct2' + keyname2 = u'direct2' parentmap = u'auto.master' map_kw = {'key': keyname, 'raw': True} + map_kw2 = {'key': keyname2, 'raw': True} + + tofiles_output = textwrap.dedent(u""" + /etc/auto.master: + /-\t/etc/auto.direct + /home\t/etc/auto.home + --------------------------- + /etc/auto.direct: + --------------------------- + /etc/auto.home: + direct2\t-fstype=autofs ldap:auto.direct2 + + maps not connected to /etc/auto.master: + --------------------------- + /etc/auto.direct2: + """).strip() def test_0_automountlocation_add(self): """ @@ -333,6 +535,19 @@ class test_automount_indirect_no_parent(XMLRPC_test): assert res assert_attr_equal(res, 'automountkey', self.keyname) + def test_2a_automountmap_add_indirect(self): + """ + Test adding an indirect map with default parent. + """ + res = api.Command['automountmap_add_indirect'](self.locname, + u'auto.direct2', parentmap=self.mapname, **self.map_kw2)['result'] + assert res + assert_attr_equal(res, 'automountmapname', self.mapname2) + + def test_2b_automountmap_tofiles(self): + """Test the `automountmap_tofiles` command""" + self.check_tofiles() + def test_3_automountkey_del(self): """ Remove the indirect key /home. |