|
9 | 9 | Host your_hostname localhost 127.0.0.*
|
10 | 10 | StrictHostKeyChecking no
|
11 | 11 | LogLevel ERROR
|
| 12 | +
|
| 13 | +The hostname mock command available in tests/bin needs to be |
| 14 | +used on the remote nodes (tests/bin added to PATH in .bashrc). |
12 | 15 | """
|
13 | 16 |
|
14 | 17 | import logging
|
|
18 | 21 | import warnings
|
19 | 22 |
|
20 | 23 | from ClusterShell.NodeSet import NodeSet
|
| 24 | +from ClusterShell.Propagation import RouteResolvingError |
| 25 | +from ClusterShell.Event import EventHandler |
21 | 26 | from ClusterShell.Task import task_self, task_terminate, task_wait
|
22 | 27 | from ClusterShell.Task import Task, task_cleanup
|
23 | 28 | from ClusterShell.Topology import TopologyGraph
|
|
36 | 41 | NODE_FOREIGN = '127.0.0.5'
|
37 | 42 |
|
38 | 43 |
|
39 |
| -class TEventHandlerBase(object): |
| 44 | +class TEventHandlerBase(EventHandler): |
40 | 45 | """Base Test class for EventHandler"""
|
41 | 46 |
|
42 | 47 | def __init__(self):
|
@@ -103,6 +108,16 @@ def ev_close(self, worker, timedout):
|
103 | 108 | if timedout:
|
104 | 109 | self.ev_timedout_cnt += 1
|
105 | 110 |
|
| 111 | +class TRoutingEventHandler(TEventHandler): |
| 112 | + """Test Routing Event Handler""" |
| 113 | + |
| 114 | + def __init__(self): |
| 115 | + TEventHandler.__init__(self) |
| 116 | + self.routing_events = [] |
| 117 | + |
| 118 | + def _ev_routing(self, worker, arg): |
| 119 | + self.routing_events.append((worker, arg)) |
| 120 | + |
106 | 121 |
|
107 | 122 | class TreeWorkerTestBase(unittest.TestCase):
|
108 | 123 | """
|
@@ -348,6 +363,38 @@ def test_tree_run_event(self):
|
348 | 363 | self.assertEqual(teh.ev_close_cnt, 1)
|
349 | 364 | self.assertEqual(teh.last_read, b'Lorem Ipsum')
|
350 | 365 |
|
| 366 | + def test_tree_run_event_multiple(self): |
| 367 | + """test multiple tree runs with EventHandler (1.8+)""" |
| 368 | + # Test for GH#566 |
| 369 | + teh = TEventHandler() |
| 370 | + self.task.run('echo Lorem Ipsum Unum', nodes=NODE_DISTANT, handler=teh) |
| 371 | + self.assertEqual(teh.ev_start_cnt, 1) |
| 372 | + self.assertEqual(teh.ev_pickup_cnt, 1) |
| 373 | + self.assertEqual(teh.ev_read_cnt, 1) |
| 374 | + self.assertEqual(teh.ev_written_cnt, 0) |
| 375 | + self.assertEqual(teh.ev_hup_cnt, 1) |
| 376 | + self.assertEqual(teh.ev_timedout_cnt, 0) |
| 377 | + self.assertEqual(teh.ev_close_cnt, 1) |
| 378 | + self.assertEqual(teh.last_read, b'Lorem Ipsum Unum') |
| 379 | + self.task.run('echo Lorem Ipsum Duo', nodes=NODE_DISTANT, handler=teh) |
| 380 | + self.assertEqual(teh.ev_start_cnt, 2) |
| 381 | + self.assertEqual(teh.ev_pickup_cnt, 2) |
| 382 | + self.assertEqual(teh.ev_read_cnt, 2) |
| 383 | + self.assertEqual(teh.ev_written_cnt, 0) |
| 384 | + self.assertEqual(teh.ev_hup_cnt, 2) |
| 385 | + self.assertEqual(teh.ev_timedout_cnt, 0) |
| 386 | + self.assertEqual(teh.ev_close_cnt, 2) |
| 387 | + self.assertEqual(teh.last_read, b'Lorem Ipsum Duo') |
| 388 | + self.task.run('echo Lorem Ipsum Tres', nodes=NODE_DISTANT, handler=teh) |
| 389 | + self.assertEqual(teh.ev_start_cnt, 3) |
| 390 | + self.assertEqual(teh.ev_pickup_cnt, 3) |
| 391 | + self.assertEqual(teh.ev_read_cnt, 3) |
| 392 | + self.assertEqual(teh.ev_written_cnt, 0) |
| 393 | + self.assertEqual(teh.ev_hup_cnt, 3) |
| 394 | + self.assertEqual(teh.ev_timedout_cnt, 0) |
| 395 | + self.assertEqual(teh.ev_close_cnt, 3) |
| 396 | + self.assertEqual(teh.last_read, b'Lorem Ipsum Tres') |
| 397 | + |
351 | 398 | def test_tree_run_event_timeout(self):
|
352 | 399 | """test tree run with EventHandler (1.8+) with timeout"""
|
353 | 400 | teh = TEventHandler()
|
@@ -713,6 +760,17 @@ def ev_hup(self, worker, node, rc):
|
713 | 760 | self.assertEqual(teh.ev_close_cnt, 1)
|
714 | 761 | self.assertEqual(teh.last_read, None)
|
715 | 762 |
|
| 763 | + def test_tree_gateway_bogus_single(self): |
| 764 | + """test tree run with bogus single gateway""" |
| 765 | + # Part of GH#566 |
| 766 | + teh = TEventHandler() |
| 767 | + os.environ['CLUSTERSHELL_GW_PYTHON_EXECUTABLE'] = '/test/bogus' |
| 768 | + try: |
| 769 | + self.assertRaises(RouteResolvingError, self.task.run, 'echo Lorem Ipsum', |
| 770 | + nodes=NODE_DISTANT, handler=teh) |
| 771 | + finally: |
| 772 | + del os.environ['CLUSTERSHELL_GW_PYTHON_EXECUTABLE'] |
| 773 | + |
716 | 774 |
|
717 | 775 | @unittest.skipIf(HOSTNAME == 'localhost', "does not work with hostname set to 'localhost'")
|
718 | 776 | class TreeWorkerGW2Test(TreeWorkerTestBase):
|
@@ -858,3 +916,24 @@ def test_tree_run_gw2f1_write_distant(self):
|
858 | 916 | def test_tree_run_gw2f1_write_distant2_mt(self):
|
859 | 917 | """test tree run with write(), 1/2 gateways, distant 2 targets, separate thread"""
|
860 | 918 | self._tree_run_write(NODE_DISTANT2, separate_thread=True)
|
| 919 | + |
| 920 | + def test_tree_run_gw2f1_reroute(self): |
| 921 | + """test tree run with reroute event, 1/2 gateways""" |
| 922 | + teh = TRoutingEventHandler() |
| 923 | + self.task.run('echo Lorem Ipsum', nodes=NODE_DISTANT2, handler=teh) |
| 924 | + self.assertEqual(len(teh.routing_events), 1) |
| 925 | + worker, arg = teh.routing_events[0] |
| 926 | + self.assertEqual(worker.command, "echo Lorem Ipsum") |
| 927 | + self.assertEqual(arg["event"], "reroute") |
| 928 | + self.assertIn(arg["targets"], NodeSet(NODE_DISTANT2)) |
| 929 | + # event handler checks |
| 930 | + self.assertEqual(teh.ev_start_cnt, 1) |
| 931 | + self.assertEqual(teh.ev_pickup_cnt, 2) |
| 932 | + # read_cnt += 1 for gateway error on stderr (so currently not fully |
| 933 | + # transparent to the user) |
| 934 | + self.assertEqual(teh.ev_read_cnt, 3) |
| 935 | + self.assertEqual(teh.ev_written_cnt, 0) |
| 936 | + self.assertEqual(teh.ev_hup_cnt, 2) |
| 937 | + self.assertEqual(teh.ev_timedout_cnt, 0) |
| 938 | + self.assertEqual(teh.ev_close_cnt, 1) |
| 939 | + self.assertEqual(teh.last_read, b'Lorem Ipsum') |
0 commit comments