# vim: tabstop=4 shiftwidth=4 softtabstop=4

#    Copyright 2010 OpenStack LLC
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from datetime import datetime
import errno
import os
import select
import time

from nova import test
from nova.utils import parse_mailmap, str_dict_replace, synchronized


class ProjectTestCase(test.TestCase):
    def test_authors_up_to_date(self):
        if os.path.exists('.bzr'):
            contributors = set()

            mailmap = parse_mailmap('.mailmap')

            import bzrlib.workingtree
            tree = bzrlib.workingtree.WorkingTree.open('.')
            tree.lock_read()
            try:
                parents = tree.get_parent_ids()
                g = tree.branch.repository.get_graph()
                for p in parents[1:]:
                    rev_ids = [r for r, _ in g.iter_ancestry(parents)
                               if r != "null:"]
                    revs = tree.branch.repository.get_revisions(rev_ids)
                    for r in revs:
                        for author in r.get_apparent_authors():
                            email = author.split(' ')[-1]
                            contributors.add(str_dict_replace(email, mailmap))

                authors_file = open('Authors', 'r').read()

                missing = set()
                for contributor in contributors:
                    if contributor == 'nova-core':
                        continue
                    if not contributor in authors_file:
                        missing.add(contributor)

                self.assertTrue(len(missing) == 0,
                                '%r not listed in Authors' % missing)
            finally:
                tree.unlock()


class LockTestCase(test.TestCase):
    def test_synchronized(self):
        rpipe, wpipe = os.pipe()
        pid = os.fork()
        if pid > 0:
            os.close(wpipe)

            @synchronized('testlock')
            def f():
                rfds, _, __ = select.select([rpipe], [], [], 1)
                self.assertEquals(len(rfds), 0, "The other process, which was"
                                                " supposed to be locked, "
                                                "wrote on its end of the "
                                                "pipe")
                os.close(rpipe)

            f()
        else:
            os.close(rpipe)

            @synchronized('testlock')
            def g():
                try:
                    os.write(wpipe, "foo")
                except OSError, e:
                    self.assertEquals(e.errno, errno.EPIPE)
                    return
            g()
            os._exit(0)

@@ -651,38 +651,8 @@
 e.%0A%0A
-from datetime import datetime%0A
 impo
@@ -687,20 +687,8 @@
 lect
-%0Aimport time
 %0A%0Afr
@@ -2218,32 +2218,456 @@
 test.TestCase):%0A
+    def test_synchronized_wrapped_function_metadata(self):%0A        @synchronized('whatever')%0A        def foo():%0A            %22%22%22Bar%22%22%22%0A            pass%0A        self.assertEquals(foo.__doc__, 'Bar', %22Wrapped function's docstring %22%0A                                              %22got lost%22)%0A        self.assertEquals(foo.__name__, 'foo', %22Wrapped function's name %22%0A                                               %22got mangled%22)%0A%0A
     def test_syn

Use functools.wraps to make sure wrapped method's metadata (docstring and name) doesn't get mangled.