Add more automount tests

This adds tests for the automountlocation_tofiles and
automountlocation_import commands, and to automountmap_add_indirect
with the --parentmap option.

The tofiles test checks not only the XML-RPC output, but also the
output_for_cli method.

The import tests load data from tofiles output to the directory
and check that tofiles output matches.
This only works when all maps are connected to auto.master.

Two minor touches to the automount plugin itself: remove an extra
space, and don't hide the traceback when re-raising an exception.
This commit is contained in:
Petr Viktorin
2012-05-25 10:53:23 -04:00
committed by Rob Crittenden
parent 895203c477
commit c799f6a0bf
2 changed files with 223 additions and 8 deletions

View File

@@ -349,7 +349,7 @@ class automountlocation_tofiles(LDAPQuery):
textui.print_plain(_('maps not connected to /etc/auto.master:')) textui.print_plain(_('maps not connected to /etc/auto.master:'))
for m in orphanmaps: for m in orphanmaps:
textui.print_plain('---------------------------') textui.print_plain('---------------------------')
textui.print_plain('/etc/%s: ' % m['automountmapname']) textui.print_plain('/etc/%s:' % m['automountmapname'])
for k in orphankeys: for k in orphankeys:
if len(k) == 0: continue if len(k) == 0: continue
dn = DN(k[0]['dn']) dn = DN(k[0]['dn'])
@@ -391,7 +391,7 @@ class automountlocation_import(LDAPQuery):
reason=_('File %(file)s not found') % {'file': filename} reason=_('File %(file)s not found') % {'file': filename}
) )
else: else:
raise e raise
return map return map
def forward(self, *args, **options): def forward(self, *args, **options):

View File

@@ -22,14 +22,90 @@ Test the `ipalib/plugins/automount.py' module.
""" """
import sys 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 api
from ipalib import errors from ipalib import errors
from ipalib.dn import DN
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 test_automount(XMLRPC_test): 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. Test the `automount` plugin.
""" """
@@ -45,6 +121,18 @@ class test_automount(XMLRPC_test):
key_kw = {'automountkey': keyname, 'automountinformation': info, 'raw': True} key_kw = {'automountkey': keyname, 'automountinformation': info, 'raw': True}
key_kw2 = {'automountkey': keyname2, '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): def test_0_automountlocation_add(self):
""" """
Test adding a location `xmlrpc.automountlocation_add` method. Test adding a location `xmlrpc.automountlocation_add` method.
@@ -141,6 +229,59 @@ class test_automount(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'description', 'new description') 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): def test_b_automountkey_del(self):
""" """
Test the `xmlrpc.automountkey_del` method. Test the `xmlrpc.automountkey_del` method.
@@ -175,7 +316,8 @@ class test_automount(XMLRPC_test):
with assert_raises(errors.NotFound): with assert_raises(errors.NotFound):
api.Command['automountkey_show'](self.locname, self.mapname, **key_kw) 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. Test the `automount` plugin indirect map functionality.
""" """
@@ -184,6 +326,18 @@ class test_automount_direct(XMLRPC_test):
keyname = u'/-' keyname = u'/-'
direct_kw = { 'key' : keyname } 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): def test_0_automountlocation_add(self):
""" """
Test adding a location. 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'] 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): def test_3_automountlocation_del(self):
""" """
Remove the location. Remove the location.
@@ -219,7 +377,13 @@ class test_automount_direct(XMLRPC_test):
with assert_raises(errors.NotFound): with assert_raises(errors.NotFound):
api.Command['automountlocation_show'](self.locname) 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. 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} map_kw = {'key': keyname, 'parentmap': parentmap, 'raw': True}
key_kw = {'automountkey': keyname, 'automountinformation': mapname} 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): def test_0_automountlocation_add(self):
""" """
Test adding a location. Test adding a location.
@@ -261,6 +437,10 @@ class test_automount_indirect(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'automountmapname', self.mapname) 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): def test_3_automountkey_del(self):
""" """
Remove the indirect key /home. Remove the indirect key /home.
@@ -297,16 +477,38 @@ class test_automount_indirect(XMLRPC_test):
with assert_raises(errors.NotFound): with assert_raises(errors.NotFound):
api.Command['automountlocation_show'](self.locname) 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. Test the `automount` plugin Indirect map function.
""" """
locname = u'testlocation' locname = u'testlocation'
mapname = u'auto.home' mapname = u'auto.home'
keyname = u'/home' keyname = u'/home'
mapname2 = u'auto.direct2'
keyname2 = u'direct2'
parentmap = u'auto.master' parentmap = u'auto.master'
map_kw = {'key': keyname, 'raw': True} 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): def test_0_automountlocation_add(self):
""" """
@@ -333,6 +535,19 @@ class test_automount_indirect_no_parent(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'automountkey', self.keyname) 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): def test_3_automountkey_del(self):
""" """
Remove the indirect key /home. Remove the indirect key /home.