Skip to content

Commit 4ac2dad

Browse files
committed
New testcase 'verify_smb_linux'
New testcase 'verify_smb_linux' A comprehensive test to verify CIFS module and SMB share functionality between two Linux VMs.
1 parent e20a430 commit 4ac2dad

File tree

1 file changed

+192
-2
lines changed

1 file changed

+192
-2
lines changed

lisa/microsoft/testsuites/core/storage.py

Lines changed: 192 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,26 @@
3232
SecurityProfileType,
3333
)
3434
from lisa.node import Node
35-
from lisa.operating_system import BSD, Posix, Windows
35+
from lisa.operating_system import BSD, AlmaLinux, CBLMariner, Posix, Redhat, Windows
3636
from lisa.schema import DiskControllerType, DiskOptionSettings, DiskType
3737
from lisa.sut_orchestrator import AZURE, HYPERV
3838
from lisa.sut_orchestrator.azure.features import AzureDiskOptionSettings, AzureFileShare
3939
from lisa.sut_orchestrator.azure.tools import Waagent
40-
from lisa.tools import Blkid, Cat, Dmesg, Echo, Lsblk, Mount, NFSClient, Swap, Sysctl
40+
from lisa.tools import (
41+
Blkid,
42+
Cat,
43+
Dmesg,
44+
Echo,
45+
Ls,
46+
Lsblk,
47+
Mount,
48+
NFSClient,
49+
Rm,
50+
SmbClient,
51+
SmbServer,
52+
Swap,
53+
Sysctl,
54+
)
4155
from lisa.tools.blkid import PartitionInfo
4256
from lisa.tools.journalctl import Journalctl
4357
from lisa.tools.kernel_config import KernelConfig
@@ -590,6 +604,182 @@ def after_case(self, log: Logger, **kwargs: Any) -> None:
590604
except Exception:
591605
raise BadEnvironmentStateException
592606

