Skip to content

Commit 42ae4db

Browse files
committed
tests: Fix SCSI debug disks setup and cleanup in SMART tests
Multiple fixes including avoiding infinite loops in cleanup, retries for the module unloading and moving common code for the two plugin implementation tests to utils.
1 parent 011f6cc commit 42ae4db

File tree

3 files changed

+63
-68
lines changed

3 files changed

+63
-68
lines changed

tests/smart_test.py

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import unittest
22
import os
3-
import glob
4-
import time
53
import overrides_hack
64

7-
from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, TestTags, tag_test, write_file, run_command, required_plugins
5+
from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, TestTags, tag_test, required_plugins, setup_scsi_debug, clean_scsi_debug
86

97
import gi
108
gi.require_version('GLib', '2.0')
@@ -59,29 +57,6 @@ def _clean_loop(self):
5957
pass
6058
os.unlink(self.loop_dev_file)
6159

62-
def _setup_scsi_debug(self):
63-
res, _out, _err = run_command('modprobe scsi_debug')
64-
self.assertEqual(res, 0)
65-
dirs = []
66-
while len(dirs) < 1:
67-
dirs = glob.glob('/sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block')
68-
time.sleep(0.1)
69-
self.scsi_debug_dev = os.listdir(dirs[0])
70-
self.assertEqual(len(self.scsi_debug_dev), 1)
71-
self.scsi_debug_dev = '/dev/' + self.scsi_debug_dev[0]
72-
self.assertTrue(os.path.exists(self.scsi_debug_dev))
73-
74-
def _clean_scsi_debug(self):
75-
try:
76-
device = self.scsi_debug_dev.split('/')[-1]
77-
if os.path.exists('/sys/block/' + device):
78-
self.write_file('/sys/block/%s/device/delete' % device, '1')
79-
while os.path.exists(device):
80-
time.sleep(0.1)
81-
self.run_command('modprobe -r scsi_debug')
82-
except:
83-
pass
84-
8560
@tag_test(TestTags.NOSTORAGE)
8661
def test_plugin_version(self):
8762
self.assertEqual(BlockDev.get_plugin_soname(BlockDev.Plugin.SMART), "libbd_smart.so.3")
@@ -110,8 +85,8 @@ def test_ata_info(self):
11085
BlockDev.smart_ata_get_info(self.loop_dev)
11186

11287
# scsi_debug
113-
self._setup_scsi_debug()
114-
self.addCleanup(self._clean_scsi_debug)
88+
self.scsi_debug_dev = setup_scsi_debug()
89+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
11590
with self.assertRaisesRegex(GLib.GError, msg):
11691
BlockDev.smart_ata_get_info(self.scsi_debug_dev)
11792

@@ -144,8 +119,8 @@ def test_smart_enable_disable(self):
144119
BlockDev.smart_set_enabled(self.loop_dev, True)
145120

146121
# scsi_debug
147-
self._setup_scsi_debug()
148-
self.addCleanup(self._clean_scsi_debug)
122+
self.scsi_debug_dev = setup_scsi_debug()
123+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
149124
with self.assertRaisesRegex(GLib.GError, msg):
150125
BlockDev.smart_set_enabled(self.scsi_debug_dev, False)
151126
with self.assertRaisesRegex(GLib.GError, msg):
@@ -182,8 +157,8 @@ def test_smart_selftest(self):
182157
BlockDev.smart_device_self_test(self.loop_dev, t)
183158

184159
# scsi_debug
185-
self._setup_scsi_debug()
186-
self.addCleanup(self._clean_scsi_debug)
160+
self.scsi_debug_dev = setup_scsi_debug()
161+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
187162
for t in tests:
188163
with self.assertRaisesRegex(GLib.GError, msg):
189164
BlockDev.smart_device_self_test(self.scsi_debug_dev, t)
@@ -199,6 +174,7 @@ def test_scsi_info(self):
199174

