Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / rbd / set_ro.py
1 #!/usr/bin/env python
2
3 import logging
4 import subprocess
5 import sys
6
7 logging.basicConfig(level=logging.DEBUG)
8 log = logging.getLogger()
9
10 def run_command(args, except_on_error=True):
11     log.debug('running command "%s"', ' '.join(args))
12     proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13     out, err = proc.communicate()
14     if out:
15         log.debug('stdout: %s', out)
16     if err:
17         log.debug('stderr: %s', err)
18     if proc.returncode:
19         log.debug('ret: %d', proc.returncode)
20         if except_on_error:
21             raise subprocess.CalledProcessError(proc.returncode, ' '.join(args))
22     return (proc.returncode, out, err)
23
24 def setup(image_name):
25     run_command(['rbd', 'create', '-s', '100', image_name])
26     run_command(['rbd', 'snap', 'create', image_name + '@snap'])
27     run_command(['rbd', 'map', image_name])
28     run_command(['rbd', 'map', image_name + '@snap'])
29
30 def teardown(image_name, fail_on_error=True):
31     run_command(['rbd', 'unmap', '/dev/rbd/rbd/' + image_name + '@snap'], fail_on_error)
32     run_command(['rbd', 'unmap', '/dev/rbd/rbd/' + image_name], fail_on_error)
33     run_command(['rbd', 'snap', 'rm', image_name + '@snap'], fail_on_error)
34     run_command(['rbd', 'rm', image_name], fail_on_error)
35
36 def write(target, expect_fail=False):
37     try:
38         with open(target, 'w', 0) as f:
39             f.write('test')
40             f.flush()
41         assert not expect_fail, 'writing should have failed'
42     except IOError:
43         assert expect_fail, 'writing should not have failed'
44
45 def test_ro(image_name):
46     dev = '/dev/rbd/rbd/' + image_name
47     snap_dev = dev + '@snap'
48
49     log.info('basic device is readable')
50     write(dev)
51
52     log.info('basic snapshot is read-only')
53     write(snap_dev, True)
54
55     log.info('cannot set snapshot rw')
56     ret, _, _ = run_command(['blockdev', '--setrw', snap_dev], False)
57     assert ret != 0, 'snapshot was set read-write!'
58     run_command(['udevadm', 'settle'])
59     write(snap_dev, True)
60
61     log.info('set device ro')
62     run_command(['blockdev', '--setro', dev])
63     run_command(['udevadm', 'settle'])
64     write(dev, True)
65
66     log.info('cannot set device rw when in-use')
67     with open(dev, 'r') as f:
68         ret, _, _ = run_command(['blockdev', '--setro', dev], False)
69         assert ret != 0, 'in-use device was set read-only!'
70         run_command(['udevadm', 'settle'])
71
72     write(dev, True)
73     run_command(['blockdev', '--setro', dev])
74     run_command(['udevadm', 'settle'])
75     write(dev, True)
76
77     run_command(['blockdev', '--setrw', dev])
78     run_command(['udevadm', 'settle'])
79     write(dev)
80     run_command(['udevadm', 'settle'])
81     run_command(['blockdev', '--setrw', dev])
82     run_command(['udevadm', 'settle'])
83     write(dev)
84
85     log.info('cannot set device ro when in-use')
86     with open(dev, 'r') as f:
87         ret, _, _ = run_command(['blockdev', '--setro', dev], False)
88         assert ret != 0, 'in-use device was set read-only!'
89         run_command(['udevadm', 'settle'])
90
91     run_command(['rbd', 'unmap', '/dev/rbd/rbd/' + image_name])
92     run_command(['rbd', 'map', '--read-only', image_name])
93
94     log.info('cannot write to newly mapped ro device')
95     write(dev, True)
96
97     log.info('can set ro mapped device rw')
98     run_command(['blockdev', '--setrw', dev])
99     run_command(['udevadm', 'settle'])
100     write(dev)
101
102 def main():
103     image_name = 'test1'
104     # clean up any state from previous test runs
105     teardown(image_name, False)
106     setup(image_name)
107
108     test_ro(image_name)
109
110     teardown(image_name)
111
112 if __name__ == '__main__':
113     main()