Merging upstream version 2.11.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
6f6d3e85f8
commit
0f2367f2fa
533 changed files with 9033 additions and 4835 deletions
|
@ -52,8 +52,10 @@ class TestNVMeAttachDetachNSCmd(TestNVMe):
|
|||
super().setUp()
|
||||
self.dps = 0
|
||||
self.flbas = 0
|
||||
self.nsze = 0x1400000
|
||||
self.ncap = 0x1400000
|
||||
(ds, ms) = self.get_lba_format_size()
|
||||
ncap = int(self.get_ncap() / (ds+ms))
|
||||
self.nsze = ncap
|
||||
self.ncap = ncap
|
||||
self.setup_log_dir(self.__class__.__name__)
|
||||
self.ctrl_id = self.get_ctrl_id()
|
||||
self.delete_all_ns()
|
||||
|
|
|
@ -45,9 +45,20 @@ class TestNVMeCompareCmd(TestNVMeIO):
|
|||
- test_log_dir : directory for logs, temp files.
|
||||
"""
|
||||
|
||||
def compare_cmd_supported(self):
|
||||
""" Wrapper for extracting optional NVM 'compare' command support
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- True if 'compare' is supported, otherwise False
|
||||
"""
|
||||
return int(self.get_id_ctrl_field_value("oncs"), 16) & (1 << 0)
|
||||
|
||||
def setUp(self):
|
||||
""" Pre Section for TestNVMeCompareCmd """
|
||||
super().setUp()
|
||||
if not self.compare_cmd_supported():
|
||||
self.skipTest("because: Optional NVM Command 'Compare' (NVMCMPS) not supported")
|
||||
self.data_size = 1024
|
||||
self.start_block = 1023
|
||||
self.setup_log_dir(self.__class__.__name__)
|
||||
|
|
|
@ -36,6 +36,7 @@ class TestNVMeCopy(TestNVMe):
|
|||
super().setUp()
|
||||
print("\nSetting up test...")
|
||||
self.ocfs = self.get_ocfs()
|
||||
self.host_behavior_data = None
|
||||
cross_namespace_copy = self.ocfs & 0xc
|
||||
if cross_namespace_copy:
|
||||
# get host behavior support data
|
||||
|
|
|
@ -54,6 +54,10 @@ class TestNVMeCreateMaxNS(TestNVMe):
|
|||
self.flbas = 0
|
||||
self.nsze = int(self.get_ncap() /
|
||||
self.get_format() / self.get_max_ns())
|
||||
# Make sure that we have enough capacity for each ns.
|
||||
# Creating a ns might allocate more bits (NVMCAP) than specified by
|
||||
# nsze and ncap.
|
||||
self.nsze = int(self.nsze / 2)
|
||||
self.ncap = self.nsze
|
||||
self.setup_log_dir(self.__class__.__name__)
|
||||
self.max_ns = self.get_max_ns()
|
||||
|
@ -75,11 +79,12 @@ class TestNVMeCreateMaxNS(TestNVMe):
|
|||
self.flbas,
|
||||
self.dps), 0)
|
||||
self.attach_ns(self.ctrl_id, self.default_nsid)
|
||||
super.tearDown()
|
||||
super().tearDown()
|
||||
|
||||
def test_attach_detach_ns(self):
|
||||
""" Testcase main """
|
||||
for nsid in range(1, self.max_ns):
|
||||
print(f"##### Testing max_ns: {self.max_ns}")
|
||||
for nsid in range(1, self.max_ns + 1):
|
||||
print("##### Creating " + str(nsid))
|
||||
err = self.create_and_validate_ns(nsid,
|
||||
self.nsze,
|
||||
|
@ -90,9 +95,9 @@ class TestNVMeCreateMaxNS(TestNVMe):
|
|||
print("##### Attaching " + str(nsid))
|
||||
self.assertEqual(self.attach_ns(self.ctrl_id, nsid), 0)
|
||||
print("##### Running IOs in " + str(nsid))
|
||||
self.run_ns_io(nsid, 0)
|
||||
self.run_ns_io(nsid, 9, 1)
|
||||
|
||||
for nsid in range(1, self.max_ns):
|
||||
for nsid in range(1, self.max_ns + 1):
|
||||
print("##### Detaching " + str(nsid))
|
||||
self.assertEqual(self.detach_ns(self.ctrl_id, nsid), 0)
|
||||
print("#### Deleting " + str(nsid))
|
||||
|
|
|
@ -46,3 +46,5 @@ class TestNVMeCtrlReset(TestNVMe):
|
|||
def test_ctrl_reset(self):
|
||||
""" Testcase main """
|
||||
self.assertEqual(self.ctrl_reset(), 0)
|
||||
# Check if sqs and cqs are setup again and I/O operations are possible
|
||||
self.run_ns_io(self.default_nsid, 0, 10)
|
||||
|
|
|
@ -37,6 +37,7 @@ Namespace Format testcase :-
|
|||
- Delete Namespace.
|
||||
"""
|
||||
|
||||
import math
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
|
@ -63,10 +64,14 @@ class TestNVMeFormatCmd(TestNVMe):
|
|||
def setUp(self):
|
||||
""" Pre Section for TestNVMeFormatCmd """
|
||||
super().setUp()
|
||||
self.dps = 0 # ns data protection settings
|
||||
self.flbas = 0 # ns formattes logical block settings
|
||||
self.nsze = 0x1400000 # ns size
|
||||
self.ncap = 0x1400000 # ns capacity
|
||||
self.dps = 0
|
||||
self.flbas = 0
|
||||
# Assuming run_ns_io with 4KiB * 10 writes.
|
||||
# Calculating minimum required ncap for this workload
|
||||
(ds, _) = self.get_lba_format_size()
|
||||
ncap = int(math.ceil((4096*10)/ds))
|
||||
self.ncap = ncap
|
||||
self.nsze = ncap
|
||||
self.ctrl_id = self.get_ctrl_id()
|
||||
self.lba_format_list = []
|
||||
self.ms_list = []
|
||||
|
|
|
@ -94,6 +94,8 @@ class TestNVMeGetMandatoryFeatures(TestNVMe):
|
|||
else:
|
||||
get_feat_cmd = "nvme get-feature " + self.ctrl + \
|
||||
" --feature-id=" + str(feature_id) + " -H"
|
||||
if str(feature_id) == "0x05":
|
||||
get_feat_cmd += f" --namespace-id={self.default_nsid}"
|
||||
proc = subprocess.Popen(get_feat_cmd,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
|
|
|
@ -26,11 +26,12 @@ class TestNVMeGetLbaStatusCmd(TestNVMe):
|
|||
def setUp(self):
|
||||
""" Pre Section for TestNVMeGetLbaStatusCmd. """
|
||||
super().setUp()
|
||||
if not self.get_lba_status_supported():
|
||||
self.skipTest("because: Optional Admin Command 'Get LBA Status' (OACS->GLSS) not supported")
|
||||
self.start_lba = 0
|
||||
self.block_count = 0
|
||||
self.namespace = 1
|
||||
self.max_dw = 1
|
||||
self.action = 11
|
||||
self.action = 0x11
|
||||
self.range_len = 1
|
||||
self.setup_log_dir(self.__class__.__name__)
|
||||
|
||||
|
@ -51,7 +52,7 @@ class TestNVMeGetLbaStatusCmd(TestNVMe):
|
|||
"""
|
||||
err = 0
|
||||
get_lba_status_cmd = "nvme get-lba-status " + self.ctrl + \
|
||||
" --namespace-id=" + str(self.namespace) + \
|
||||
" --namespace-id=" + str(self.ns1) + \
|
||||
" --start-lba=" + str(self.start_lba) + \
|
||||
" --max-dw=" + str(self.max_dw) + \
|
||||
" --action=" + str(self.action) + \
|
||||
|
|
|
@ -26,6 +26,8 @@ class TestNVMeLbaStatLogCmd(TestNVMe):
|
|||
def setUp(self):
|
||||
""" Pre Section for TestNVMeLbaStatLogCmd. """
|
||||
super().setUp()
|
||||
if not self.get_lba_status_supported():
|
||||
self.skipTest("because: Optional Admin Command 'Get LBA Status' (OACS->GLSS) not supported")
|
||||
self.setup_log_dir(self.__class__.__name__)
|
||||
|
||||
def tearDown(self):
|
||||
|
|
|
@ -85,5 +85,5 @@ class TestNVMeSmartLogCmd(TestNVMe):
|
|||
""" Testcase main """
|
||||
self.assertEqual(self.get_smart_log_ctrl(), 0)
|
||||
smlp = self.supp_check_id_ctrl("lpa")
|
||||
if smlp & 0x1 == True:
|
||||
if smlp & 0x1:
|
||||
self.assertEqual(self.get_smart_log_all_ns(), 0)
|
||||
|
|
|
@ -70,6 +70,30 @@ class TestNVMe(unittest.TestCase):
|
|||
""" Post Section for TestNVMe. """
|
||||
if self.clear_log_dir is True:
|
||||
shutil.rmtree(self.log_dir, ignore_errors=True)
|
||||
self.create_and_attach_default_ns()
|
||||
|
||||
def create_and_attach_default_ns(self):
|
||||
""" Creates a default namespace with the full capacity of the ctrls NVM
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- None
|
||||
"""
|
||||
self.dps = 0
|
||||
self.flbas = 0
|
||||
(ds, ms) = self.get_lba_format_size()
|
||||
ncap = int(self.get_ncap() / (ds+ms))
|
||||
self.nsze = ncap
|
||||
self.ncap = ncap
|
||||
self.ctrl_id = self.get_ctrl_id()
|
||||
self.delete_all_ns()
|
||||
err = self.create_and_validate_ns(self.default_nsid,
|
||||
self.nsze,
|
||||
self.ncap,
|
||||
self.flbas,
|
||||
self.dps)
|
||||
self.assertEqual(err, 0)
|
||||
self.assertEqual(self.attach_ns(self.ctrl_id, self.default_nsid), 0)
|
||||
|
||||
def validate_pci_device(self):
|
||||
""" Validate underlying device belongs to pci subsystem.
|
||||
|
@ -147,22 +171,23 @@ class TestNVMe(unittest.TestCase):
|
|||
self.assertEqual(proc.wait(), 0, "ERROR : pci rescan failed")
|
||||
|
||||
def get_ctrl_id(self):
|
||||
""" Wrapper for extracting the controller id.
|
||||
""" Wrapper for extracting the first controller id.
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- controller id.
|
||||
"""
|
||||
get_ctrl_id = "nvme list-ctrl " + self.ctrl
|
||||
get_ctrl_id = f"nvme list-ctrl {self.ctrl} --output-format=json"
|
||||
proc = subprocess.Popen(get_ctrl_id,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
err = proc.wait()
|
||||
self.assertEqual(err, 0, "ERROR : nvme list-ctrl failed")
|
||||
line = proc.stdout.readline()
|
||||
ctrl_id = line.split(":")[1].strip()
|
||||
return ctrl_id
|
||||
json_output = json.loads(proc.stdout.read())
|
||||
self.assertTrue(len(json_output['ctrl_list']) > 0,
|
||||
"ERROR : nvme list-ctrl could not find ctrl")
|
||||
return str(json_output['ctrl_list'][0]['ctrl_id'])
|
||||
|
||||
def get_ns_list(self):
|
||||
""" Wrapper for extracting the namespace list.
|
||||
|
@ -207,6 +232,43 @@ class TestNVMe(unittest.TestCase):
|
|||
print(max_ns)
|
||||
return int(max_ns)
|
||||
|
||||
def get_lba_status_supported(self):
|
||||
""" Check if 'Get LBA Status' command is supported by the device
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- True if 'Get LBA Status' command is supported, otherwise False
|
||||
"""
|
||||
return int(self.get_id_ctrl_field_value("oacs"), 16) & (1 << 9)
|
||||
|
||||
def get_lba_format_size(self):
|
||||
""" Wrapper for extracting lba format size of the given flbas
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- lba format size as a tuple of (data_size, metadata_size) in bytes.
|
||||
"""
|
||||
nvme_id_ns_cmd = f"nvme id-ns {self.ns1} --output-format=json"
|
||||
proc = subprocess.Popen(nvme_id_ns_cmd,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
err = proc.wait()
|
||||
self.assertEqual(err, 0, "ERROR : reading id-ns")
|
||||
json_output = json.loads(proc.stdout.read())
|
||||
self.assertTrue(len(json_output['lbafs']) > self.flbas,
|
||||
"Error : could not match the given flbas to an existing lbaf")
|
||||
lbaf_json = json_output['lbafs'][int(self.flbas)]
|
||||
ms_expo = int(lbaf_json['ms'])
|
||||
ds_expo = int(lbaf_json['ds'])
|
||||
ds = 0
|
||||
ms = 0
|
||||
if ds_expo > 0:
|
||||
ds = (1 << ds_expo)
|
||||
if ms_expo > 0:
|
||||
ms = (1 << ms_expo)
|
||||
return (ds, ms)
|
||||
|
||||
def get_ncap(self):
|
||||
""" Wrapper for extracting capacity.
|
||||
- Args:
|
||||
|
@ -231,6 +293,25 @@ class TestNVMe(unittest.TestCase):
|
|||
print(ncap)
|
||||
return int(ncap)
|
||||
|
||||
def get_id_ctrl_field_value(self, field):
|
||||
""" Wrapper for extracting id-ctrl field values
|
||||
- Args:
|
||||
- None
|
||||
- Returns:
|
||||
- Filed value of the given field
|
||||
"""
|
||||
id_ctrl_cmd = f"nvme id-ctrl {self.ctrl} --output-format=json"
|
||||
proc = subprocess.Popen(id_ctrl_cmd,
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
err = proc.wait()
|
||||
self.assertEqual(err, 0, "ERROR : reading id-ctrl failed")
|
||||
json_output = json.loads(proc.stdout.read())
|
||||
self.assertTrue(field in json_output,
|
||||
f"ERROR : reading field '{field}' failed")
|
||||
return str(json_output[field])
|
||||
|
||||
def get_ocfs(self):
|
||||
""" Wrapper for extracting optional copy formats supported
|
||||
- Args:
|
||||
|
@ -238,11 +319,7 @@ class TestNVMe(unittest.TestCase):
|
|||
- Returns:
|
||||
- Optional Copy Formats Supported
|
||||
"""
|
||||
pattern = re.compile(r'^ocfs\s*: 0x[0-9a-fA-F]+$')
|
||||
output = subprocess.check_output(["nvme", "id-ctrl", self.ctrl], encoding='utf-8')
|
||||
ocfs_line = next(line for line in output.splitlines() if pattern.match(line))
|
||||
ocfs = ocfs_line.split(":")[1].strip()
|
||||
return int(ocfs, 16)
|
||||
return int(self.get_id_ctrl_field_value("ocfs"), 16)
|
||||
|
||||
def get_format(self):
|
||||
""" Wrapper for extracting format.
|
||||
|
@ -391,25 +468,8 @@ class TestNVMe(unittest.TestCase):
|
|||
encoding='utf-8')
|
||||
err = proc.wait()
|
||||
self.assertEqual(err, 0, "ERROR : nvme smart log failed")
|
||||
|
||||
for line in proc.stdout:
|
||||
if "data_units_read" in line:
|
||||
data_units_read = \
|
||||
line.replace(",", "", 1)
|
||||
if "data_units_written" in line:
|
||||
data_units_written = \
|
||||
line.replace(",", "", 1)
|
||||
if "host_read_commands" in line:
|
||||
host_read_commands = \
|
||||
line.replace(",", "", 1)
|
||||
if "host_write_commands" in line:
|
||||
host_write_commands = \
|
||||
line.replace(",", "", 1)
|
||||
|
||||
print("data_units_read " + data_units_read)
|
||||
print("data_units_written " + data_units_written)
|
||||
print("host_read_commands " + host_read_commands)
|
||||
print("host_write_commands " + host_write_commands)
|
||||
smart_log_output = proc.communicate()[0]
|
||||
print(f"{smart_log_output}")
|
||||
return err
|
||||
|
||||
def get_id_ctrl(self, vendor=False):
|
||||
|
@ -422,7 +482,7 @@ class TestNVMe(unittest.TestCase):
|
|||
if not vendor:
|
||||
id_ctrl_cmd = "nvme id-ctrl " + self.ctrl
|
||||
else:
|
||||
id_ctrl_cmd = "nvme id-ctrl -v " + self.ctrl
|
||||
id_ctrl_cmd = "nvme id-ctrl --vendor-specific " + self.ctrl
|
||||
print(id_ctrl_cmd)
|
||||
proc = subprocess.Popen(id_ctrl_cmd,
|
||||
shell=True,
|
||||
|
@ -439,7 +499,7 @@ class TestNVMe(unittest.TestCase):
|
|||
- Returns:
|
||||
- 0 on success, error code on failure.
|
||||
"""
|
||||
pattern = re.compile("^ Entry\[[ ]*[0-9]+\]")
|
||||
pattern = re.compile(r"^ Entry\[[ ]*[0-9]+\]")
|
||||
error_log_cmd = "nvme error-log " + self.ctrl
|
||||
proc = subprocess.Popen(error_log_cmd,
|
||||
shell=True,
|
||||
|
@ -456,7 +516,7 @@ class TestNVMe(unittest.TestCase):
|
|||
|
||||
return 0 if err_log_entry_count == entry_count else 1
|
||||
|
||||
def run_ns_io(self, nsid, lbads):
|
||||
def run_ns_io(self, nsid, lbads, count=10):
|
||||
""" Wrapper to run ios on namespace under test.
|
||||
- Args:
|
||||
- lbads : LBA Data size supported in power of 2 format.
|
||||
|
@ -466,14 +526,14 @@ class TestNVMe(unittest.TestCase):
|
|||
block_size = mmap.PAGESIZE if int(lbads) < 9 else 2 ** int(lbads)
|
||||
ns_path = self.ctrl + "n" + str(nsid)
|
||||
io_cmd = "dd if=" + ns_path + " of=/dev/null" + " bs=" + \
|
||||
str(block_size) + " count=10 > /dev/null 2>&1"
|
||||
str(block_size) + " count=" + str(count) + " > /dev/null 2>&1"
|
||||
print(io_cmd)
|
||||
run_io = subprocess.Popen(io_cmd, shell=True, stdout=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
run_io_result = run_io.communicate()[1]
|
||||
self.assertEqual(run_io_result, None)
|
||||
io_cmd = "dd if=/dev/zero of=" + ns_path + " bs=" + \
|
||||
str(block_size) + " count=10 > /dev/null 2>&1"
|
||||
str(block_size) + " count=" + str(count) + " > /dev/null 2>&1"
|
||||
print(io_cmd)
|
||||
run_io = subprocess.Popen(io_cmd, shell=True, stdout=subprocess.PIPE,
|
||||
encoding='utf-8')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue