Skip to content

Commit

Permalink
Introduce setup and teardown fixture
Browse files Browse the repository at this point in the history
With this change, multiple test modules triggered from testcases/mount
can be run as individual tests complying to pytest standards.
Also any number of new tests can be added efficiently on the mount.

Old approach:
-  All the different tests are called from test_mount.py:
   https://github.com/samba-in-kubernetes/sit-test-cases/blob/main/testcases/mount/test_mount.py
-  Test_mount.py creates a mount, the required tests are called and then test_mount.py cleans the mount.

New approach :
-  This PR complies with the proposal to use fixtures in order to remove all the load on one single
   module:
   samba-in-kubernetes#25 (comment)
   samba-in-kubernetes#25 (comment)
-  The tests are no more called from test_mount.py.
-  Setting up of mount and tearing down of mount is taken care by setup and teardown fixture
   which is defined in testcases/mount/conftest.py

   More information about fixtures:
   https://docs.pytest.org/en/6.2.x/fixture.html
-  With this change, test files remain the same, but the initiator function starts with keyword test
   and the each test module starts with keyword 'test'

   That way the tests are called by pytest.
   Usage of setup and teardown fixture becomes easily possible.
   We no more need to to call the test function explictly.

   This also helps with easy debugging and better understanding of the code, as the tests will be
   failed at individual mount/IO test.

   In this case, pytest clearly points which test among test_mount_io.py, test_mount_dbm.py
   and test_mount_stress.py are failing.
   Can be very useful
   - when more and more tests are added
   - when we want to parse test results in sit-environment project

Fixes: samba-in-kubernetes#30
Signed-off-by: Shwetha K Acharya <Shwetha.K.Acharya@ibm.com>
  • Loading branch information
Shwetha-Acharya authored and spuiuk committed Jan 10, 2024
1 parent 7ddd860 commit 0e09247
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 106 deletions.
20 changes: 0 additions & 20 deletions test-info.yml.example

This file was deleted.

58 changes: 58 additions & 0 deletions testcases/mount/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3

import pytest
import os
import shutil
import testhelper
import typing
from pathlib import Path

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


@pytest.fixture
def setup_mount(
request: pytest.FixtureRequest,
) -> typing.Generator[Path, None, None]:
ipaddr, share_name = request.param
flag_mounted: bool = False
tmp_root = testhelper.get_tmp_root()
mount_point = testhelper.get_tmp_mount_point(tmp_root)
try:
mount_params = testhelper.get_mount_parameters(test_info, share_name)
mount_params["host"] = ipaddr

# mount cifs share
testhelper.cifs_mount(mount_params, mount_point)
flag_mounted = True
test_dir = mount_point / "mount_test"
test_dir.mkdir()
except Exception as e:
raise Exception(f"Setup failed: {str(e)}")

# Yield the setup result
yield test_dir

# Perform teardown after the test has run
try:
if flag_mounted and test_dir:
shutil.rmtree(test_dir, ignore_errors=True)
testhelper.cifs_umount(mount_point)
mount_point.rmdir()
tmp_root.rmdir()
except Exception as e:
raise Exception(f"Teardown failed: {str(e)}")


def generate_mount_check() -> typing.List[typing.Tuple[str, str]]:
ipaddr = test_info["public_interfaces"][0]
exported_sharenames = test_info.get("exported_sharenames", [])
arr = []
for share_name in exported_sharenames:
arr.append((ipaddr, share_name))
return arr


def generate_mount_check_premounted() -> typing.List[Path]:
return testhelper.get_premounted_shares(test_info)
70 changes: 0 additions & 70 deletions testcases/mount/test_mount.py

This file was deleted.

27 changes: 20 additions & 7 deletions testcases/mount/mount_dbm.py → testcases/mount/test_mount_dbm.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#!/usr/bin/env python3
# Test various database operations via SMB mount-point.

import pytest
import dbm
import hashlib
import pickle
import shutil
import typing
import random
from pathlib import Path
from .conftest import generate_mount_check, generate_mount_check_premounted


class Record:
Expand Down Expand Up @@ -89,12 +91,23 @@ def _check_dbm_consistency(base: Path, nrecs: int) -> None:
db.destroy()


