1
0
Fork 0

Merging upstream version 2.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-16 12:15:45 +01:00
parent 888be815c6
commit e4376063b0
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
521 changed files with 21541 additions and 21644 deletions

View file

@ -1,48 +0,0 @@
###############################################################################
#
# Makefile : Allows user to run testcases, generate documentation, and
# perform static code analysis.
#
###############################################################################
NOSE2_OPTIONS="--verbose"
help: all
all:
@echo "Usage:"
@echo
@echo " make run - Run all testcases."
@echo " make doc - Generate Documentation."
@echo " make cleanall - removes *pyc, documentation."
@echo " make static_check- runs pep8, flake8, pylint on code."
doc:
@epydoc -v --output=Documentation *.py
run:
@for i in `ls *.py`; \
do \
echo "Running $${i}"; \
TESTCASE_NAME=`echo $${i} | cut -f 1 -d '.'`; \
nose2 ${NOSE2_OPTIONS} $${TESTCASE_NAME}; \
done
static_check:
@for i in `ls *.py`; \
do \
echo "Pylint :- " ; \
printf "%10s " $${i}; \
pylint $${i} 2>&1 | grep "^Your code" | awk '{print $$7}';\
echo "--------------------------------------------";\
pep8 $${i}; \
echo "pep8 :- "; \
echo "flake8 :- "; \
flake8 $${i}; \
done
cleanall: clean
@rm -fr *.pyc Documentation
clean:
@rm -fr *.pyc

View file

