Skip to content

Supplementary tests #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions selftest/test-info1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ users:
# Backend filesystem of the exported shares
backend: glusterfs

# Additional information which may be used by tests here
# some tests may be skipped if the required config option is not set
extra:
# The supplementary group to be used by test_permissions
supplementary_group: test_sg


# shares: List of dict of exported shares
shares:
# share export1
Expand All @@ -19,6 +26,8 @@ shares:
backend:
# If present override default backend filesystem
name: cephfs.vfs
# if present, provide access to backend filesystem
path: /mnt/backend/export1
# If present, use these credentials to perform the
# tests for this share
users:
Expand Down
15 changes: 15 additions & 0 deletions selftest/test_testhelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def test_read_yaml1():
assert export1["server"] == "hostname1"
assert export1["path"] == "/mnt/share/export1-cephfs-vfs"
assert export1["backend"]["name"] == "cephfs.vfs"
assert export1["backend"]["path"] == "/mnt/backend/export1"
assert "user1" not in export1["users"]
assert "test2" in export1["users"]
assert export1["users"]["test2"] == "x"
Expand All @@ -17,6 +18,7 @@ def test_read_yaml1():
assert export2["server"] == "server_name"
assert "path" not in export2
assert export2["backend"]["name"] == "glusterfs"
assert export2["backend"]["path"] is None
assert "test2" not in export2["users"]
assert "user2" in export2["users"]
assert export2["users"]["user2"] == "user2password"
Expand Down Expand Up @@ -60,3 +62,16 @@ def test_generate_exported_shares():
arr.append((share["server"], share["name"]))
assert len(arr) == 1
assert ("server_name", "export2") in arr


def test_get_extra_configuration():
testinfo = testhelper.read_yaml("test-info1.yml")
sg = testhelper.get_extra_configuration(testinfo, "supplementary_group")
assert sg == "test_sg", "Could not read extra configuration"
other = testhelper.get_extra_configuration(testinfo, "other")
assert other is None, "Incorrectly read other from extra configuration"

# test-info2.yml does not have extra section
testinfo = testhelper.read_yaml("test-info2.yml")
sg = testhelper.get_extra_configuration(testinfo, "supplementary_group")
assert sg is None, "Could not read extra configuration"
8 changes: 8 additions & 0 deletions test-info.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ users:
# Backend filesystem of the exported shares
backend: glusterfs

# Additional information which may be used by tests here
# some tests may be skipped if the required config option is not set
extra:
# The supplementary group to be used by test_supplementary_group
supplementary_group: sg

# shares: List of dict of exported shares
shares:
# share export1
Expand All @@ -19,6 +25,8 @@ shares:
backend:
# If present override default backend filesystem
name: cephfs.vfs
# If present, provide access to backend filesystem
path: /mnt/backend/export1
# If present, use these credentials to perform the
# tests for this share
users:
Expand Down
93 changes: 93 additions & 0 deletions testcases/misc/test_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import testhelper
import os
import pytest
import pwd
import grp
import shutil
from pathlib import Path

test_info_file = os.getenv("TEST_INFO_FILE")
test_info = testhelper.read_yaml(test_info_file)
test_string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

# test_supplementary_group:
# This test is to check writes to a folder owned by a supplementary group.
#
# Requirements:
# 1. username in share["user"] exists
# 2. username is part of supplementary group provided in
# user["extra"]["supplementary_group"]
# 3. share["backend"]["path"] should be set
#
# Steps:
# 1. Create folder test_subdir/ on direct path with
# group set to sgroup and mode 0770
# 2. Upload file to test_subdir/test-cp
#
# Expected:
# Copy passes


# function to check if requirements are met
def check_reqs_supplementary_group(share: dict, sgroup: str) -> bool:
if share["backend"]["path"] is None:
return False

username = list(share["users"].keys())[0]
try:
pwd.getpwnam(username)
if username not in grp.getgrnam(sgroup).gr_mem:
return False
except KeyError:
return False
return True


def gen_supplementary_group_param(test_info: dict) -> list:
if not test_info:
return []
sgroup = testhelper.get_extra_configuration(
test_info, "supplementary_group"
)
if sgroup is None:
return []

arr = []
for s in testhelper.get_shares(test_info).values():
if check_reqs_supplementary_group(s, sgroup):
arr.append((s["server"], s["name"]))
return arr


@pytest.mark.privileged
@pytest.mark.parametrize(
"ipaddr,share_name", gen_supplementary_group_param(test_info)
)
def test_supplementary_group(ipaddr: str, share_name: str) -> None:
share = testhelper.get_share(test_info, share_name)
fs_path = Path(share["backend"]["path"])
sgroup = testhelper.get_extra_configuration(
test_info, "supplementary_group"
)
test_subdir = Path("supplementary_group")
mount_params = testhelper.get_mount_parameters(test_info, share_name)

# setup local testdir
testdir = fs_path / test_subdir
testdir.mkdir(exist_ok=True)
shutil.chown(testdir, group=sgroup)
testdir.chmod(0o770)

smbclient = testhelper.SMBClient(
ipaddr,
mount_params["share"],
mount_params["username"],
mount_params["password"],
)

try:
remote_test_file = str(Path("/") / test_subdir / Path("test-cp"))
smbclient.write_text(remote_test_file, test_string)
finally:
smbclient.disconnect()
shutil.rmtree(testdir)
18 changes: 17 additions & 1 deletion testhelper/testhelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ def read_yaml(test_info_file):
shares[sharename] = {"name": sharename}
share = shares[sharename]
share.setdefault("name", sharename)
share.setdefault("backend", {})
share.setdefault("server", default_server)
share.setdefault("users", default_users)
share.setdefault("backend", {})
share["backend"].setdefault("name", default_backend)
share["backend"].setdefault("path", None)

test_info["shares"] = shares

Expand Down Expand Up @@ -191,3 +192,18 @@ def get_exported_shares(test_info: dict) -> typing.List[str]:
if not is_premounted_share(share):
arr.append(share["name"])
return arr


def get_extra_configuration(test_info: dict, extra_var: str) -> typing.Any:
"""Return value of config set in extra section

Parameters:
test_info: Dict containing the parsed yaml file
extra_var: string containing extra config value required
Returns:
value set for the extra_var in the extra section
"""
extra = test_info.get("extra")
if extra is None:
return None
return extra.get(extra_var)
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ commands = pytest -vrfEsxXpP testcases/consistency
deps =
pytest
pyyaml
pysmb
changedir = {toxinidir}/selftest
commands = pytest -vrfEsxXpP .

Expand Down