1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2010 OpenStack LLC
5
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6
# not use this file except in compliance with the License. You may obtain
7
# a copy of the License at
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
# License for the specific language governing permissions and limitations
23
from eventlet import greenpool
24
from eventlet import greenthread
27
from cinder import exception
28
from cinder import test
29
from cinder import utils
32
class ExceptionTestCase(test.TestCase):
37
def test_exceptions_raise(self):
38
for name in dir(exception):
39
exc = getattr(exception, name)
40
if isinstance(exc, type):
41
self.assertRaises(exc, self._raise_exc, exc)
44
class ProjectTestCase(test.TestCase):
45
def test_authors_up_to_date(self):
46
topdir = os.path.normpath(os.path.dirname(__file__) + '/../../')
49
mailmap = utils.parse_mailmap(os.path.join(topdir, '.mailmap'))
50
authors_file = open(os.path.join(topdir,
51
'Authors'), 'r').read().lower()
53
if os.path.exists(os.path.join(topdir, '.git')):
54
for email in commands.getoutput('git log --format=%ae').split():
57
if "jenkins" in email and "openstack.org" in email:
59
email = '<' + email.lower() + '>'
60
contributors.add(utils.str_dict_replace(email, mailmap))
64
for contributor in contributors:
65
if contributor == 'cinder-core':
67
if not contributor in authors_file:
68
missing.add(contributor)
70
self.assertTrue(len(missing) == 0,
71
'%r not listed in Authors' % missing)
73
def test_all_migrations_have_downgrade(self):
74
topdir = os.path.normpath(os.path.dirname(__file__) + '/../../')
75
py_glob = os.path.join(topdir, "cinder", "db", "sqlalchemy",
76
"migrate_repo", "versions", "*.py")
77
missing_downgrade = []
78
for path in glob.iglob(py_glob):
81
with open(path, "r") as f:
83
if 'def upgrade(' in line:
85
if 'def downgrade(' in line:
88
if has_upgrade and not has_downgrade:
89
fname = os.path.basename(path)
90
missing_downgrade.append(fname)
92
helpful_msg = (_("The following migrations are missing a downgrade:"
93
"\n\t%s") % '\n\t'.join(sorted(missing_downgrade)))
94
self.assert_(not missing_downgrade, helpful_msg)
97
class LockTestCase(test.TestCase):
98
def test_synchronized_wrapped_function_metadata(self):
99
@utils.synchronized('whatever')
103
self.assertEquals(foo.__doc__, 'Bar', "Wrapped function's docstring "
105
self.assertEquals(foo.__name__, 'foo', "Wrapped function's name "
108
def test_synchronized_internally(self):
109
"""We can lock across multiple green threads"""
110
saved_sem_num = len(utils._semaphores)
111
seen_threads = list()
113
@utils.synchronized('testlock2', external=False)
116
seen_threads.append(id)
120
pool = greenpool.GreenPool(10)
122
threads.append(pool.spawn(f, i))
124
for thread in threads:
127
self.assertEquals(len(seen_threads), 100)
128
# Looking at the seen threads, split it into chunks of 10, and verify
129
# that the last 9 match the first in each chunk.
132
self.assertEquals(seen_threads[i * 10],
133
seen_threads[i * 10 + 1 + j])
135
self.assertEqual(saved_sem_num, len(utils._semaphores),
136
"Semaphore leak detected")
138
def test_nested_external_fails(self):
139
"""We can not nest external syncs"""
141
@utils.synchronized('testlock1', external=True)
144
@utils.synchronized('testlock2', external=True)
149
self.assertRaises(lockfile.NotMyLock, outer_lock)
151
utils.cleanup_file_locks()
153
def test_synchronized_externally(self):
154
"""We can lock across multiple processes"""
155
rpipe1, wpipe1 = os.pipe()
156
rpipe2, wpipe2 = os.pipe()
158
@utils.synchronized('testlock1', external=True)
161
os.write(wpipe, "foo")
163
self.assertEquals(e.errno, errno.EPIPE)
166
rfds, _wfds, _efds = select.select([rpipe], [], [], 1)
167
self.assertEquals(len(rfds), 0, "The other process, which was"
168
" supposed to be locked, "
169
"wrote on its end of the "