Skip to content

Commit 24f29dd

Browse files
committed
Cover the various check access helpers in the fileio unit tests.
Please note that we effectively run unit tests as uid 0 when using the containerized setup, and that may yield rather surprising results when testing file access, because super-users have access to everything despite what the permissions indicate. The added tests take uid 0 into account and will succeed, but we should really eliminate these privileges when unit testing as they can easily cause a lot of head-scratching. The tests also uncovered a couple of additional corner case bugs in the access checks, which don't show up with the uid 0 case but need to be addressed for the general benefit. They have been registered in issue #378 for further work.
1 parent d327542 commit 24f29dd

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

tests/test_mig_shared_fileio.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,5 +1047,163 @@ def test_fails_for_file_path(self):
10471047
self.assertFalse(result)
10481048

10491049

1050+
class MigSharedFileio__check_access(MigTestCase):
1051+
"""Test the various check access functions from mig.shared.fileio module"""
1052+
1053+
def _provide_configuration(self):
1054+
"""Set up isolated test configuration and logger for the tests"""
1055+
return 'testconfig'
1056+
1057+
def setUp(self):
1058+
"""Initialize test environment for access check tests"""
1059+
super(MigSharedFileio__check_access, self).setUp()
1060+
self.tmp_dir = temppath('fileio/check_access', self)
1061+
os.makedirs(self.tmp_dir)
1062+
self.writeonly_file = os.path.join(self.tmp_dir, 'writeonly.txt')
1063+
self.readonly_file = os.path.join(self.tmp_dir, 'readonly.txt')
1064+
self.readwrite_file = os.path.join(self.tmp_dir, 'readwrite.txt')
1065+
1066+
# Create test files with different permissions
1067+
with open(self.writeonly_file, 'w') as fh:
1068+
fh.write("writeonly")
1069+
with open(self.readonly_file, 'w') as fh:
1070+
fh.write("readonly")
1071+
with open(self.readwrite_file, 'w') as fh:
1072+
fh.write("read-write")
1073+
1074+
# Set permissions
1075+
os.chmod(self.writeonly_file, 0o200)
1076+
os.chmod(self.readonly_file, 0o400)
1077+
os.chmod(self.readwrite_file, 0o600)
1078+
1079+
def test_check_read_access_file(self):
1080+
"""Test check_read_access with readable file"""
1081+
self.assertTrue(fileio.check_read_access(self.readwrite_file))
1082+
self.assertTrue(fileio.check_read_access(self.readonly_file))
1083+
self.assertTrue(fileio.check_read_access(self.tmp_dir,
1084+
parent_dir=True))
1085+
# Super-user has access to read and write all files!
1086+
if os.getuid() == 0:
1087+
self.assertTrue(fileio.check_read_access(self.writeonly_file))
1088+
else:
1089+
self.assertFalse(fileio.check_read_access(self.writeonly_file))
1090+
self.assertFalse(fileio.check_read_access('/invalid/path'))
1091+
1092+
def test_check_write_access_file(self):
1093+
"""Test check_write_access with writable file"""
1094+
self.assertTrue(fileio.check_write_access(self.writeonly_file))
1095+
self.assertTrue(fileio.check_write_access(self.readwrite_file))
1096+
# Super-user has access to read and write all files!
1097+
if os.getuid() == 0:
1098+
self.assertTrue(fileio.check_write_access(self.readonly_file))
1099+
else:
1100+
self.assertFalse(fileio.check_write_access(self.readonly_file))
1101+
self.assertFalse(fileio.check_write_access('/invalid/path'))
1102+
1103+
def test_check_read_access_with_parent(self):
1104+
"""Test check_read_access with parent_dir True"""
1105+
sub_file = os.path.join(self.tmp_dir, 'file.txt')
1106+
result = fileio.check_read_access(sub_file, parent_dir=True)
1107+
self.assertTrue(result)
1108+
1109+
def test_check_write_access_with_parent(self):
1110+
"""Test check_write_access with parent_dir True"""
1111+
sub_file = os.path.join(self.tmp_dir, 'file.txt')
1112+
result = fileio.check_write_access(sub_file, parent_dir=True)
1113+
self.assertTrue(result)
1114+
1115+
def test_check_readable(self):
1116+
"""Test check_readable wrapper function"""
1117+
self.assertTrue(fileio.check_readable(self.configuration,
1118+
self.readwrite_file))
1119+
self.assertTrue(fileio.check_readable(self.configuration,
1120+
self.readonly_file))
1121+
# Super-user has access to read and write all files!
1122+
if os.getuid() == 0:
1123+
self.assertTrue(fileio.check_readable(self.configuration,
1124+
self.writeonly_file))
1125+
else:
1126+
self.assertFalse(fileio.check_readable(self.configuration,
1127+
self.writeonly_file))
1128+
self.assertFalse(fileio.check_readable(self.configuration,
1129+
'/invalid/path'))
1130+
1131+
def test_check_writable(self):
1132+
"""Test check_writable wrapper function"""
1133+
self.assertTrue(fileio.check_writable(self.configuration,
1134+
self.readwrite_file))
1135+
self.assertTrue(fileio.check_writable(self.configuration,
1136+
self.writeonly_file))
1137+
# Super-user has access to read and write all files!
1138+
if os.getuid() == 0:
1139+
self.assertTrue(fileio.check_writable(self.configuration,
1140+
self.readonly_file))
1141+
else:
1142+
self.assertFalse(fileio.check_writable(self.configuration,
1143+
self.readonly_file))
1144+
self.assertFalse(fileio.check_writable(self.configuration,
1145+
"/no/such/file"))
1146+
1147+
def test_check_readonly(self):
1148+
"""Test check_readonly wrapper function"""
1149+
# Super-user has access to read and write all files!
1150+
if os.getuid() == 0:
1151+
# Test with read-only file path
1152+
self.assertFalse(fileio.check_readonly(self.configuration,
1153+
self.readonly_file))
1154+
1155+
# Test with writable file
1156+
self.assertFalse(fileio.check_readonly(self.configuration,
1157+
self.writeonly_file))
1158+
self.assertFalse(fileio.check_readonly(self.configuration,
1159+
self.readwrite_file))
1160+
else:
1161+
# Test with read-only file path
1162+
self.assertTrue(fileio.check_readonly(self.configuration,
1163+
self.readonly_file))
1164+
1165+
# Test with writable file
1166+
self.assertFalse(fileio.check_readonly(self.configuration,
1167+
self.writeonly_file))
1168+
self.assertFalse(fileio.check_readonly(self.configuration,
1169+
self.readwrite_file))
1170+
1171+
def test_check_readwritable(self):
1172+
"""Test check_readwritable wrapper function"""
1173+
self.assertTrue(fileio.check_readwritable(self.configuration,
1174+
self.readwrite_file))
1175+
# Super-user has access to read and write all files!
1176+
if os.getuid() == 0:
1177+
self.assertTrue(fileio.check_readwritable(self.configuration,
1178+
self.readonly_file))
1179+
self.assertTrue(fileio.check_readwritable(self.configuration,
1180+
self.writeonly_file))
1181+
else:
1182+
self.assertFalse(fileio.check_readwritable(self.configuration,
1183+
self.readonly_file))
1184+
self.assertFalse(fileio.check_readwritable(self.configuration,
1185+
self.writeonly_file))
1186+
1187+
self.assertFalse(fileio.check_readwritable(self.configuration,
1188+
"/invalid/file"))
1189+
1190+
def test_special_cases(self):
1191+
"""Test various special cases for access checks"""
1192+
# Check directory paths
1193+
self.assertTrue(fileio.check_read_access(self.tmp_dir))
1194+
self.assertTrue(fileio.check_write_access(self.tmp_dir))
1195+
1196+
# Check non-existent paths
1197+
missing_path = os.path.join(self.tmp_dir, 'missing.txt')
1198+
self.assertFalse(fileio.check_read_access(missing_path))
1199+
self.assertFalse(fileio.check_write_access(missing_path))
1200+
1201+
# Check with custom follow_symlink=False
1202+
self.assertTrue(fileio.check_read_access(self.readwrite_file,
1203+
follow_symlink=False))
1204+
self.assertTrue(fileio.check_read_access(self.tmp_dir, True,
1205+
follow_symlink=False))
1206+
1207+
10501208
if __name__ == '__main__':
10511209
testmain()

0 commit comments

Comments
 (0)