@ -11,18 +11,16 @@ nvmetests
1. Common Package Dependencies
------------------------------
1. Python(>= 2.7.5 or >= 3.3)
2. nose(http://nose.readthedocs.io/en/latest/)
3. nose2(Installation guide http://nose2.readthedocs.io/)
4. pep8(https://pypi.python.org/pypi/setuptools-pep8)
5. flake8(https://pypi.python.org/pypi/flake8)
6. pylint(https://www.pylint.org/)
7. Epydoc(http://epydoc.sourceforge.net/)
8. nvme-cli(https://github.com/linux-nvme/nvme-cli.git)
1. Python(>= 3.3)
2. nose2 (Installation guide http://nose2.readthedocs.io/)
3. flake8 (https://pypi.python.org/pypi/flake8)
4. mypy (https://pypi.org/project/mypy/)
5. autopep8 (https://pypi.org/project/autopep8/)
6. isort (https://pypi.org/project/isort/)
Python package management system pip can be used to install most of the
listed packages(https://pip.pypa.io/en/stable/installing/) :-
$ pip install nose nose2 pep8 flake8 pylint epydoc
$ pip install nose2 flake8 mypy autopep8 isort
2. Overview
-----------
@ -76,12 +74,12 @@ nvmetests
6. Before writing a new function have a look into TestNVMe to see if it
can be reused.
7. Once testcase is ready make sure :-
a. Run pep8, flake8, pylint on the testcase and fix errors/warnings.
-Example "$ make static_check" will run pep8, flake8 and pylint on
all the python files in current directory.
b. Execute make doc to generate the documentation.
-Example "$ make doc" will create and update existing
documentation.
a. Run flake8, mypy, autopep8 and isort on the testcase and fix
errors/warnings.
- Example "$ ninja -C .build lint-python" will run flake8 and
mypy on all the python files in current directory.
- Example "$ ninja -C .build format-python" will run autopep8 and
isort on all the python files in the current directory.
4. Running testcases with framework
-----------------------------------
@ -89,5 +87,5 @@ nvmetests
$ nose2 --verbose nvme_writezeros_test
$ nose2 --verbose nvme_read_write_test
2. Running all the testcases with Makefile :-
$ make run
2. Running all the testcases with ninja :-
$ ninja test -C .build

79
tests/meson.build Normal file
View file

@ -0,0 +1,79 @@
tests = [
'nvme_attach_detach_ns_test',
'nvme_compare_test',
'nvme_create_max_ns_test',
'nvme_error_log_test',
'nvme_flush_test',
'nvme_format_test',
'nvme_fw_log_test',
'nvme_get_features_test',
'nvme_id_ctrl_test',
'nvme_id_ns_test',
'nvme_read_write_test',
'nvme_simple_template_test',
'nvme_smart_log_test',
'nvme_test_io',
'nvme_test_logger',
'nvme_test',
'nvme_writeuncor_test',
'nvme_writezeros_test',
'nvme_copy_test',
'nvme_dsm_test',
'nvme_verify_test',
'nvme_lba_status_log_test',
'nvme_get_lba_status_test',
]
runtests = find_program('nose2', required : false)
if runtests.found()
foreach t : tests
test(t, runtests,
args: ['--verbose', '--start-dir', meson.current_source_dir(), t],
workdir: meson.current_source_dir(),
env: ['PATH=' + meson.build_root() + ':/usr/bin:/usr/sbin'],
timeout: 500)
endforeach
endif
python_module = import('python')
python = python_module.find_installation('python3')
mypy = find_program(
'mypy',
required : false,
)
flake8 = find_program(
'flake8',
required : false,
)
linter_script = files('run_py_linters.py')
if mypy.found() and flake8.found()
run_target(
'lint-python',
command : [python, linter_script, 'lint'],
)
else
message('Mypy or Flake8 not found. Python linting disabled')
endif
autopep8 = find_program(
'autopep8',
required : false,
)
isort = find_program(
'isort',
required : false,
)
if autopep8.found() and isort.found()
run_target(
'format-python',
command : [python, linter_script, 'format'],
)
else
message('autopep8 or isort not found. Python formating disabled')
endif

View file

@ -28,6 +28,7 @@ NVMe Namespace Management Testcase:-
"""
import time
from nose.tools import assert_equal
from nvme_test import TestNVMe

60
tests/nvme_copy_test.py Normal file
View file

@ -0,0 +1,60 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of nvme-cli
#
# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
#
# Author: Arunpandian J <apj.arun@samsung.com>
"""
NVMe Copy Testcase:-
1. Issue copy command on set of block; shall pass.
"""
from nose.tools import assert_equal
from nvme_test import TestNVMe
class TestNVMeCopy(TestNVMe):
"""
Represents NVMe Verify testcase.
- Attributes:
- start_block : starting block of to verify operation.
- range : Range of blocks for DSM operation.
- slbs : 64-bit addr of first block per range
- test_log_dir : directory for logs, temp files.
"""
def __init__(self):
""" Pre Section for TestNVMeCopy """
TestNVMe.__init__(self)
self.start_block = 0
self.range = 1
self.slbs = 1
self.namespace = 1
self.setup_log_dir(self.__class__.__name__)
def __del__(self):
""" Post Section for TestNVMeCopy """
TestNVMe.__del__(self)
def copy(self):
""" Wrapper for nvme copy
- Args:
- None
- Returns:
- return code for nvme copy command.
"""
copy_cmd = "nvme copy " + self.ctrl + \
" --namespace-id=" + str(self.namespace) + \
" --sdlba=" + str(self.start_block) + \
" --blocks=" + str(self.range) + \
" --slbs=" + str(self.range)
return self.exec_cmd(copy_cmd)
def test_copy(self):
""" Testcase main """
assert_equal(self.copy(), 0)

View file

@ -28,6 +28,7 @@ NVMe Namespace Management Testcase:-
"""
import time
from nose.tools import assert_equal
from nvme_test import TestNVMe
@ -50,7 +51,8 @@ class TestNVMeCreateMaxNS(TestNVMe):
TestNVMe.__init__(self)
self.dps = 0
self.flbas = 0
self.nsze = int(self.get_ncap() / self.get_format() / self.get_max_ns())
self.nsze = int(self.get_ncap() /
self.get_format() / self.get_max_ns())
self.ncap = self.nsze
self.setup_log_dir(self.__class__.__name__)
self.max_ns = self.get_max_ns()

57
tests/nvme_dsm_test.py Normal file
View file

@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of nvme-cli
#
# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
#
# Author: Arunpandian J <apj.arun@samsung.com>
"""
NVMe DSM Testcase:-
1. Issue DSM command on set of block; shall pass.
"""
from nose.tools import assert_equal
from nvme_test import TestNVMe
class TestNVMeDsm(TestNVMe):
"""
Represents NVMe Verify testcase.
- Attributes:
- start_block : starting block of to verify operation.
- range : Range of blocks for DSM operation.
- test_log_dir : directory for logs, temp files.
"""
def __init__(self):
""" Pre Section for TestNVMeDsm """
TestNVMe.__init__(self)
self.start_block = 0
self.range = 0
self.namespace = 1
self.setup_log_dir(self.__class__.__name__)
def __del__(self):
""" Post Section for TestNVMeDsm """
TestNVMe.__del__(self)
def dsm(self):
""" Wrapper for nvme verify
- Args:
- None
- Returns:
- return code for nvme dsm command.
"""
dsm_cmd = "nvme dsm " + self.ctrl + \
" --namespace-id=" + str(self.namespace) + \
" --blocks=" + str(self.range) + \
" --slbs=" + str(self.start_block)
return self.exec_cmd(dsm_cmd)
def test_dsm(self):
""" Testcase main """
assert_equal(self.dsm(), 0)

View file

@ -35,8 +35,9 @@ Namespace Format testcase :-
- Delete Namespace.
"""
import time
import subprocess
import time
from nose.tools import assert_equal
from nvme_test import TestNVMe
@ -130,8 +131,8 @@ class TestNVMeFormatCmd(TestNVMe):
# iterate through all supported format
for i in range(0, len(self.lba_format_list)):
print("\nlba format " + str(self.lba_format_list[i]) + \
" lbad " + str(self.lbads_list[i]) + \
print("\nlba format " + str(self.lba_format_list[i]) +
" lbad " + str(self.lbads_list[i]) +
" ms " + str(self.ms_list[i]))
metadata_size = 1 if self.ms_list[i] == '8' else 0
err = self.create_and_validate_ns(self.default_nsid,

View file

@ -25,6 +25,7 @@ NVMe Firmware Log Testcase :-
"""
import subprocess
from nose.tools import assert_equal
from nvme_test import TestNVMe
@ -62,7 +63,7 @@ class TestNVMeFwLogCmd(TestNVMe):
stdout=subprocess.PIPE,
encoding='utf-8')
fw_log_output = proc.communicate()[0]
print(fw_log_output + "\n")
print("\n" + fw_log_output + "\n")
err = proc.wait()
return err

View file

@ -33,6 +33,7 @@ Test the Mandatory features with get features command:-
"""
import subprocess
from nose.tools import assert_equal
from nvme_test import TestNVMe

View file

@ -0,0 +1,71 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of nvme-cli
#
# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
#
# Author: Arunpandian J <apj.arun@samsung.com>
"""
NVMe LBA Status Log Testcase :-
1. Execute get-lba-status on a device.
"""
import subprocess
from nose.tools import assert_equal
from nvme_test import TestNVMe
class TestNVMeGetLbaStatusCmd(TestNVMe):
"""
Represents Get LBA Status test.
"""
def __init__(self):
""" Pre Section for TestNVMeGetLbaStatusCmd. """
TestNVMe.__init__(self)
self.start_lba = 0
self.block_count = 0
self.namespace = 1
self.max_dw = 1
self.action = 11
self.range_len = 1
self.setup_log_dir(self.__class__.__name__)
def __del__(self):
"""
Post Section for TestNVMeGetLbaStatusCmd.
- Call super class's destructor.
"""
TestNVMe.__del__(self)
def get_lba_status(self):
""" Wrapper for executing nvme get-lba-status.
- Args:
- None
- Returns:
- 0 on success, error code on failure.
"""
err = 0
get_lba_status_cmd = "nvme get-lba-status " + self.ctrl + \
" --namespace-id=" + str(self.namespace) + \
" --start-lba=" + str(self.start_lba) + \
" --max-dw=" + str(self.max_dw) + \
" --action=" + str(self.action) + \
" --range-len=" + str(self.range_len)
proc = subprocess.Popen(get_lba_status_cmd,
shell=True,
stdout=subprocess.PIPE,
encoding='utf-8')
get_lba_status_output = proc.communicate()[0]
print("\n" + get_lba_status_output + "\n")
err = proc.wait()
return err
def test_get_lba_status(self):
""" Testcase main """
assert_equal(self.get_lba_status(), 0)

View file

@ -26,6 +26,7 @@ NVme Identify Namespace Testcase:-
"""
import subprocess
from nose.tools import assert_equal
from nvme_test import TestNVMe
@ -78,7 +79,7 @@ class TestNVMeIdentifyNamespace(TestNVMe):
- 0 on success, error code on failure.
"""
err = 0
for namespace in self.ns_list:
for namespace in self.ns_list:
err = self.get_id_ns(str(namespace))
return err

View file

@ -0,0 +1,60 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of nvme-cli
#
# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
#
# Author: Arunpandian J <apj.arun@samsung.com>
"""
NVMe LBA Status Log Testcase :-
1. Execute lba-status-log on a device.
"""
import subprocess
from nose.tools import assert_equal
from nvme_test import TestNVMe
class TestNVMeLbaStatLogCmd(TestNVMe):
"""
Represents LBA Status Log test.
"""
def __init__(self):
""" Pre Section for TestNVMeLbaStatLogCmd. """
TestNVMe.__init__(self)
self.setup_log_dir(self.__class__.__name__)
def __del__(self):
"""
Post Section for TestNVMeLbaStatLogCmd.
- Call super class's destructor.
"""
TestNVMe.__del__(self)
def get_lba_stat_log(self):
""" Wrapper for executing nvme lba-status-log.
- Args:
- None
- Returns:
- 0 on success, error code on failure.
"""
err = 0
lba_stat_log_cmd = "nvme lba-status-log " + self.ctrl
proc = subprocess.Popen(lba_stat_log_cmd,
shell=True,
stdout=subprocess.PIPE,
encoding='utf-8')
lba_stat_log_output = proc.communicate()[0]
print("\n" + lba_stat_log_output + "\n")
err = proc.wait()
return err
def test_lba_stat_log(self):
""" Testcase main """
assert_equal(self.get_lba_stat_log(), 0)

View file

@ -27,6 +27,7 @@ NVMe Read/Write Testcae:-
"""
import filecmp
from nose.tools import assert_equal
from nvme_test_io import TestNVMeIO
@ -41,6 +42,7 @@ class TestNVMeReadWriteTest(TestNVMeIO):
- compare_file : data file to use in nvme compare command.
- test_log_dir : directory for logs, temp files.
"""
def __init__(self):
""" Pre Section for TestNVMeReadWriteTest """
TestNVMeIO.__init__(self)

View file

@ -83,4 +83,6 @@ class TestNVMeSmartLogCmd(TestNVMe):
def test_smart_log(self):
""" Testcase main """
assert_equal(self.get_smart_log_ctrl(), 0)
assert_equal(self.get_smart_log_all_ns(), 0)
smlp = self.supp_check_id_ctrl("lpa")
if smlp & 0x1 == True:
assert_equal(self.get_smart_log_all_ns(), 0)

View file

@ -20,15 +20,16 @@
""" Base class for all the testcases
"""
import re
import os
import sys
import json
import mmap
import stat
import time
import os
import re
import shutil
import stat
import subprocess
import sys
import time
from nose import tools
from nose.tools import assert_equal
from nvme_test_logger import TestNVMeLogger
@ -477,3 +478,26 @@ class TestNVMe(object):
encoding='utf-8')
run_io_result = run_io.communicate()[1]
assert_equal(run_io_result, None)
def supp_check_id_ctrl(self, key):
""" Wrapper for support check.
- Args:
- key : search key.
- Returns:
- value for key requested.
"""
id_ctrl = "nvme id-ctrl " + self.ctrl
print("\n" + id_ctrl)
proc = subprocess.Popen(id_ctrl,
shell=True,
stdout=subprocess.PIPE,
encoding='utf-8')
err = proc.wait()
assert_equal(err, 0, "ERROR : nvme Identify controller Data \
structure failed")
for line in proc.stdout:
if key in line:
key = line.replace(",", "", 1)
print(key)
val = (key.split(':'))[1].strip()
return int(val, 16)

View file

@ -20,6 +20,7 @@
""" Inherit TestNVMeIO for nvme read/write operations """
import os
from nose import tools
from nvme_test import TestNVMe

View file

@ -26,6 +26,7 @@ import sys
class TestNVMeLogger(object):
""" Represents Logger for NVMe Testframework. """
def __init__(self, log_file_path):
""" Logger setup
- Args:

56
tests/nvme_verify_test.py Normal file
View file

@ -0,0 +1,56 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# This file is part of nvme-cli
#
# Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
#
# Author: Arunpandian J <apj.arun@samsung.com>
"""
NVMe Verify Testcase:-
1. Issue verify command on set of block; shall pass.
"""
from nose.tools import assert_equal
from nvme_test import TestNVMe
class TestNVMeVerify(TestNVMe):
"""
Represents NVMe Verify testcase.
- Attributes:
- start_block : starting block of to verify operation.
- test_log_dir : directory for logs, temp files.
"""
def __init__(self):
""" Pre Section for TestNVMeVerify """
TestNVMe.__init__(self)
self.start_block = 0
self.block_count = 0
self.namespace = 1
self.setup_log_dir(self.__class__.__name__)
def __del__(self):
""" Post Section for TestNVMeVerify """
TestNVMe.__del__(self)
def verify(self):
""" Wrapper for nvme verify
- Args:
- None
- Returns:
- return code for nvme verify command.
"""
verify_cmd = "nvme verify " + self.ctrl + \
" --namespace-id=" + str(self.namespace) + \
" --start-block=" + str(self.start_block) + \
" --block-count=" + str(self.block_count)
return self.exec_cmd(verify_cmd)
def test_verify(self):
""" Testcase main """
assert_equal(self.verify(), 0)

View file

@ -28,6 +28,7 @@ NVMe Write Zeros:-
"""
import filecmp
from nose.tools import assert_equal
from nvme_test_io import TestNVMeIO
@ -44,6 +45,7 @@ class TestNVMeWriteZeros(TestNVMeIO):
- block_count: Number of blocks to use in IO.
- test_log_dir : directory for logs, temp files.
"""
def __init__(self):
""" Pre Section for TestNVMeWriteZeros """
TestNVMeIO.__init__(self)

123
tests/run_py_linters.py Normal file
View file

@ -0,0 +1,123 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Copied from https://github.com/python-sdbus/python-sdbus
# Copyright (C) 2020, 2021 igo95862
# This file is part of nvme-cli
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
from __future__ import annotations
from argparse import ArgumentParser
from os import environ
from pathlib import Path
from subprocess import run
from typing import List
source_root = Path(environ['MESON_SOURCE_ROOT'])
build_dir = Path(environ['MESON_BUILD_ROOT'])
tests_dir = source_root / 'tests'
all_python_modules = [
tests_dir,
]
mypy_cache_dir = build_dir / '.mypy_cache'
def run_mypy(path: Path) -> None:
print(f"Running mypy on {path}")
run(
args=(
'mypy', '--strict',
'--cache-dir', mypy_cache_dir,
'--python-version', '3.8',
'--namespace-packages',
'--ignore-missing-imports',
path,
),
check=False,
env={'MYPYPATH': str(tests_dir.absolute()), **environ},
)
def linter_main() -> None:
run(
args=(
'flake8',
*all_python_modules,
),
check=False,
)
for x in all_python_modules:
run_mypy(x)
def get_all_python_files() -> List[Path]:
python_files: List[Path] = []
for python_module in all_python_modules:
if python_module.is_dir():
for a_file in python_module.iterdir():
if a_file.suffix == '.py':
python_files.append(a_file)
else:
python_files.append(python_module)
return python_files
def formater_main() -> None:
all_python_files = get_all_python_files()
run(
args=('autopep8', '--in-place', *all_python_files),
check=False,
)
run(
args=(
'isort',
'-m', 'VERTICAL_HANGING_INDENT',
'--trailing-comma',
*all_python_files,
),
check=False,
)
def main() -> None:
parser = ArgumentParser()
parser.add_argument(
'mode',
choices=('lint', 'format'),
)
args = parser.parse_args()
mode = args.mode
if mode == 'lint':
linter_main()
elif mode == 'format':
formater_main()
else:
raise ValueError('Unknown mode', mode)
if __name__ == '__main__':
main()