200175
# LIO device (SCSI)
201176
self._setup_lio()
177+
self.addCleanup(self._clean_lio)
202178
with self.assertRaisesRegex(GLib.GError, msg):
203179
BlockDev.smart_scsi_get_info(self.lio_dev)
204180

@@ -209,8 +185,8 @@ def test_scsi_info(self):
209185
BlockDev.smart_scsi_get_info(self.loop_dev)
210186

211187
# scsi_debug
212-
self._setup_scsi_debug()
213-
self.addCleanup(self._clean_scsi_debug)
188+
self.scsi_debug_dev = setup_scsi_debug()
189+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
214190
with self.assertRaisesRegex(GLib.GError, msg):
215191
BlockDev.smart_scsi_get_info(self.scsi_debug_dev)
216192

tests/smartmontools_test.py

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import unittest
22
import os
3-
import glob
4-
import time
53
import shutil
64
import overrides_hack
75

8-
from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, TestTags, tag_test, write_file, run_command, required_plugins
6+
from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, TestTags, tag_test, required_plugins, setup_scsi_debug, clean_scsi_debug
97

108
import gi
119
gi.require_version('GLib', '2.0')
@@ -59,29 +57,6 @@ def _clean_loop(self):
5957
pass
6058
os.unlink(self.loop_dev_file)
6159

62-
def _setup_scsi_debug(self):
63-
res, _out, _err = run_command('modprobe scsi_debug')
64-
self.assertEqual(res, 0)
65-
dirs = []
66-
while len(dirs) < 1:
67-
dirs = glob.glob('/sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block')
68-
time.sleep(0.1)
69-
self.scsi_debug_dev = os.listdir(dirs[0])
70-
self.assertEqual(len(self.scsi_debug_dev), 1)
71-
self.scsi_debug_dev = '/dev/' + self.scsi_debug_dev[0]
72-
self.assertTrue(os.path.exists(self.scsi_debug_dev))
73-
74-
def _clean_scsi_debug(self):
75-
try:
76-
device = self.scsi_debug_dev.split('/')[-1]
77-
if os.path.exists('/sys/block/' + device):
78-
self.write_file('/sys/block/%s/device/delete' % device, '1')
79-
while os.path.exists(device):
80-
time.sleep(0.1)
81-
self.run_command('modprobe -r scsi_debug')
82-
except:
83-
pass
84-
8560
@tag_test(TestTags.NOSTORAGE)
8661
def test_plugin_version(self):
8762
self.assertEqual(BlockDev.get_plugin_soname(BlockDev.Plugin.SMART), "libbd_smartmontools.so.3")
@@ -132,8 +107,8 @@ def test_ata_info(self):
132107
BlockDev.smart_ata_get_info(self.loop_dev, [BlockDev.ExtraArg.new("--device=ata", "")])
133108

134109
# scsi_debug
135-
self._setup_scsi_debug()
136-
self.addCleanup(self._clean_scsi_debug)
110+
self.scsi_debug_dev = setup_scsi_debug()
111+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
137112
msg = r"Error parsing smartctl JSON data: The member .ata_smart_data. is not defined in the object at the current position."
138113
with self.assertRaisesRegex(GLib.GError, msg):
139114
BlockDev.smart_ata_get_info(self.scsi_debug_dev, None)
@@ -280,8 +255,8 @@ def test_smart_enable_disable(self):
280255
BlockDev.smart_set_enabled(self.loop_dev, True, [BlockDev.ExtraArg.new("--device=ata", "")])
281256

282257
# scsi_debug
283-
self._setup_scsi_debug()
284-
self.addCleanup(self._clean_scsi_debug)
258+
self.scsi_debug_dev = setup_scsi_debug()
259+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
285260
BlockDev.smart_set_enabled(self.scsi_debug_dev, False)
286261
BlockDev.smart_set_enabled(self.scsi_debug_dev, True)
287262
BlockDev.smart_set_enabled(self.scsi_debug_dev, False, [BlockDev.ExtraArg.new("--device=scsi", "")])
@@ -344,8 +319,8 @@ def test_smart_selftest(self):
344319
BlockDev.smart_device_self_test(self.loop_dev, t, [BlockDev.ExtraArg.new("--device=scsi", "")])
345320

346321
# scsi_debug
347-
self._setup_scsi_debug()
348-
self.addCleanup(self._clean_scsi_debug)
322+
self.scsi_debug_dev = setup_scsi_debug()
323+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
349324
for t in [BlockDev.SmartSelfTestOp.OFFLINE, BlockDev.SmartSelfTestOp.SHORT,
350325
BlockDev.SmartSelfTestOp.LONG, BlockDev.SmartSelfTestOp.CONVEYANCE,
351326
BlockDev.SmartSelfTestOp.ABORT]:
@@ -374,6 +349,7 @@ def test_scsi_info(self):
374349

375350
# LIO device (SCSI)
376351
self._setup_lio()
352+
self.addCleanup(self._clean_lio)
377353
msg = r"Error getting SCSI SMART info: Some SMART or other ATA command to the disk failed, or there was a checksum error in a SMART data structure."
378354
with self.assertRaisesRegex(GLib.GError, msg):
379355
BlockDev.smart_scsi_get_info(self.lio_dev, None)
@@ -396,8 +372,8 @@ def test_scsi_info(self):
396372
BlockDev.smart_scsi_get_info(self.loop_dev, [BlockDev.ExtraArg.new("--device=ata", "")])
397373

398374
# scsi_debug
399-
self._setup_scsi_debug()
400-
self.addCleanup(self._clean_scsi_debug)
375+
self.scsi_debug_dev = setup_scsi_debug()
376+
self.addCleanup(clean_scsi_debug, self.scsi_debug_dev)
401377
msg = r"Error getting SCSI SMART info: Some SMART or other ATA command to the disk failed, or there was a checksum error in a SMART data structure."
402378
with self.assertRaisesRegex(GLib.GError, msg):
403379
BlockDev.smart_scsi_get_info(self.scsi_debug_dev, None)

tests/utils.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,49 @@ def delete_lio_device(dev_path):
231231
else:
232232
raise RuntimeError("Unknown device '%s'" % dev_path)
233233

234+
235+
def setup_scsi_debug():
236+
res, out, err = run_command('modprobe scsi_debug')
237+
if res != 0:
238+
raise RuntimeError("Failed to load scsi_debug module: %s %s" % (out, err))
239+
dirs = []
240+
n_tries = 0
241+
while len(dirs) < 1 and n_tries < 5:
242+
dirs = glob.glob('/sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block')
243+
time.sleep(0.5)
244+
n_tries += 1
245+
if len(dirs) < 1:
246+
raise RuntimeError("Failed to setup SCSI debug device for testing")
247+
scsi_debug_dev = os.listdir(dirs[0])
248+
if len(scsi_debug_dev) != 1:
249+
raise RuntimeError("Failed to setup SCSI debug device for testing")
250+
251+
scsi_debug_dev = '/dev/' + scsi_debug_dev[0]
252+
if not os.path.exists(scsi_debug_dev):
253+
raise RuntimeError("Failed to setup SCSI debug device for testing")
254+
255+
return scsi_debug_dev
256+
257+
258+
def clean_scsi_debug(scsi_debug_dev):
259+
try:
260+
device = scsi_debug_dev.split('/')[-1]
261+
if os.path.exists('/sys/block/' + device):
262+
write_file('/sys/block/%s/device/delete' % device, '1')
263+
n_tries = 0
264+
while os.path.exists(device) and n_tries < 5:
265+
time.sleep(0.5)
266+
n_tries += 1
267+
n_tries = 0
268+
while n_tries < 5:
269+
res, _out, _err = run_command('modprobe -r scsi_debug')
270+
if res == 0:
271+
break
272+
time.sleep(0.5)
273+
n_tries += 1
274+
except:
275+
pass
276+
234277
def find_nvme_ctrl_devs_for_subnqn(subnqn):
235278
"""
236279
Find NVMe controller devices for the specified subsystem nqn

0 commit comments

Comments
 (0)