Skip to content

Commit 604fa34

Browse files
Copilotigaw
andauthored
tests: replace config.json with CLI args in tap_runner; add --destructive flag
- tap_runner.py: add --controller, --namespace, --log-dir, --nvme-bin, --debug, --no-pci-validate, --destructive CLI args; each falls back to the corresponding NVME_TESTS_* env var; args are propagated as env vars for nvme_test.py to read; fix exit code to reflect test pass/fail - nvme_test.py: load_config() now treats config.json as optional fallback; NVME_TESTS_* env vars (set by tap_runner) always override config.json; add destructive = False class attribute; skip destructive tests unless NVME_TESTS_DESTRUCTIVE=1; skip gracefully when no device is configured; drop unused mmap import - nvme_{compare,copy,ctrl_reset,dsm,format,read_write,writeuncor,writezeros} _test.py: set destructive = True so they are skipped by default - meson_options.txt: add nvme-tests-{controller,namespace,log-dir,bin,destructive} options for configuring hardware tests at meson setup time - tests/meson.build: remove config.json from infra list; build extra args for tap_runner from the new meson options - run-nightly-tests.yml: replace config.json generation with meson setup -D options; use absolute log dir path /nvme-cli/tests/nvmetests/ to fix artifact upload after the switch to meson (meson runs tests from the build dir, so a relative path resolved to .build-ci/tests/nvmetests/) Agent-Logs-Url: https://github.com/linux-nvme/nvme-cli/sessions/9541e0d9-7570-4a69-9907-c871a0cd3cf9 Co-authored-by: igaw <[email protected]>
1 parent 48b4976 commit 604fa34

13 files changed

Lines changed: 192 additions & 42 deletions

.github/workflows/run-nightly-tests.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,19 @@ jobs:
100100
cd /nvme-cli
101101
git checkout ${{ github.sha }}
102102
CONTROLLER=$(echo "${BDEV0}" | sed 's/n[0-9]*$//')
103-
cat > tests/config.json << EOJ
104-
{
105-
"controller" : "${CONTROLLER}",
106-
"ns1": "${BDEV0}",
107-
"log_dir": "tests/nvmetests/",
108-
"nvme_bin": "/nvme-cli/.build-ci/nvme"
109-
}
110-
EOJ
111-
cat tests/config.json
112-
113-
scripts/build.sh -b release -c gcc tests
103+
104+
CC=gcc meson setup \
105+
--werror \
106+
--buildtype=release \
107+
-Dnvme-tests=true \
108+
-Dnvme-tests-controller="${CONTROLLER}" \
109+
-Dnvme-tests-namespace="${BDEV0}" \
110+
-Dnvme-tests-log-dir="/nvme-cli/tests/nvmetests/" \
111+
-Dnvme-tests-bin="/nvme-cli/.build-ci/nvme" \
112+
-Dnvme-tests-destructive=true \
113+
.build-ci
114+
meson compile -C .build-ci
115+
meson test -C .build-ci
114116
EOF
115117
116118
sudo chmod +x test.sh

