Skip to content

Commit

Permalink
Add iSCSI test test_33_no_lun_zero (#13693)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmeagherix authored May 9, 2024
1 parent 34a8d93 commit eecaea0
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 16 deletions.
43 changes: 35 additions & 8 deletions src/middlewared/middlewared/test/integration/assets/iscsi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import platform
import time
from pathlib import Path

from middlewared.test.integration.utils import call, run_on_runner, RunOnRunnerException

Expand Down Expand Up @@ -73,14 +74,15 @@ def iscsi_target(data):
call("iscsi.target.delete", target["id"])


def target_login_test(portal_ip, target_name):
def target_login_test(portal_ip, target_name, check_surfaced_luns=None):
if IS_LINUX:
return target_login_test_linux(portal_ip, target_name)
return target_login_test_linux(portal_ip, target_name, check_surfaced_luns)
else:
return target_login_test_freebsd(portal_ip, target_name)
return target_login_test_freebsd(portal_ip, target_name, check_surfaced_luns)


def target_login_test_linux(portal_ip, target_name):
def target_login_test_linux(portal_ip, target_name, check_surfaced_luns=None):
logged_in = False
try:
if os.geteuid():
# Non-root requires sudo
Expand All @@ -89,11 +91,27 @@ def target_login_test_linux(portal_ip, target_name):
iscsiadm = ['iscsiadm']
run_on_runner(iscsiadm + ['-m', 'discovery', '-t', 'sendtargets', '--portal', portal_ip])
run_on_runner(iscsiadm + ['-m', 'node', '--targetname', target_name, '--portal', portal_ip, '--login'])
logged_in = True
if check_surfaced_luns is not None:
retries = 10
pattern = f'ip-{portal_ip}:3260-iscsi-{target_name}-lun-*'
by_path = Path('/dev/disk/by-path')
while retries:
luns = set(int(p.name.split('-')[-1]) for p in by_path.glob(pattern))
if luns == check_surfaced_luns:
break
time.sleep(1)
retries -= 1
assert check_surfaced_luns == luns, luns
except RunOnRunnerException:
return False
except AssertionError:
return False
else:
run_on_runner(iscsiadm + ['-m', 'node', '--targetname', target_name, '--portal', portal_ip, '--logout'])
return True
finally:
if logged_in:
run_on_runner(iscsiadm + ['-m', 'node', '--targetname', target_name, '--portal', portal_ip, '--logout'])


@contextlib.contextmanager
Expand All @@ -109,7 +127,7 @@ def iscsi_client_freebsd():
run_on_runner(['service', 'iscsid', 'onestop'])


def target_login_impl_freebsd(portal_ip, target_name):
def target_login_impl_freebsd(portal_ip, target_name, check_surfaced_luns=None):
run_on_runner(['iscsictl', '-A', '-p', portal_ip, '-t', target_name], check=False)
retries = 5
connected = False
Expand All @@ -128,11 +146,20 @@ def target_login_impl_freebsd(portal_ip, target_name):

assert connected is True, connected_clients

if check_surfaced_luns is not None:
luns = set()
for session in connected_clients.get('iscsictl', {}).get('session', []):
if session.get('name') == target_name and session.get('state') == 'Connected':
for lun in session.get('devices', {}).get('lun'):
if lun_val := lun.get('lun'):
luns.add(lun_val)
assert check_surfaced_luns == luns, luns


def target_login_test_freebsd(portal_ip, target_name):
def target_login_test_freebsd(portal_ip, target_name, check_surfaced_luns=None):
with iscsi_client_freebsd():
try:
target_login_impl_freebsd(portal_ip, target_name)
target_login_impl_freebsd(portal_ip, target_name, check_surfaced_luns)
except AssertionError:
return False
else:
Expand Down
37 changes: 29 additions & 8 deletions tests/api2/test_261_iscsi_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,21 @@
import ipaddress
import os
import random
import requests
import socket
import string
import sys
from time import sleep

import iscsi
import pyscsi
import pytest
from pyscsi.pyscsi.scsi_sense import sense_ascq_dict
from pytest_dependency import depends

apifolder = os.getcwd()
sys.path.append(apifolder)

import requests
from middlewared.service_exception import ValidationError, ValidationErrors
from middlewared.test.integration.assets.iscsi import target_login_test
from middlewared.test.integration.assets.pool import dataset, snapshot
from middlewared.test.integration.utils import call
from pyscsi.pyscsi.scsi_sense import sense_ascq_dict
from pytest_dependency import depends

from auto_config import ha, hostname, isns_ip, pool_name
from functions import SSH_TEST
from protocols import (initiator_name_supported, iscsi_scsi_connection,
Expand Down Expand Up @@ -2728,6 +2725,30 @@ def test_target_sizes(ipaddr):
test_target_sizes(controller2_ip)


def test_33_no_lun_zero():
"""
Verify that an iSCSI client can login to a target that is missing LUN 0 (and LUN 1)
and that report LUNs works as expected.
"""
iqn = f'{basename}:{target_name}'
with initiator_portal() as config:
portal_id = config['portal']['id']
with target(target_name, [{'portal': portal_id}]) as target_config:
target_id = target_config['id']
with dataset(dataset_name):
with file_extent(pool_name, dataset_name, "target.extent1", filesize=MB_100, extent_name="extent1") as extent1_config:
with file_extent(pool_name, dataset_name, "target.extent2", filesize=MB_256, extent_name="extent2") as extent2_config:
with target_extent_associate(target_id, extent1_config['id'], 100):
with target_extent_associate(target_id, extent2_config['id'], 101):
# libiscsi sends a TUR to the lun on connect, so cannot properly test using it.
# Let's actually login and check that the expected LUNs surface.
assert target_login_test(get_ip_addr(ip), iqn, {100, 101})

# With libiscsi we can also check that the expected LUNs are there
with iscsi_scsi_connection(ip, iqn, 100) as s:
_verify_luns(s, [100, 101])


def test_99_teardown(request):
# Disable iSCSI service
depends(request, ["iscsi_cmd_00"])
Expand Down

0 comments on commit eecaea0

Please sign in to comment.