607+
@TestCaseMetadata(
608+
description="""
609+
A comprehensive test to verify CIFS module and SMB share functionality between
610+
two Linux VMs.
611+
This test case will
612+
1. Create an 2 VMs in azure
613+
2. Check if CONFIG_CIFS is enabled in KCONFIG
614+
3. Configure one VM as SMB server and create a share
615+
4. Mount the other VM to the SMB share
616+
5. Verify mount is successful
617+
6. Write a test file to the SMB share and read it back to verify IO
618+
7. Clean up the SMB share and unmount
619+
8. repeat steps 4-7 for SMB versions ["2.0", "2.1", "3.0", "3.1.1"]
620+
""",
621+
timeout=TIME_OUT,
622+
requirement=simple_requirement(
623+
min_count=2,
624+
unsupported_os=[Redhat, CBLMariner, AlmaLinux, BSD, Windows],
625+
),
626+
use_new_environment=True,
627+
priority=1,
628+
)
629+
def verify_smb_linux(
630+
self, log: Logger, node: Node, environment: Environment
631+
) -> None:
632+
# Check if CONFIG_CIFS is enabled in KCONFIG
633+
if not node.tools[KernelConfig].is_enabled("CONFIG_CIFS"):
634+
raise LisaException("CIFS module must be present for SMB testing")
635+
636+
# Assign server and client roles to the 2 VMs
637+
server_node = cast(RemoteNode, environment.nodes[0])
638+
client_node = cast(RemoteNode, environment.nodes[1])
639+
640+
# Install and setup SMB tools on both nodes
641+
smb_server = server_node.tools[SmbServer]
642+
smb_client = client_node.tools[SmbClient]
643+
644+
# SMB versions to test
645+
smb_versions = ["3.0", "3.1.1", "2.1", "2.0"]
646+
647+
# Test configuration
648+
share_name = "testshare"
649+
share_path = f"/tmp/{share_name}"
650+
mount_point = f"/mnt/{share_name}"
651+
652+
try:
653+
# Step 3: Configure SMB server and create a share
654+
smb_server.create_share(share_name, share_path)
655+
656+
# Step 8: Repeat for different SMB versions
657+
for smb_version in smb_versions:
658+
log.info(f"Testing SMB version {smb_version}")
659+
660+
# Step 4: Mount the SMB share on client
661+
smb_client.mount_share(
662+
server_node.internal_address, share_name, mount_point, smb_version
663+
)
664+
665+
# Step 5& 6: Verify mount is successful
666+
self._verify_smb_mount(
667+
client_node,
668+
mount_point,
669+
server_node,
670+
share_path,
671+
log,
672+
)
673+
674+
# Step 7: Cleanup between version tests
675+
smb_client.unmount_share(mount_point)
676+
finally:
677+
# Cleanup
678+
self._cleanup_smb_test(
679+
server_node, client_node, share_path, mount_point, log
680+
)
681+
682+
def _verify_smb_mount(
683+
self,
684+
client_node: RemoteNode,
685+
mount_point: str,
686+
server_node: RemoteNode,
687+
share_path: str,
688+
log: Logger,
689+
) -> None:
690+
"""
691+
Verify SMB mount is working by creating and reading a file from
692+
both client and server.
693+
"""
694+
test_file = "smb_test.txt"
695+
test_content = "SMB test content"
696+
mount = client_node.tools[Mount]
697+
698+
# Verify mount point exists and is mounted
699+
mount_point_exists = mount.check_mount_point_exist(mount_point)
700+
if not mount_point_exists:
701+
raise LisaException(
702+
f"Mount point {mount_point} does not exist or is not mounted"
703+
)
704+
705+
# Create test file on mounted share from client
706+
test_file_path = f"{mount_point}/{test_file}"
707+
echo = client_node.tools[Echo]
708+
echo.write_to_file(
709+
test_content,
710+
client_node.get_pure_path(test_file_path),
711+
sudo=True,
712+
ignore_error=False,
713+
)
714+
715+
# Read and verify file content from client side
716+
file_content_client = client_node.tools[Cat].read(
717+
test_file_path, sudo=True, force_run=True
718+
)
719+
720+
assert_that(file_content_client).described_as(
721+
"SMB file content should match written content on client"
722+
).is_equal_to(test_content)
723+
724+
# Verify content from server VM if server_node and share_path are provided
725+
if server_node and share_path:
726+
server_file_path = f"{share_path}/{test_file}"
727+
728+
# Check if file exists on server
729+
if not server_node.tools[Ls].path_exists(server_file_path, sudo=True):
730+
raise LisaException(
731+
f"Test file {server_file_path} not found on server VM"
732+
)
733+
734+
# Read file content directly from server VM
735+
file_content_server = server_node.tools[Cat].read(
736+
server_file_path, sudo=True, force_run=True
737+
)
738+
739+
assert_that(file_content_server).described_as(
740+
"SMB file content should match on server VM"
741+
).is_equal_to(test_content)
742+
743+
log.info(
744+
f"Successfully verified file content on both client and server: "
745+
f"'{test_content}'"
746+
)
747+
748+
# Clean up test file from client (will also remove from server via SMB)
749+
client_node.tools[Rm].remove_file(test_file_path, sudo=True)
750+
751+
def _cleanup_smb_test(
752+
self,
753+
server_node: RemoteNode,
754+
client_node: RemoteNode,
755+
share_path: str,
756+
mount_point: str,
757+
log: Logger,
758+
) -> None:
759+
"""Clean up SMB test resources."""
760+
# Cleanup on client
761+
try:
762+
smb_client = client_node.tools[SmbClient]
763+
if smb_client.is_mounted(mount_point):
764+
smb_client.unmount_share(mount_point)
765+
smb_client.cleanup_mount_point(mount_point)
766+
except Exception as e:
767+
raise LisaException(
768+
f"fail to cleanup SMB client mount point {mount_point}: "
769+
f"{e.__class__.__name__}: {e}."
770+
)
771+
772+
# Cleanup on server
773+
try:
774+
smb_server = server_node.tools[SmbServer]
775+
smb_server.stop()
776+
smb_server.remove_share(share_path)
777+
except Exception as e:
778+
raise LisaException(
779+
f"fail to remove share {share_path} from SMB server: "
780+
f"{e.__class__.__name__}: {e}."
781+
)
782+
593783
@TestCaseMetadata(
594784
description="""
595785
This test case will

0 commit comments

Comments
 (0)