def check_dbm_consistency(rootdir: Path) -> None:
base = rootdir / "dbm-consistency"
base.mkdir(parents=True, exist_ok=True)
def _run_dbm_consistency_checks(base_path: Path) -> None:
base_path.mkdir(parents=True, exist_ok=True)
try:
_check_dbm_consistency(base, 10)
_check_dbm_consistency(base, 100)
_check_dbm_consistency(base, 10000)
_check_dbm_consistency(base_path, 10)
_check_dbm_consistency(base_path, 100)
_check_dbm_consistency(base_path, 10000)
finally:
shutil.rmtree(base, ignore_errors=True)
shutil.rmtree(base_path, ignore_errors=True)


@pytest.mark.parametrize("setup_mount", generate_mount_check(), indirect=True)
def test_dbm_consistency(setup_mount: Path) -> None:
base = setup_mount / "dbm-consistency"
_run_dbm_consistency_checks(base)


@pytest.mark.parametrize("test_dir", generate_mount_check_premounted())
def test_dbm_consistency_premounted(test_dir: Path) -> None:
base = test_dir / "dbm-consistency"
_run_dbm_consistency_checks(base)
20 changes: 16 additions & 4 deletions testcases/mount/mount_io.py → testcases/mount/test_mount_io.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

# Test various file-system I/O operations via local SMB mount-point.

import pytest
import datetime
import shutil
import typing
import testhelper
import random
from pathlib import Path
from .conftest import generate_mount_check, generate_mount_check_premounted


class DataPath:
Expand Down Expand Up @@ -99,11 +101,11 @@ def _run_checks(dsets: typing.List[DataPath]) -> None:
dset.verify_noent()


def _check_io_consistency(rootdir: Path) -> None:
def _check_io_consistency(test_dir: Path) -> None:
base = None
try:
print("\n")
base = rootdir / "test_io_consistency"
base = test_dir / "test_io_consistency"
base.mkdir(parents=True)
# Case-1: single 4K file
_run_checks(_make_datasets(base, 4096, 1))
Expand All @@ -127,6 +129,16 @@ def _reset_random_seed() -> None:
random.seed(seed)


def check_io_consistency(rootdir: Path) -> None:
def _perform_io_consistency_check(directory: Path) -> None:
_reset_random_seed()
_check_io_consistency(rootdir)
_check_io_consistency(directory)


@pytest.mark.parametrize("setup_mount", generate_mount_check(), indirect=True)
def test_check_io_consistency(setup_mount: Path) -> None:
_perform_io_consistency_check(setup_mount)


@pytest.mark.parametrize("test_dir", generate_mount_check_premounted())
def test_check_io_consistency_premounted(test_dir: Path) -> None:
_perform_io_consistency_check(test_dir)
24 changes: 19 additions & 5 deletions testcases/mount/mount_stress.py → testcases/mount/test_mount_stress.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest
import threading
import testhelper
from pathlib import Path
from .conftest import generate_mount_check, generate_mount_check_premounted


def _perform_file_operations(
Expand Down Expand Up @@ -43,14 +45,26 @@ def _stress_test(
print("Stress test complete.")


def check_mnt_stress(root_dir: Path) -> None:
_stress_test(root_dir, num_clients=5, num_operations=20, file_size=2**22)
def _run_stress_tests(directory: Path) -> None:
_stress_test(
root_dir, num_clients=10, num_operations=30, file_size=2**23
directory, num_clients=5, num_operations=20, file_size=2**22
)
_stress_test(
root_dir, num_clients=20, num_operations=40, file_size=2**24
directory, num_clients=10, num_operations=30, file_size=2**23
)
_stress_test(
root_dir, num_clients=15, num_operations=25, file_size=2**25
directory, num_clients=20, num_operations=40, file_size=2**24
)
_stress_test(
directory, num_clients=15, num_operations=25, file_size=2**25
)


@pytest.mark.parametrize("setup_mount", generate_mount_check(), indirect=True)
def test_check_mnt_stress(setup_mount: Path) -> None:
_run_stress_tests(setup_mount)


@pytest.mark.parametrize("test_dir", generate_mount_check_premounted())
def test_check_mnt_stress_premounted(test_dir: Path) -> None:
_run_stress_tests(test_dir)

0 comments on commit 0e09247

Please sign in to comment.