From: Rishabh Dave Date: Fri, 25 Jul 2025 08:20:06 +0000 (+0530) Subject: qa, test: run unit tests for cephfs.pyx with non-root user X-Git-Tag: testing/wip-jcollin-testing-20251016.112434-squid^2~7 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=7666ced14a5c6811d622475ffded4904e8ba5e51;p=ceph-ci.git qa, test: run unit tests for cephfs.pyx with non-root user Run test_python.sh with non-root user. This makes it necessary to change the owner user and group of file system root to be same as this non-root user. This brings testing closer to the real-world scenario and also allows exercising negative tests where an FS op would fail for a non-root user but it would pass for root user. There are few tests that exercise FS operations where root user is needed. Group these tests under a separate class and add extra code for this class that allows these tests to run with root UID and GID. Signed-off-by: Rishabh Dave (cherry picked from commit 6021dda7ed137445885979cd4d4b28c770abce13) Conflicts: src/test/pybind/test_cephfs.py - PR #64999 is merged in main but not in Squid, causing this branch to have less tests that need to be moved to class TestWithRootUser. --- diff --git a/qa/workunits/fs/test_python.sh b/qa/workunits/fs/test_python.sh index 6e39b95a4d1..462c096b8f0 100755 --- a/qa/workunits/fs/test_python.sh +++ b/qa/workunits/fs/test_python.sh @@ -1,6 +1,4 @@ #!/bin/sh -ex -# Running as root because the filesystem root directory will be -# owned by uid 0, and that's where we're writing. -sudo python3 -m pytest -v $(dirname $0)/../../../src/test/pybind/test_cephfs.py +python3 -m pytest -v $(dirname $0)/../../../src/test/pybind/test_cephfs.py exit 0 diff --git a/src/test/pybind/test_cephfs.py b/src/test/pybind/test_cephfs.py index 09379269451..8cd9ff72f78 100644 --- a/src/test/pybind/test_cephfs.py +++ b/src/test/pybind/test_cephfs.py @@ -12,14 +12,27 @@ import stat import uuid import json from datetime import datetime +from subprocess import getoutput as get_cmd_output + cephfs = None + def setup_module(): global cephfs cephfs = libcephfs.LibCephFS(conffile='') + + username = get_cmd_output('id -un') + uid = get_cmd_output(f'id -u {username}') + gid = get_cmd_output(f'id -g {username}') + cephfs.conf_set('client_mount_uid', uid) + cephfs.conf_set('client_mount_gid', gid) cephfs.mount() + cephfs.conf_set('client_permissions' , 'false') + cephfs.chown('/', int(uid), int(gid)) + cephfs.conf_set('client_permissions' , 'true') + def teardown_module(): global cephfs cephfs.shutdown() @@ -569,23 +582,6 @@ def test_fchmod(testdir): cephfs.close(fd) cephfs.unlink(b'/file-fchmod') -def test_fchown(testdir): - fd = cephfs.open(b'/file-fchown', 'w', 0o655) - uid = os.getuid() - gid = os.getgid() - assert_raises(TypeError, cephfs.fchown, b'/file-fchown', uid, gid) - assert_raises(TypeError, cephfs.fchown, fd, "uid", "gid") - cephfs.fchown(fd, uid, gid) - st = cephfs.statx(b'/file-fchown', libcephfs.CEPH_STATX_UID | libcephfs.CEPH_STATX_GID, 0) - assert_equal(st["uid"], uid) - assert_equal(st["gid"], gid) - cephfs.fchown(fd, 9999, 9999) - st = cephfs.statx(b'/file-fchown', libcephfs.CEPH_STATX_UID | libcephfs.CEPH_STATX_GID, 0) - assert_equal(st["uid"], 9999) - assert_equal(st["gid"], 9999) - cephfs.close(fd) - cephfs.unlink(b'/file-fchown') - def test_truncate(testdir): fd = cephfs.open(b'/file-truncate', 'w', 0o755) cephfs.write(fd, b"1111", 0) @@ -721,80 +717,6 @@ def test_preadv_pwritev(): cephfs.close(fd) cephfs.unlink(b'file-1') -def test_setattrx(testdir): - fd = cephfs.open(b'file-setattrx', 'w', 0o655) - cephfs.write(fd, b"1111", 0) - cephfs.close(fd) - st = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE, 0) - mode = st["mode"] | stat.S_IXUSR - assert_raises(TypeError, cephfs.setattrx, b'file-setattrx', "dict", 0, 0) - - time.sleep(1) - statx_dict = dict() - statx_dict["mode"] = mode - statx_dict["uid"] = 9999 - statx_dict["gid"] = 9999 - dt = datetime.now() - statx_dict["mtime"] = dt - statx_dict["atime"] = dt - statx_dict["ctime"] = dt - statx_dict["size"] = 10 - statx_dict["btime"] = dt - cephfs.setattrx(b'file-setattrx', statx_dict, libcephfs.CEPH_SETATTR_MODE | libcephfs.CEPH_SETATTR_UID | - libcephfs.CEPH_SETATTR_GID | libcephfs.CEPH_SETATTR_MTIME | - libcephfs.CEPH_SETATTR_ATIME | libcephfs.CEPH_SETATTR_CTIME | - libcephfs.CEPH_SETATTR_SIZE | libcephfs.CEPH_SETATTR_BTIME, 0) - st1 = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE | libcephfs.CEPH_STATX_UID | - libcephfs.CEPH_STATX_GID | libcephfs.CEPH_STATX_MTIME | - libcephfs.CEPH_STATX_ATIME | libcephfs.CEPH_STATX_CTIME | - libcephfs.CEPH_STATX_SIZE | libcephfs.CEPH_STATX_BTIME, 0) - assert_equal(mode, st1["mode"]) - assert_equal(9999, st1["uid"]) - assert_equal(9999, st1["gid"]) - assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp())) - assert_equal(10, st1["size"]) - cephfs.unlink(b'file-setattrx') - -def test_fsetattrx(testdir): - fd = cephfs.open(b'file-fsetattrx', 'w', 0o655) - cephfs.write(fd, b"1111", 0) - st = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE, 0) - mode = st["mode"] | stat.S_IXUSR - assert_raises(TypeError, cephfs.fsetattrx, fd, "dict", 0, 0) - - time.sleep(1) - statx_dict = dict() - statx_dict["mode"] = mode - statx_dict["uid"] = 9999 - statx_dict["gid"] = 9999 - dt = datetime.now() - statx_dict["mtime"] = dt - statx_dict["atime"] = dt - statx_dict["ctime"] = dt - statx_dict["size"] = 10 - statx_dict["btime"] = dt - cephfs.fsetattrx(fd, statx_dict, libcephfs.CEPH_SETATTR_MODE | libcephfs.CEPH_SETATTR_UID | - libcephfs.CEPH_SETATTR_GID | libcephfs.CEPH_SETATTR_MTIME | - libcephfs.CEPH_SETATTR_ATIME | libcephfs.CEPH_SETATTR_CTIME | - libcephfs.CEPH_SETATTR_SIZE | libcephfs.CEPH_SETATTR_BTIME) - st1 = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE | libcephfs.CEPH_STATX_UID | - libcephfs.CEPH_STATX_GID | libcephfs.CEPH_STATX_MTIME | - libcephfs.CEPH_STATX_ATIME | libcephfs.CEPH_STATX_CTIME | - libcephfs.CEPH_STATX_SIZE | libcephfs.CEPH_STATX_BTIME, 0) - assert_equal(mode, st1["mode"]) - assert_equal(9999, st1["uid"]) - assert_equal(9999, st1["gid"]) - assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp())) - assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp())) - assert_equal(10, st1["size"]) - cephfs.close(fd) - cephfs.unlink(b'file-fsetattrx') - def test_get_layout(testdir): fd = cephfs.open(b'file-get-layout', 'w', 0o755) cephfs.write(fd, b"1111", 0) @@ -942,6 +864,141 @@ def test_multi_target_command(): assert(list(mds_sessions.keys())[0].startswith('mds.')) +class TestWithRootUser: + + def setup_method(self): + cephfs.unmount() + cephfs.conf_set('client_mount_uid', '0') + cephfs.conf_set('client_mount_gid', '0') + cephfs.mount() + + cephfs.conf_set('client_permissions' , 'false') + cephfs.chown('/', 0, 0) + cephfs.conf_set('client_permissions' , 'true') + + def teardown_method(self): + cephfs.unmount() + + username = get_cmd_output('id -un') + uid = get_cmd_output(f'id -u {username}') + gid = get_cmd_output(f'id -g {username}') + + cephfs.conf_set('client_mount_uid', uid) + cephfs.conf_set('client_mount_gid', gid) + cephfs.mount() + + cephfs.conf_set('client_permissions' , 'false') + cephfs.chown('/', int(uid), int(gid)) + cephfs.conf_set('client_permissions' , 'true') + + def test_fchown(testdir): + fd = cephfs.open(b'/file-fchown', 'w', 0o655) + uid = os.getuid() + gid = os.getgid() + assert_raises(TypeError, cephfs.fchown, b'/file-fchown', uid, gid) + assert_raises(TypeError, cephfs.fchown, fd, "uid", "gid") + cephfs.fchown(fd, uid, gid) + st = cephfs.statx(b'/file-fchown', libcephfs.CEPH_STATX_UID | libcephfs.CEPH_STATX_GID, 0) + assert_equal(st["uid"], uid) + assert_equal(st["gid"], gid) + cephfs.fchown(fd, 9999, 9999) + st = cephfs.statx(b'/file-fchown', libcephfs.CEPH_STATX_UID | libcephfs.CEPH_STATX_GID, 0) + assert_equal(st["uid"], 9999) + assert_equal(st["gid"], 9999) + cephfs.close(fd) + cephfs.unlink(b'/file-fchown') + + def test_setattrx(testdir): + fd = cephfs.open(b'file-setattrx', 'w', 0o655) + cephfs.write(fd, b"1111", 0) + cephfs.close(fd) + st = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE, 0) + mode = st["mode"] | stat.S_IXUSR + assert_raises(TypeError, cephfs.setattrx, b'file-setattrx', "dict", 0, 0) + + time.sleep(1) + statx_dict = dict() + statx_dict["mode"] = mode + statx_dict["uid"] = 9999 + statx_dict["gid"] = 9999 + dt = datetime.now() + statx_dict["mtime"] = dt + statx_dict["atime"] = dt + statx_dict["ctime"] = dt + statx_dict["size"] = 10 + statx_dict["btime"] = dt + cephfs.setattrx(b'file-setattrx', statx_dict, libcephfs.CEPH_SETATTR_MODE | + libcephfs.CEPH_SETATTR_UID | + libcephfs.CEPH_SETATTR_GID | + libcephfs.CEPH_SETATTR_MTIME | + libcephfs.CEPH_SETATTR_ATIME | + libcephfs.CEPH_SETATTR_CTIME | + libcephfs.CEPH_SETATTR_SIZE | + libcephfs.CEPH_SETATTR_BTIME, 0) + st1 = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE | + libcephfs.CEPH_STATX_UID | + libcephfs.CEPH_STATX_GID | + libcephfs.CEPH_STATX_MTIME | + libcephfs.CEPH_STATX_ATIME | + libcephfs.CEPH_STATX_CTIME | + libcephfs.CEPH_STATX_SIZE | + libcephfs.CEPH_STATX_BTIME, 0) + assert_equal(mode, st1["mode"]) + assert_equal(9999, st1["uid"]) + assert_equal(9999, st1["gid"]) + assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp())) + assert_equal(10, st1["size"]) + cephfs.unlink(b'file-setattrx') + + def test_fsetattrx(testdir): + fd = cephfs.open(b'file-fsetattrx', 'w', 0o655) + cephfs.write(fd, b"1111", 0) + st = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE, 0) + mode = st["mode"] | stat.S_IXUSR + assert_raises(TypeError, cephfs.fsetattrx, fd, "dict", 0, 0) + + time.sleep(1) + statx_dict = dict() + statx_dict["mode"] = mode + statx_dict["uid"] = 9999 + statx_dict["gid"] = 9999 + dt = datetime.now() + statx_dict["mtime"] = dt + statx_dict["atime"] = dt + statx_dict["ctime"] = dt + statx_dict["size"] = 10 + statx_dict["btime"] = dt + cephfs.fsetattrx(fd, statx_dict, libcephfs.CEPH_SETATTR_MODE | + libcephfs.CEPH_SETATTR_UID | + libcephfs.CEPH_SETATTR_GID | + libcephfs.CEPH_SETATTR_MTIME | + libcephfs.CEPH_SETATTR_ATIME | + libcephfs.CEPH_SETATTR_CTIME | + libcephfs.CEPH_SETATTR_SIZE | + libcephfs.CEPH_SETATTR_BTIME) + st1 = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE | + libcephfs.CEPH_STATX_UID | + libcephfs.CEPH_STATX_GID | + libcephfs.CEPH_STATX_MTIME | + libcephfs.CEPH_STATX_ATIME | + libcephfs.CEPH_STATX_CTIME | + libcephfs.CEPH_STATX_SIZE | + libcephfs.CEPH_STATX_BTIME, 0) + assert_equal(mode, st1["mode"]) + assert_equal(9999, st1["uid"]) + assert_equal(9999, st1["gid"]) + assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp())) + assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp())) + assert_equal(10, st1["size"]) + cephfs.close(fd) + cephfs.unlink(b'file-fsetattrx') + + class TestRmtree: ''' Test rmtree() method of CephFS python bindings.