root / test / py / ganeti.storage.bdev_unittest.py @ 688b5752
History | View | Annotate | Download (13.7 kB)
1 | 3840729d | Iustin Pop | #!/usr/bin/python
|
---|---|---|---|
2 | 3840729d | Iustin Pop | #
|
3 | 3840729d | Iustin Pop | |
4 | 23d95cff | Bernardo Dal Seno | # Copyright (C) 2006, 2007, 2010, 2012, 2013 Google Inc.
|
5 | 3840729d | Iustin Pop | #
|
6 | 3840729d | Iustin Pop | # This program is free software; you can redistribute it and/or modify
|
7 | 3840729d | Iustin Pop | # it under the terms of the GNU General Public License as published by
|
8 | 3840729d | Iustin Pop | # the Free Software Foundation; either version 2 of the License, or
|
9 | 3840729d | Iustin Pop | # (at your option) any later version.
|
10 | 3840729d | Iustin Pop | #
|
11 | 3840729d | Iustin Pop | # This program is distributed in the hope that it will be useful, but
|
12 | 3840729d | Iustin Pop | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 3840729d | Iustin Pop | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 3840729d | Iustin Pop | # General Public License for more details.
|
15 | 3840729d | Iustin Pop | #
|
16 | 3840729d | Iustin Pop | # You should have received a copy of the GNU General Public License
|
17 | 3840729d | Iustin Pop | # along with this program; if not, write to the Free Software
|
18 | 3840729d | Iustin Pop | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 3840729d | Iustin Pop | # 02110-1301, USA.
|
20 | 3840729d | Iustin Pop | |
21 | 3840729d | Iustin Pop | |
22 | 3840729d | Iustin Pop | """Script for unittesting the bdev module"""
|
23 | 3840729d | Iustin Pop | |
24 | 3840729d | Iustin Pop | |
25 | 6634816b | Iustin Pop | import os |
26 | 23d95cff | Bernardo Dal Seno | import random |
27 | 3840729d | Iustin Pop | import unittest |
28 | 3840729d | Iustin Pop | |
29 | 23d95cff | Bernardo Dal Seno | from ganeti import compat |
30 | 8a69b3a8 | Andrea Spadaccini | from ganeti import constants |
31 | 23d95cff | Bernardo Dal Seno | from ganeti import errors |
32 | 23d95cff | Bernardo Dal Seno | from ganeti import objects |
33 | fbdac0d9 | Michael Hanselmann | from ganeti import utils |
34 | cde49218 | Helga Velroyen | from ganeti.storage import bdev |
35 | 3840729d | Iustin Pop | |
36 | 25231ec5 | Michael Hanselmann | import testutils |
37 | 25231ec5 | Michael Hanselmann | |
38 | 3840729d | Iustin Pop | |
39 | 7181fba0 | Constantinos Venetsanopoulos | class TestRADOSBlockDevice(testutils.GanetiTestCase): |
40 | 2e076ede | Stratos Psomadakis | def setUp(self): |
41 | 2e076ede | Stratos Psomadakis | """Set up input data"""
|
42 | 2e076ede | Stratos Psomadakis | testutils.GanetiTestCase.setUp(self)
|
43 | 2e076ede | Stratos Psomadakis | |
44 | 2e076ede | Stratos Psomadakis | self.plain_output_old_ok = \
|
45 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_old_ok.txt")
|
46 | 2e076ede | Stratos Psomadakis | self.plain_output_old_no_matches = \
|
47 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_old_no_matches.txt")
|
48 | 2e076ede | Stratos Psomadakis | self.plain_output_old_extra_matches = \
|
49 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_old_extra_matches.txt")
|
50 | 2e076ede | Stratos Psomadakis | self.plain_output_old_empty = \
|
51 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_old_empty.txt")
|
52 | 2e076ede | Stratos Psomadakis | self.plain_output_new_ok = \
|
53 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_new_ok.txt")
|
54 | 2e076ede | Stratos Psomadakis | self.plain_output_new_no_matches = \
|
55 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_new_no_matches.txt")
|
56 | 2e076ede | Stratos Psomadakis | self.plain_output_new_extra_matches = \
|
57 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/plain_output_new_extra_matches.txt")
|
58 | 2e076ede | Stratos Psomadakis | # This file is completely empty, and as such it's not shipped.
|
59 | 2e076ede | Stratos Psomadakis | self.plain_output_new_empty = "" |
60 | 2e076ede | Stratos Psomadakis | self.json_output_ok = testutils.ReadTestData("bdev-rbd/json_output_ok.txt") |
61 | 2e076ede | Stratos Psomadakis | self.json_output_no_matches = \
|
62 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/json_output_no_matches.txt")
|
63 | 2e076ede | Stratos Psomadakis | self.json_output_extra_matches = \
|
64 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/json_output_extra_matches.txt")
|
65 | 2e076ede | Stratos Psomadakis | self.json_output_empty = \
|
66 | 2e076ede | Stratos Psomadakis | testutils.ReadTestData("bdev-rbd/json_output_empty.txt")
|
67 | 2e076ede | Stratos Psomadakis | self.output_invalid = testutils.ReadTestData("bdev-rbd/output_invalid.txt") |
68 | 2e076ede | Stratos Psomadakis | |
69 | 2e076ede | Stratos Psomadakis | self.volume_name = "d7ab910a-4933-4ffe-88d0-faf2ce31390a.rbd.disk0" |
70 | 2e076ede | Stratos Psomadakis | |
71 | 2e076ede | Stratos Psomadakis | def test_ParseRbdShowmappedJson(self): |
72 | 2e076ede | Stratos Psomadakis | parse_function = bdev.RADOSBlockDevice._ParseRbdShowmappedJson |
73 | 2e076ede | Stratos Psomadakis | |
74 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.json_output_ok, self.volume_name), |
75 | 2e076ede | Stratos Psomadakis | "/dev/rbd3")
|
76 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.json_output_empty, self.volume_name), |
77 | 2e076ede | Stratos Psomadakis | None)
|
78 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.json_output_no_matches, |
79 | 2e076ede | Stratos Psomadakis | self.volume_name), None) |
80 | 7181fba0 | Constantinos Venetsanopoulos | self.assertRaises(errors.BlockDeviceError, parse_function,
|
81 | 2e076ede | Stratos Psomadakis | self.json_output_extra_matches, self.volume_name) |
82 | 7181fba0 | Constantinos Venetsanopoulos | self.assertRaises(errors.BlockDeviceError, parse_function,
|
83 | 2e076ede | Stratos Psomadakis | self.output_invalid, self.volume_name) |
84 | 2e076ede | Stratos Psomadakis | |
85 | 2e076ede | Stratos Psomadakis | def test_ParseRbdShowmappedPlain(self): |
86 | 2e076ede | Stratos Psomadakis | parse_function = bdev.RADOSBlockDevice._ParseRbdShowmappedPlain |
87 | 2e076ede | Stratos Psomadakis | |
88 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_new_ok, |
89 | 2e076ede | Stratos Psomadakis | self.volume_name), "/dev/rbd3") |
90 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_old_ok, |
91 | 2e076ede | Stratos Psomadakis | self.volume_name), "/dev/rbd3") |
92 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_new_empty, |
93 | 2e076ede | Stratos Psomadakis | self.volume_name), None) |
94 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_old_empty, |
95 | 2e076ede | Stratos Psomadakis | self.volume_name), None) |
96 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_new_no_matches, |
97 | 2e076ede | Stratos Psomadakis | self.volume_name), None) |
98 | 2e076ede | Stratos Psomadakis | self.assertEqual(parse_function(self.plain_output_old_no_matches, |
99 | 2e076ede | Stratos Psomadakis | self.volume_name), None) |
100 | 2e076ede | Stratos Psomadakis | self.assertRaises(errors.BlockDeviceError, parse_function,
|
101 | 2e076ede | Stratos Psomadakis | self.plain_output_new_extra_matches, self.volume_name) |
102 | 2e076ede | Stratos Psomadakis | self.assertRaises(errors.BlockDeviceError, parse_function,
|
103 | 2e076ede | Stratos Psomadakis | self.plain_output_old_extra_matches, self.volume_name) |
104 | 2e076ede | Stratos Psomadakis | self.assertRaises(errors.BlockDeviceError, parse_function,
|
105 | 2e076ede | Stratos Psomadakis | self.output_invalid, self.volume_name) |
106 | 7181fba0 | Constantinos Venetsanopoulos | |
107 | 23e3c9b7 | Michael Hanselmann | class TestComputeWrongFileStoragePathsInternal(unittest.TestCase): |
108 | 23e3c9b7 | Michael Hanselmann | def testPaths(self): |
109 | 23e3c9b7 | Michael Hanselmann | paths = bdev._GetForbiddenFileStoragePaths() |
110 | 23e3c9b7 | Michael Hanselmann | |
111 | 23e3c9b7 | Michael Hanselmann | for path in ["/bin", "/usr/local/sbin", "/lib64", "/etc", "/sys"]: |
112 | 23e3c9b7 | Michael Hanselmann | self.assertTrue(path in paths) |
113 | 23e3c9b7 | Michael Hanselmann | |
114 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(set(map(os.path.normpath, paths)), paths) |
115 | 23e3c9b7 | Michael Hanselmann | |
116 | 23e3c9b7 | Michael Hanselmann | def test(self): |
117 | 23e3c9b7 | Michael Hanselmann | vfsp = bdev._ComputeWrongFileStoragePaths |
118 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(vfsp([]), [])
|
119 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(vfsp(["/tmp"]), []) |
120 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(vfsp(["/bin/ls"]), ["/bin/ls"]) |
121 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(vfsp(["/bin"]), ["/bin"]) |
122 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(vfsp(["/usr/sbin/vim", "/srv/file-storage"]), |
123 | 23e3c9b7 | Michael Hanselmann | ["/usr/sbin/vim"])
|
124 | 23e3c9b7 | Michael Hanselmann | |
125 | 23e3c9b7 | Michael Hanselmann | |
126 | 23e3c9b7 | Michael Hanselmann | class TestComputeWrongFileStoragePaths(testutils.GanetiTestCase): |
127 | 23e3c9b7 | Michael Hanselmann | def test(self): |
128 | 23e3c9b7 | Michael Hanselmann | tmpfile = self._CreateTempFile()
|
129 | 23e3c9b7 | Michael Hanselmann | |
130 | 23e3c9b7 | Michael Hanselmann | utils.WriteFile(tmpfile, data="""
|
131 | 23e3c9b7 | Michael Hanselmann | /tmp
|
132 | 23e3c9b7 | Michael Hanselmann | x/y///z/relative
|
133 | 23e3c9b7 | Michael Hanselmann | # This is a test file
|
134 | 23e3c9b7 | Michael Hanselmann | /srv/storage
|
135 | 23e3c9b7 | Michael Hanselmann | /bin
|
136 | 23e3c9b7 | Michael Hanselmann | /usr/local/lib32/
|
137 | 23e3c9b7 | Michael Hanselmann | relative/path
|
138 | 23e3c9b7 | Michael Hanselmann | """)
|
139 | 23e3c9b7 | Michael Hanselmann | |
140 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(bdev.ComputeWrongFileStoragePaths(_filename=tmpfile), [
|
141 | 23e3c9b7 | Michael Hanselmann | "/bin",
|
142 | 23e3c9b7 | Michael Hanselmann | "/usr/local/lib32",
|
143 | 23e3c9b7 | Michael Hanselmann | "relative/path",
|
144 | 23e3c9b7 | Michael Hanselmann | "x/y/z/relative",
|
145 | 23e3c9b7 | Michael Hanselmann | ]) |
146 | 23e3c9b7 | Michael Hanselmann | |
147 | 23e3c9b7 | Michael Hanselmann | |
148 | 23e3c9b7 | Michael Hanselmann | class TestCheckFileStoragePathInternal(unittest.TestCase): |
149 | fbdac0d9 | Michael Hanselmann | def testNonAbsolute(self): |
150 | fbdac0d9 | Michael Hanselmann | for i in ["", "tmp", "foo/bar/baz"]: |
151 | fbdac0d9 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
152 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath, i, ["/tmp"])
|
153 | fbdac0d9 | Michael Hanselmann | |
154 | fbdac0d9 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
155 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath, "/tmp", ["tmp", "xyz"]) |
156 | fbdac0d9 | Michael Hanselmann | |
157 | fbdac0d9 | Michael Hanselmann | def testNoAllowed(self): |
158 | fbdac0d9 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
159 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath, "/tmp", [])
|
160 | fbdac0d9 | Michael Hanselmann | |
161 | fbdac0d9 | Michael Hanselmann | def testNoAdditionalPathComponent(self): |
162 | fbdac0d9 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
163 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath, "/tmp/foo", ["/tmp/foo"]) |
164 | fbdac0d9 | Michael Hanselmann | |
165 | fbdac0d9 | Michael Hanselmann | def testAllowed(self): |
166 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath("/tmp/foo/a", ["/tmp/foo"]) |
167 | fbdac0d9 | Michael Hanselmann | bdev._CheckFileStoragePath("/tmp/foo/a/x", ["/tmp/foo"]) |
168 | fbdac0d9 | Michael Hanselmann | |
169 | fbdac0d9 | Michael Hanselmann | |
170 | 23e3c9b7 | Michael Hanselmann | class TestCheckFileStoragePath(testutils.GanetiTestCase): |
171 | 23e3c9b7 | Michael Hanselmann | def testNonExistantFile(self): |
172 | 23e3c9b7 | Michael Hanselmann | filename = "/tmp/this/file/does/not/exist"
|
173 | 23e3c9b7 | Michael Hanselmann | assert not os.path.exists(filename) |
174 | 23e3c9b7 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
175 | 23e3c9b7 | Michael Hanselmann | bdev.CheckFileStoragePath, "/bin/", _filename=filename)
|
176 | 23e3c9b7 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
177 | 23e3c9b7 | Michael Hanselmann | bdev.CheckFileStoragePath, "/srv/file-storage",
|
178 | 23e3c9b7 | Michael Hanselmann | _filename=filename) |
179 | 23e3c9b7 | Michael Hanselmann | |
180 | 23e3c9b7 | Michael Hanselmann | def testAllowedPath(self): |
181 | 23e3c9b7 | Michael Hanselmann | tmpfile = self._CreateTempFile()
|
182 | 23e3c9b7 | Michael Hanselmann | |
183 | 23e3c9b7 | Michael Hanselmann | utils.WriteFile(tmpfile, data="""
|
184 | 23e3c9b7 | Michael Hanselmann | /srv/storage
|
185 | 23e3c9b7 | Michael Hanselmann | """)
|
186 | 23e3c9b7 | Michael Hanselmann | |
187 | 23e3c9b7 | Michael Hanselmann | bdev.CheckFileStoragePath("/srv/storage/inst1", _filename=tmpfile)
|
188 | 23e3c9b7 | Michael Hanselmann | |
189 | 23e3c9b7 | Michael Hanselmann | # No additional path component
|
190 | 23e3c9b7 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
191 | 23e3c9b7 | Michael Hanselmann | bdev.CheckFileStoragePath, "/srv/storage",
|
192 | 23e3c9b7 | Michael Hanselmann | _filename=tmpfile) |
193 | 23e3c9b7 | Michael Hanselmann | |
194 | 23e3c9b7 | Michael Hanselmann | # Forbidden path
|
195 | 23e3c9b7 | Michael Hanselmann | self.assertRaises(errors.FileStoragePathError,
|
196 | 23e3c9b7 | Michael Hanselmann | bdev.CheckFileStoragePath, "/usr/lib64/xyz",
|
197 | 23e3c9b7 | Michael Hanselmann | _filename=tmpfile) |
198 | 23e3c9b7 | Michael Hanselmann | |
199 | 23e3c9b7 | Michael Hanselmann | |
200 | fbdac0d9 | Michael Hanselmann | class TestLoadAllowedFileStoragePaths(testutils.GanetiTestCase): |
201 | fbdac0d9 | Michael Hanselmann | def testDevNull(self): |
202 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(bdev._LoadAllowedFileStoragePaths("/dev/null"), []) |
203 | fbdac0d9 | Michael Hanselmann | |
204 | fbdac0d9 | Michael Hanselmann | def testNonExistantFile(self): |
205 | fbdac0d9 | Michael Hanselmann | filename = "/tmp/this/file/does/not/exist"
|
206 | fbdac0d9 | Michael Hanselmann | assert not os.path.exists(filename) |
207 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(bdev._LoadAllowedFileStoragePaths(filename), [])
|
208 | fbdac0d9 | Michael Hanselmann | |
209 | fbdac0d9 | Michael Hanselmann | def test(self): |
210 | fbdac0d9 | Michael Hanselmann | tmpfile = self._CreateTempFile()
|
211 | fbdac0d9 | Michael Hanselmann | |
212 | fbdac0d9 | Michael Hanselmann | utils.WriteFile(tmpfile, data="""
|
213 | fbdac0d9 | Michael Hanselmann | # This is a test file
|
214 | fbdac0d9 | Michael Hanselmann | /tmp
|
215 | fbdac0d9 | Michael Hanselmann | /srv/storage
|
216 | fbdac0d9 | Michael Hanselmann | relative/path
|
217 | fbdac0d9 | Michael Hanselmann | """)
|
218 | fbdac0d9 | Michael Hanselmann | |
219 | 23e3c9b7 | Michael Hanselmann | self.assertEqual(bdev._LoadAllowedFileStoragePaths(tmpfile), [
|
220 | fbdac0d9 | Michael Hanselmann | "/tmp",
|
221 | fbdac0d9 | Michael Hanselmann | "/srv/storage",
|
222 | fbdac0d9 | Michael Hanselmann | "relative/path",
|
223 | fbdac0d9 | Michael Hanselmann | ]) |
224 | fbdac0d9 | Michael Hanselmann | |
225 | fbdac0d9 | Michael Hanselmann | |
226 | 23d95cff | Bernardo Dal Seno | class TestExclusiveStoragePvs(unittest.TestCase): |
227 | 23d95cff | Bernardo Dal Seno | """Test cases for functions dealing with LVM PV and exclusive storage"""
|
228 | 23d95cff | Bernardo Dal Seno | # Allowance for rounding
|
229 | 23d95cff | Bernardo Dal Seno | _EPS = 1e-4
|
230 | 23d95cff | Bernardo Dal Seno | _MARGIN = constants.PART_MARGIN + constants.PART_RESERVED + _EPS |
231 | 23d95cff | Bernardo Dal Seno | |
232 | 23d95cff | Bernardo Dal Seno | @staticmethod
|
233 | 23d95cff | Bernardo Dal Seno | def _GenerateRandomPvInfo(rnd, name, vg): |
234 | 23d95cff | Bernardo Dal Seno | # Granularity is .01 MiB
|
235 | 23d95cff | Bernardo Dal Seno | size = rnd.randint(1024 * 100, 10 * 1024 * 1024 * 100) |
236 | 23d95cff | Bernardo Dal Seno | if rnd.choice([False, True]): |
237 | 23d95cff | Bernardo Dal Seno | free = float(rnd.randint(0, size)) / 100.0 |
238 | 23d95cff | Bernardo Dal Seno | else:
|
239 | 23d95cff | Bernardo Dal Seno | free = float(size) / 100.0 |
240 | 23d95cff | Bernardo Dal Seno | size = float(size) / 100.0 |
241 | 23d95cff | Bernardo Dal Seno | attr = "a-"
|
242 | 23d95cff | Bernardo Dal Seno | return objects.LvmPvInfo(name=name, vg_name=vg, size=size, free=free,
|
243 | 23d95cff | Bernardo Dal Seno | attributes=attr) |
244 | 23d95cff | Bernardo Dal Seno | |
245 | 23d95cff | Bernardo Dal Seno | def testGetStdPvSize(self): |
246 | 23d95cff | Bernardo Dal Seno | """Test cases for bdev.LogicalVolume._GetStdPvSize()"""
|
247 | 23d95cff | Bernardo Dal Seno | rnd = random.Random(9517)
|
248 | 23d95cff | Bernardo Dal Seno | for _ in range(0, 50): |
249 | 23d95cff | Bernardo Dal Seno | # Identical volumes
|
250 | 23d95cff | Bernardo Dal Seno | pvi = self._GenerateRandomPvInfo(rnd, "disk", "myvg") |
251 | 23d95cff | Bernardo Dal Seno | onesize = bdev.LogicalVolume._GetStdPvSize([pvi]) |
252 | 23d95cff | Bernardo Dal Seno | self.assertTrue(onesize <= pvi.size)
|
253 | 23d95cff | Bernardo Dal Seno | self.assertTrue(onesize > pvi.size * (1 - self._MARGIN)) |
254 | 23d95cff | Bernardo Dal Seno | for length in range(2, 10): |
255 | 23d95cff | Bernardo Dal Seno | n_size = bdev.LogicalVolume._GetStdPvSize([pvi] * length) |
256 | 23d95cff | Bernardo Dal Seno | self.assertEqual(onesize, n_size)
|
257 | 23d95cff | Bernardo Dal Seno | |
258 | 23d95cff | Bernardo Dal Seno | # Mixed volumes
|
259 | 23d95cff | Bernardo Dal Seno | for length in range(1, 10): |
260 | 23d95cff | Bernardo Dal Seno | pvlist = [self._GenerateRandomPvInfo(rnd, "disk", "myvg") |
261 | 23d95cff | Bernardo Dal Seno | for _ in range(0, length)] |
262 | 23d95cff | Bernardo Dal Seno | std_size = bdev.LogicalVolume._GetStdPvSize(pvlist) |
263 | 23d95cff | Bernardo Dal Seno | self.assertTrue(compat.all(std_size <= pvi.size for pvi in pvlist)) |
264 | 23d95cff | Bernardo Dal Seno | self.assertTrue(compat.any(std_size > pvi.size * (1 - self._MARGIN) |
265 | 23d95cff | Bernardo Dal Seno | for pvi in pvlist)) |
266 | 23d95cff | Bernardo Dal Seno | pvlist.append(pvlist[0])
|
267 | 23d95cff | Bernardo Dal Seno | p1_size = bdev.LogicalVolume._GetStdPvSize(pvlist) |
268 | 23d95cff | Bernardo Dal Seno | self.assertEqual(std_size, p1_size)
|
269 | 23d95cff | Bernardo Dal Seno | |
270 | 23d95cff | Bernardo Dal Seno | def testComputeNumPvs(self): |
271 | 23d95cff | Bernardo Dal Seno | """Test cases for bdev.LogicalVolume._ComputeNumPvs()"""
|
272 | 23d95cff | Bernardo Dal Seno | rnd = random.Random(8067)
|
273 | 23d95cff | Bernardo Dal Seno | for _ in range(0, 1000): |
274 | 23d95cff | Bernardo Dal Seno | pvlist = [self._GenerateRandomPvInfo(rnd, "disk", "myvg")] |
275 | 23d95cff | Bernardo Dal Seno | lv_size = float(rnd.randint(10 * 100, 1024 * 1024 * 100)) / 100.0 |
276 | 23d95cff | Bernardo Dal Seno | num_pv = bdev.LogicalVolume._ComputeNumPvs(lv_size, pvlist) |
277 | 23d95cff | Bernardo Dal Seno | std_size = bdev.LogicalVolume._GetStdPvSize(pvlist) |
278 | 23d95cff | Bernardo Dal Seno | self.assertTrue(num_pv >= 1) |
279 | 23d95cff | Bernardo Dal Seno | self.assertTrue(num_pv * std_size >= lv_size)
|
280 | 23d95cff | Bernardo Dal Seno | self.assertTrue((num_pv - 1) * std_size < lv_size * (1 + self._EPS)) |
281 | 23d95cff | Bernardo Dal Seno | |
282 | 23d95cff | Bernardo Dal Seno | def testGetEmptyPvNames(self): |
283 | 23d95cff | Bernardo Dal Seno | """Test cases for bdev.LogicalVolume._GetEmptyPvNames()"""
|
284 | 23d95cff | Bernardo Dal Seno | rnd = random.Random(21126)
|
285 | 23d95cff | Bernardo Dal Seno | for _ in range(0, 100): |
286 | 23d95cff | Bernardo Dal Seno | num_pvs = rnd.randint(1, 20) |
287 | 23d95cff | Bernardo Dal Seno | pvlist = [self._GenerateRandomPvInfo(rnd, "disk%d" % n, "myvg") |
288 | 23d95cff | Bernardo Dal Seno | for n in range(0, num_pvs)] |
289 | 23d95cff | Bernardo Dal Seno | for num_req in range(1, num_pvs + 2): |
290 | 23d95cff | Bernardo Dal Seno | epvs = bdev.LogicalVolume._GetEmptyPvNames(pvlist, num_req) |
291 | 23d95cff | Bernardo Dal Seno | epvs_set = compat.UniqueFrozenset(epvs) |
292 | 23d95cff | Bernardo Dal Seno | if len(epvs) > 1: |
293 | 23d95cff | Bernardo Dal Seno | self.assertEqual(len(epvs), len(epvs_set)) |
294 | 23d95cff | Bernardo Dal Seno | for pvi in pvlist: |
295 | 23d95cff | Bernardo Dal Seno | if pvi.name in epvs_set: |
296 | 23d95cff | Bernardo Dal Seno | self.assertEqual(pvi.size, pvi.free)
|
297 | 23d95cff | Bernardo Dal Seno | else:
|
298 | 23d95cff | Bernardo Dal Seno | # There should be no remaining empty PV when less than the
|
299 | 23d95cff | Bernardo Dal Seno | # requeste number of PVs has been returned
|
300 | 23d95cff | Bernardo Dal Seno | self.assertTrue(len(epvs) == num_req or pvi.free != pvi.size) |
301 | 23d95cff | Bernardo Dal Seno | |
302 | 23d95cff | Bernardo Dal Seno | |
303 | 688b5752 | Bernardo Dal Seno | class TestLogicalVolume(unittest.TestCase): |
304 | 688b5752 | Bernardo Dal Seno | """Tests for bdev.LogicalVolume."""
|
305 | 688b5752 | Bernardo Dal Seno | def testParseLvInfoLine(self): |
306 | 688b5752 | Bernardo Dal Seno | """Tests for LogicalVolume._ParseLvInfoLine."""
|
307 | 688b5752 | Bernardo Dal Seno | broken_lines = [ |
308 | 688b5752 | Bernardo Dal Seno | " toomuch#-wi-ao#253#3#4096.00#2",
|
309 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3#4096.00",
|
310 | 688b5752 | Bernardo Dal Seno | " -wi-a#253#3#4096.00#2",
|
311 | 688b5752 | Bernardo Dal Seno | " -wi-ao#25.3#3#4096.00#2",
|
312 | 688b5752 | Bernardo Dal Seno | " -wi-ao#twenty#3#4096.00#2",
|
313 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3.1#4096.00#2",
|
314 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#three#4096.00#2",
|
315 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3#four#2",
|
316 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3#4096..00#2",
|
317 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3#4096.00#2.0",
|
318 | 688b5752 | Bernardo Dal Seno | " -wi-ao#253#3#4096.00#two",
|
319 | 688b5752 | Bernardo Dal Seno | ] |
320 | 688b5752 | Bernardo Dal Seno | for broken in broken_lines: |
321 | 688b5752 | Bernardo Dal Seno | self.assertRaises(errors.BlockDeviceError,
|
322 | 688b5752 | Bernardo Dal Seno | bdev.LogicalVolume._ParseLvInfoLine, broken, "#")
|
323 | 688b5752 | Bernardo Dal Seno | |
324 | 688b5752 | Bernardo Dal Seno | true_out = [ |
325 | 688b5752 | Bernardo Dal Seno | ("-wi-ao", 253, 3, 4096.00, 2), |
326 | 688b5752 | Bernardo Dal Seno | ("-wi-a-", 253, 7, 4096.00, 4), |
327 | 688b5752 | Bernardo Dal Seno | ("-ri-a-", 253, 4, 4.00, 5), |
328 | 688b5752 | Bernardo Dal Seno | ("-wc-ao", 15, 18, 4096.00, 32), |
329 | 688b5752 | Bernardo Dal Seno | ] |
330 | 688b5752 | Bernardo Dal Seno | for exp in true_out: |
331 | 688b5752 | Bernardo Dal Seno | for sep in "#;|,": |
332 | 688b5752 | Bernardo Dal Seno | lvs_line = sep.join((" %s", "%d", "%d", "%.2f", "%d")) % exp |
333 | 688b5752 | Bernardo Dal Seno | parsed = bdev.LogicalVolume._ParseLvInfoLine(lvs_line, sep) |
334 | 688b5752 | Bernardo Dal Seno | self.assertEqual(parsed, exp)
|
335 | 688b5752 | Bernardo Dal Seno | |
336 | 688b5752 | Bernardo Dal Seno | @staticmethod
|
337 | 688b5752 | Bernardo Dal Seno | def _FakeRunCmd(success, stdout): |
338 | 688b5752 | Bernardo Dal Seno | if success:
|
339 | 688b5752 | Bernardo Dal Seno | exit_code = 0
|
340 | 688b5752 | Bernardo Dal Seno | else:
|
341 | 688b5752 | Bernardo Dal Seno | exit_code = 1
|
342 | 688b5752 | Bernardo Dal Seno | return lambda cmd: utils.RunResult(exit_code, None, stdout, "", cmd, |
343 | 688b5752 | Bernardo Dal Seno | utils.process._TIMEOUT_NONE, 5)
|
344 | 688b5752 | Bernardo Dal Seno | |
345 | 688b5752 | Bernardo Dal Seno | def testGetLvInfo(self): |
346 | 688b5752 | Bernardo Dal Seno | """Tests for LogicalVolume._GetLvInfo."""
|
347 | 688b5752 | Bernardo Dal Seno | self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume._GetLvInfo,
|
348 | 688b5752 | Bernardo Dal Seno | "fake_path",
|
349 | 688b5752 | Bernardo Dal Seno | _run_cmd=self._FakeRunCmd(False, "Fake error msg")) |
350 | 688b5752 | Bernardo Dal Seno | self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume._GetLvInfo,
|
351 | 688b5752 | Bernardo Dal Seno | "fake_path", _run_cmd=self._FakeRunCmd(True, "")) |
352 | 688b5752 | Bernardo Dal Seno | self.assertRaises(errors.BlockDeviceError, bdev.LogicalVolume._GetLvInfo,
|
353 | 688b5752 | Bernardo Dal Seno | "fake_path", _run_cmd=self._FakeRunCmd(True, "BadStdOut")) |
354 | 688b5752 | Bernardo Dal Seno | good_line = " -wi-ao,253,3,4096.00,2"
|
355 | 688b5752 | Bernardo Dal Seno | fake_cmd = self._FakeRunCmd(True, good_line) |
356 | 688b5752 | Bernardo Dal Seno | good_res = bdev.LogicalVolume._GetLvInfo("fake_path", _run_cmd=fake_cmd)
|
357 | 688b5752 | Bernardo Dal Seno | # Only the last line should be parsed and taken into account
|
358 | 688b5752 | Bernardo Dal Seno | for lines in [ |
359 | 688b5752 | Bernardo Dal Seno | [good_line] * 2,
|
360 | 688b5752 | Bernardo Dal Seno | [good_line] * 3,
|
361 | 688b5752 | Bernardo Dal Seno | ["bad line", good_line],
|
362 | 688b5752 | Bernardo Dal Seno | ]: |
363 | 688b5752 | Bernardo Dal Seno | fake_cmd = self._FakeRunCmd(True, "\n".join(lines)) |
364 | 688b5752 | Bernardo Dal Seno | same_res = bdev.LogicalVolume._GetLvInfo("fake_path", fake_cmd)
|
365 | 688b5752 | Bernardo Dal Seno | self.assertEqual(same_res, good_res)
|
366 | 688b5752 | Bernardo Dal Seno | |
367 | 688b5752 | Bernardo Dal Seno | |
368 | fbdac0d9 | Michael Hanselmann | if __name__ == "__main__": |
369 | 25231ec5 | Michael Hanselmann | testutils.GanetiTestProgram() |