server/test/unittest_hook.py
changeset 3414 fe6c99b96701
parent 3413 5cd27d2cc64f
child 4252 6c4f109c2b03
equal deleted inserted replaced
3413:5cd27d2cc64f 3414:fe6c99b96701
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     7 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     7 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     8 """
     8 """
     9 
     9 
    10 from logilab.common.testlib import unittest_main
    10 from logilab.common.testlib import TestCase, unittest_main, mock_object
    11 
    11 
       
    12 
       
    13 from cubicweb.devtools import TestServerConfiguration
    12 from cubicweb.devtools.testlib import CubicWebTC
    14 from cubicweb.devtools.testlib import CubicWebTC
    13 from cubicweb.server.hook import LateOperation, Operation, SingleLastOperation
    15 from cubicweb.selectors import implements
       
    16 from cubicweb.server import hook
    14 from cubicweb.hooks import integrity, syncschema
    17 from cubicweb.hooks import integrity, syncschema
    15 
    18 
    16 
    19 
    17 def clean_session_ops(func):
    20 def clean_session_ops(func):
    18     def wrapper(self, *args, **kwargs):
    21     def wrapper(self, *args, **kwargs):
    20             return func(self, *args, **kwargs)
    23             return func(self, *args, **kwargs)
    21         finally:
    24         finally:
    22             self.session.pending_operations[:] = []
    25             self.session.pending_operations[:] = []
    23     return wrapper
    26     return wrapper
    24 
    27 
    25 class HookHelpersTC(CubicWebTC):
    28 class OperationsTC(CubicWebTC):
    26 
    29 
    27     def setUp(self):
    30     def setUp(self):
    28         CubicWebTC.setUp(self)
    31         CubicWebTC.setUp(self)
    29         self.hm = self.repo.hm
    32         self.hm = self.repo.hm
    30 
    33 
    31     @clean_session_ops
    34     @clean_session_ops
    32     def test_late_operation(self):
    35     def test_late_operation(self):
    33         session = self.session
    36         session = self.session
    34         l1 = LateOperation(session)
    37         l1 = hook.LateOperation(session)
    35         l2 = LateOperation(session)
    38         l2 = hook.LateOperation(session)
    36         l3 = Operation(session)
    39         l3 = hook.Operation(session)
    37         self.assertEquals(session.pending_operations, [l3, l1, l2])
    40         self.assertEquals(session.pending_operations, [l3, l1, l2])
    38 
    41 
    39     @clean_session_ops
    42     @clean_session_ops
    40     def test_single_last_operation(self):
    43     def test_single_last_operation(self):
    41         session = self.session
    44         session = self.session
    42         l0 = SingleLastOperation(session)
    45         l0 = hook.SingleLastOperation(session)
    43         l1 = LateOperation(session)
    46         l1 = hook.LateOperation(session)
    44         l2 = LateOperation(session)
    47         l2 = hook.LateOperation(session)
    45         l3 = Operation(session)
    48         l3 = hook.Operation(session)
    46         self.assertEquals(session.pending_operations, [l3, l1, l2, l0])
    49         self.assertEquals(session.pending_operations, [l3, l1, l2, l0])
    47         l4 = SingleLastOperation(session)
    50         l4 = hook.SingleLastOperation(session)
    48         self.assertEquals(session.pending_operations, [l3, l1, l2, l4])
    51         self.assertEquals(session.pending_operations, [l3, l1, l2, l4])
    49 
    52 
    50     @clean_session_ops
    53     @clean_session_ops
    51     def test_global_operation_order(self):
    54     def test_global_operation_order(self):
    52         session = self.session
    55         session = self.session
    57         op3 = syncschema.MemSchemaNotifyChanges(session)
    60         op3 = syncschema.MemSchemaNotifyChanges(session)
    58         op4 = integrity._DelayedDeleteOp(session)
    61         op4 = integrity._DelayedDeleteOp(session)
    59         op5 = integrity._CheckORelationOp(session)
    62         op5 = integrity._CheckORelationOp(session)
    60         self.assertEquals(session.pending_operations, [op1, op2, op4, op5, op3])
    63         self.assertEquals(session.pending_operations, [op1, op2, op4, op5, op3])
    61 
    64 
       
    65 
       
    66 class HookCalled(Exception): pass
       
    67 
       
    68 config = TestServerConfiguration('data')
       
    69 config.bootstrap_cubes()
       
    70 schema = config.load_schema()
       
    71 
       
    72 class AddAnyHook(hook.Hook):
       
    73     __regid__ = 'addany'
       
    74     category = 'cat1'
       
    75     events = ('before_add_entity',)
       
    76     def __call__(self):
       
    77         raise HookCalled()
       
    78 
       
    79 
       
    80 class HooksManagerTC(TestCase):
       
    81 
       
    82     def setUp(self):
       
    83         """ called before each test from this class """
       
    84         self.vreg = mock_object(config=config, schema=schema)
       
    85         self.o = hook.HooksRegistry(self.vreg)
       
    86 
       
    87     def test_register_bad_hook1(self):
       
    88         class _Hook(hook.Hook):
       
    89             events = ('before_add_entiti',)
       
    90         ex = self.assertRaises(Exception, self.o.register, _Hook)
       
    91         self.assertEquals(str(ex), 'bad event before_add_entiti on unittest_hook._Hook')
       
    92 
       
    93     def test_register_bad_hook2(self):
       
    94         class _Hook(hook.Hook):
       
    95             events = None
       
    96         ex = self.assertRaises(Exception, self.o.register, _Hook)
       
    97         self.assertEquals(str(ex), 'bad .events attribute None on unittest_hook._Hook')
       
    98 
       
    99     def test_register_bad_hook3(self):
       
   100         class _Hook(hook.Hook):
       
   101             events = 'before_add_entity'
       
   102         ex = self.assertRaises(Exception, self.o.register, _Hook)
       
   103         self.assertEquals(str(ex), 'bad event b on unittest_hook._Hook')
       
   104 
       
   105     def test_call_hook(self):
       
   106         self.o.register(AddAnyHook)
       
   107         cw = mock_object(vreg=self.vreg)
       
   108         self.assertRaises(HookCalled, self.o.call_hooks, 'before_add_entity', cw)
       
   109         self.o.call_hooks('before_delete_entity', cw) # nothing to call
       
   110         config.disabled_hooks_categories.add('cat1')
       
   111         self.o.call_hooks('before_add_entity', cw) # disabled hooks category, not called
       
   112         config.disabled_hooks_categories.remove('cat1')
       
   113         self.assertRaises(HookCalled, self.o.call_hooks, 'before_add_entity', cw)
       
   114         self.o.unregister(AddAnyHook)
       
   115         self.o.call_hooks('before_add_entity', cw) # nothing to call
       
   116 
       
   117 
       
   118 class SystemHooksTC(CubicWebTC):
       
   119 
       
   120     def test_startup_shutdown(self):
       
   121         import hooks # cubicweb/server/test/data/hooks.py
       
   122         self.assertEquals(hooks.CALLED_EVENTS['server_startup'], True)
       
   123         # don't actually call repository.shutdown !
       
   124         self.repo.hm.call_hooks('server_shutdown', repo=self.repo)
       
   125         self.assertEquals(hooks.CALLED_EVENTS['server_shutdown'], True)
       
   126 
       
   127     def test_session_open_close(self):
       
   128         import hooks # cubicweb/server/test/data/hooks.py
       
   129         cnx = self.login('anon')
       
   130         self.assertEquals(hooks.CALLED_EVENTS['session_open'], 'anon')
       
   131         cnx.close()
       
   132         self.assertEquals(hooks.CALLED_EVENTS['session_close'], 'anon')
       
   133 
       
   134 
       
   135 # class RelationHookTC(TestCase):
       
   136 #     """testcase for relation hooks grouping"""
       
   137 #     def setUp(self):
       
   138 #         """ called before each test from this class """
       
   139 #         self.o = HooksManager(schema)
       
   140 #         self.called = []
       
   141 
       
   142 #     def test_before_add_relation(self):
       
   143 #         """make sure before_xxx_relation hooks are called directly"""
       
   144 #         self.o.register(self._before_relation_hook,
       
   145 #                              'before_add_relation', 'concerne')
       
   146 #         self.assertEquals(self.called, [])
       
   147 #         self.o.call_hooks('before_add_relation', 'concerne', 'USER',
       
   148 #                           1, 'concerne', 2)
       
   149 #         self.assertEquals(self.called, [(1, 'concerne', 2)])
       
   150 
       
   151 #     def test_after_add_relation(self):
       
   152 #         """make sure after_xxx_relation hooks are deferred"""
       
   153 #         self.o.register(self._after_relation_hook,
       
   154 #                              'after_add_relation', 'concerne')
       
   155 #         self.assertEquals(self.called, [])
       
   156 #         self.o.call_hooks('after_add_relation', 'concerne', 'USER',
       
   157 #                           1, 'concerne', 2)
       
   158 #         self.o.call_hooks('after_add_relation', 'concerne', 'USER',
       
   159 #                           3, 'concerne', 4)
       
   160 #         self.assertEquals(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
       
   161 
       
   162 #     def test_before_delete_relation(self):
       
   163 #         """make sure before_xxx_relation hooks are called directly"""
       
   164 #         self.o.register(self._before_relation_hook,
       
   165 #                              'before_delete_relation', 'concerne')
       
   166 #         self.assertEquals(self.called, [])
       
   167 #         self.o.call_hooks('before_delete_relation', 'concerne', 'USER',
       
   168 #                           1, 'concerne', 2)
       
   169 #         self.assertEquals(self.called, [(1, 'concerne', 2)])
       
   170 
       
   171 #     def test_after_delete_relation(self):
       
   172 #         """make sure after_xxx_relation hooks are deferred"""
       
   173 #         self.o.register(self._after_relation_hook,
       
   174 #                         'after_delete_relation', 'concerne')
       
   175 #         self.o.call_hooks('after_delete_relation', 'concerne', 'USER',
       
   176 #                           1, 'concerne', 2)
       
   177 #         self.o.call_hooks('after_delete_relation', 'concerne', 'USER',
       
   178 #                           3, 'concerne', 4)
       
   179 #         self.assertEquals(self.called, [(1, 'concerne', 2), (3, 'concerne', 4)])
       
   180 
       
   181 
       
   182 #     def _before_relation_hook(self, pool, subject, r_type, object):
       
   183 #         self.called.append((subject, r_type, object))
       
   184 
       
   185 #     def _after_relation_hook(self, pool, subject, r_type, object):
       
   186 #         self.called.append((subject, r_type, object))
       
   187 
       
   188 
    62 if __name__ == '__main__':
   189 if __name__ == '__main__':
    63     unittest_main()
   190     unittest_main()