meson_options.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,36 @@ option(
6565
value : false,
6666
description: 'Run tests against real hardware'
6767
)
68+
option(
69+
'nvme-tests-controller',
70+
type : 'string',
71+
value : '',
72+
description: 'NVMe controller device for tests (e.g. /dev/nvme0)'
73+
)
74+
option(
75+
'nvme-tests-namespace',
76+
type : 'string',
77+
value : '',
78+
description: 'NVMe namespace device for tests (e.g. /dev/nvme0n1)'
79+
)
80+
option(
81+
'nvme-tests-log-dir',
82+
type : 'string',
83+
value : 'nvmetests/',
84+
description: 'Log directory for nvme-cli hardware tests'
85+
)
86+
option(
87+
'nvme-tests-bin',
88+
type : 'string',
89+
value : '',
90+
description: 'Path to nvme binary used by tests (default: nvme from PATH)'
91+
)
92+
option(
93+
'nvme-tests-destructive',
94+
type : 'boolean',
95+
value : false,
96+
description: 'Enable destructive (write) tests against real hardware'
97+
)
6898
option(
6999
'tests',
70100
type : 'boolean',

tests/meson.build

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
# Authors: Daniel Wagner <[email protected]>
77

88
infra = [
9-
'config.json',
109
'nvme_test.py',
1110
'nvme_test_io.py',
1211
'nvme_test_logger.py',
@@ -41,16 +40,47 @@ python_module = import('python')
4140

4241
python = python_module.find_installation('python3')
4342

43+
# Build the list of extra arguments for tap_runner.py from meson options.
44+
# Callers configure device paths at setup time, e.g.:
45+
# meson setup .build -Dnvme-tests=true \
46+
# -Dnvme-tests-controller=/dev/nvme0 \
47+
# -Dnvme-tests-namespace=/dev/nvme0n1 \
48+
# -Dnvme-tests-destructive=true
49+
nvme_test_args = [
50+
meson.current_source_dir() / 'tap_runner.py',
51+
'--start-dir', meson.current_source_dir(),
52+
]
53+
54+
nvme_tests_controller = get_option('nvme-tests-controller')
55+
if nvme_tests_controller != ''
56+
nvme_test_args += ['--controller', nvme_tests_controller]
57+
endif
58+
59+
nvme_tests_namespace = get_option('nvme-tests-namespace')
60+
if nvme_tests_namespace != ''
61+
nvme_test_args += ['--namespace', nvme_tests_namespace]
62+
endif
63+
64+
nvme_tests_log_dir = get_option('nvme-tests-log-dir')
65+
if nvme_tests_log_dir != ''
66+
nvme_test_args += ['--log-dir', nvme_tests_log_dir]
67+
endif
68+
69+
nvme_tests_bin = get_option('nvme-tests-bin')
70+
if nvme_tests_bin != ''
71+
nvme_test_args += ['--nvme-bin', nvme_tests_bin]
72+
endif
73+
74+
if get_option('nvme-tests-destructive')
75+
nvme_test_args += ['--destructive']
76+
endif
77+
4478
foreach t : tests
4579
t_name = t.split('.')[0]
4680
test(
4781
'nvme-cli - @0@'.format(t_name),
4882
python,
49-
args: [
50-
meson.current_source_dir() / 'tap_runner.py',
51-
'--start-dir', meson.current_source_dir(),
52-
t_name,
53-
],
83+
args: nvme_test_args + [t_name],
5484
env: ['PATH=' + meson.project_build_root() + ':/usr/bin:/usr/sbin'],
5585
timeout: 500,
5686
protocol: 'tap',

tests/nvme_compare_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class TestNVMeCompareCmd(TestNVMeIO):
4646
- test_log_dir : directory for logs, temp files.
4747
"""
4848

49+
destructive = True
50+
4951
def compare_cmd_supported(self):
5052
""" Wrapper for extracting optional NVM 'compare' command support
5153
- Args:

tests/nvme_copy_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class TestNVMeCopy(TestNVMe):
3131
- test_log_dir : directory for logs, temp files.
3232
"""
3333

34+
destructive = True
35+
3436
def setUp(self):
3537
""" Pre Section for TestNVMeCopy """
3638
super().setUp()

tests/nvme_ctrl_reset_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class TestNVMeCtrlReset(TestNVMe):
2424
- test_log_dir : directory for logs, temp files.
2525
"""
2626

27+
destructive = True
28+
2729
def setUp(self):
2830
""" Pre Section for TestNVMeCtrlReset """
2931
super().setUp()

tests/nvme_dsm_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class TestNVMeDsm(TestNVMe):
2626
- test_log_dir : directory for logs, temp files.
2727
"""
2828

29+
destructive = True
30+
2931
def setUp(self):
3032
""" Pre Section for TestNVMeDsm """
3133
super().setUp()

tests/nvme_format_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class TestNVMeFormatCmd(TestNVMe):
5959
- test_log_dir : directory for logs, temp files.
6060
"""
6161

62+
destructive = True
63+
6264
def setUp(self):
6365
""" Pre Section for TestNVMeFormatCmd """
6466
super().setUp()

tests/nvme_read_write_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class TestNVMeReadWriteTest(TestNVMeIO):
4444
- test_log_dir : directory for logs, temp files.
4545
"""
4646

47+
destructive = True
48+
4749
def setUp(self):
4850
""" Pre Section for TestNVMeReadWriteTest """
4951
super().setUp()

tests/nvme_test.py

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"""
2424

2525
import json
26-
import mmap
2726
import os
2827
import re
2928
import shutil
@@ -63,15 +62,18 @@ class or appropriate subclass which is a child of this class.
6362
- ctrl : NVMe Controller.
6463
- ns1 : default namespace.
6564
- default_nsid : default namespace id.
66-
- config_file : configuration file.
65+
- config_file : configuration file (optional fallback).
6766
- clear_log_dir : default log directory.
67+
- destructive : set to True in subclasses that write device data.
6868
"""
6969

70+
destructive = False
71+
7072
def setUp(self):
7173
""" Pre Section for TestNVMe. """
7274
# common code used in various testcases.
73-
self.ctrl = "XXX"
74-
self.ns1 = "XXX"
75+
self.ctrl = ""
76+
self.ns1 = ""
7577
self.test_log_dir = "XXX"
7678
self.nvme_bin = "nvme"
7779
self.do_validate_pci_device = True
@@ -81,6 +83,16 @@ def setUp(self):
8183
self.config_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json')
8284

8385
self.load_config()
86+
87+
if not self.ctrl:
88+
self.skipTest("no NVMe controller configured; use --controller or config.json")
89+
if not self.ns1:
90+
self.skipTest("no NVMe namespace configured; use --namespace or config.json")
91+
if self.destructive and \
92+
os.environ.get('NVME_TESTS_DESTRUCTIVE', '0') != '1':
93+
self.skipTest("destructive tests are disabled; "
94+
"pass --destructive to tap_runner.py to enable")
95+
8496
if self.do_validate_pci_device:
8597
self.validate_pci_device()
8698
self.ns_mgmt_supported = self.get_ns_mgmt_support()
@@ -136,30 +148,48 @@ def validate_pci_device(self):
136148
self.assertEqual(err, 0, "ERROR : Only NVMe PCI subsystem is supported")
137149

138150
def load_config(self):
139-
""" Load Basic test configuration.
151+
""" Load test configuration from config.json (if present) and
152+
environment variables. Environment variables always take
153+
priority over config.json values.
140154
- Args:
141155
- None
142156
- Returns:
143157
- None
144158
"""
145-
with open(self.config_file) as data_file:
146-
config = json.load(data_file)
147-
self.ctrl = config['controller']
148-
self.ns1 = config['ns1']
149-
self.log_dir = config['log_dir']
150-
self.nvme_bin = config.get('nvme_bin', self.nvme_bin)
151-
self.debug = config.get('debug', False)
152-
if self.debug:
153-
print(f"Using nvme binary '{self.nvme_bin}'")
154-
self.do_validate_pci_device = config.get(
155-
'do_validate_pci_device', self.do_validate_pci_device)
156-
self.clear_log_dir = False
157-
158-
if self.clear_log_dir is True:
159-
shutil.rmtree(self.log_dir, ignore_errors=True)
160-
161-
if not os.path.exists(self.log_dir):
162-
os.makedirs(self.log_dir)
159+
if os.path.exists(self.config_file):
160+
with open(self.config_file) as data_file:
161+
config = json.load(data_file)
162+
self.ctrl = config.get('controller', self.ctrl)
163+
self.ns1 = config.get('ns1', self.ns1)
164+
self.log_dir = config.get('log_dir', 'nvmetests/')
165+
self.nvme_bin = config.get('nvme_bin', self.nvme_bin)
166+
self.debug = config.get('debug', self.debug)
167+
self.do_validate_pci_device = config.get(
168+
'do_validate_pci_device', self.do_validate_pci_device)
169+
else:
170+
self.log_dir = 'nvmetests/'
171+
172+
# Environment variables override config.json values
173+
if os.environ.get('NVME_TESTS_CONTROLLER'):
174+
self.ctrl = os.environ['NVME_TESTS_CONTROLLER']
175+
if os.environ.get('NVME_TESTS_NAMESPACE'):
176+
self.ns1 = os.environ['NVME_TESTS_NAMESPACE']
177+
if os.environ.get('NVME_TESTS_LOG_DIR'):
178+
self.log_dir = os.environ['NVME_TESTS_LOG_DIR']
179+
if os.environ.get('NVME_TESTS_BIN'):
180+
self.nvme_bin = os.environ['NVME_TESTS_BIN']
181+
if os.environ.get('NVME_TESTS_DEBUG'):
182+
self.debug = os.environ['NVME_TESTS_DEBUG'] == '1'
183+
if os.environ.get('NVME_TESTS_SKIP_PCI_VALIDATE') == '1':
184+
self.do_validate_pci_device = False
185+
186+
if self.debug:
187+
print(f"Using nvme binary '{self.nvme_bin}'")
188+
189+
self.clear_log_dir = False
190+
191+
if not os.path.exists(self.log_dir):
192+
os.makedirs(self.log_dir)
163193

164194
def setup_log_dir(self, test_name):
165195
""" Set up the log directory for a testcase

0 commit comments

Comments
 (0)