Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4"""Tests for `gutools` package.""" 

5 

6import pytest 

7import asyncio 

8import random 

9import time 

10import logging 

11 

12from gutools import tools 

13from gutools.unet import TL, setup_config 

14from gutools.uagents import update_domestic, restore_domestic 

15from gutools.uapplication import UApplication 

16from aiopb.aiopb import Hub 

17 

18@pytest.fixture 

19def app(): 

20 hub = Hub() 

21 app = UApplication(hub=hub) 

22 return app 

23 

24def test_protocol_reliability_TODO(): 

25 """TODO: rewrite network test""" 

26 return 

27 

28 setup_config() # logging configuration 

29 

30 async def logic(nodes, prob): 

31 """ 

32 1. Wait until channels are ready 

33 2. Send broadcast and direct messages 

34 3. Wrap receive functions to simulate network dropping packets 

35 4. Listen to TL-1 receiving messages 

36 5. Send a sequence of numbers from TL-0 -> TL-1 

37 Some messages will be dropped 

38 Request/Resend/Watermark will do the work 

39 6. Wait until the last number is processed 

40 Stop the nodes 

41 7. Repeat the process again 

42 

43 """ 

44 logging.info(f"Network dropping probability : {prob*100}%") 

45 for tl in nodes: 

46 logging.debug(f'Starting {tl.uid} : id:{id(tl)}') 

47 

48 

49 def drop_packet(f, prob): 

50 def wrap(*args, **kw): 

51 if random.random() >= prob: 

52 return f(*args, **kw) 

53 logging.debug('packet droppped :)') 

54 return wrap 

55 

56 # wait until all channels are ready 

57 # await asyncio.gather(*[tl.channels_ready for tl in nodes]) 

58 

59 # send a 'broadcast' message 

60 t0, p0, baddr0, saddr0 = nodes[0].channels['broadcast'] 

61 t1, p1, baddr1, saddr1 = nodes[1].channels['broadcast'] 

62 p0.send('mykey', b'Hello', '*', saddr1) 

63 

64 # send a 'direct' message 

65 t0, p0, baddr0, saddr0 = nodes[0].channels['broadcast'] 

66 t1, p1, baddr1, saddr1 = nodes[1].channels['broadcast'] 

67 

68 # wrap functions to simulate packet dropping 

69 # and speed up the domestic: retry missing, etc 

70 for tl in nodes: 

71 for link, (_, protocol, _, _) in tl.channels.items(): 

72 protocol.datagram_received = \ 

73 drop_packet(protocol.datagram_received, prob=prob) 

74 update_domestic(protocol.request_missing, restart=0.1) 

75 update_domestic(protocol._shake_channels, restart=0.1) 

76 

77 N = 10 

78 __builtins__['__stop_test_TL_startup'] = False 

79 def check_end(key, message): 

80 if message == N - 1: 

81 logging.debug("Logic: Stopping nodes") 

82 __builtins__['__stop_test_TL_startup'] = True 

83 

84 hub = Hub(realm='') 

85 hub.subscribe('mykey', check_end) 

86 

87 to = nodes[1].uid 

88 for i in range(N): 

89 p0.send('mykey', i, to, saddr1) 

90 await asyncio.sleep(0.15) 

91 

92 logging.debug("Logic: Waiting for nodes to end") 

93 for i in range(100): 

94 await asyncio.sleep(1) 

95 if __builtins__['__stop_test_TL_startup']: 

96 # stop nodes and restart original domestic settings 

97 for tl in nodes: 

98 logging.debug(f"Stopping {tl.uid} : id:{id(tl)}") 

99 tl.stop() 

100 for link, (_, protocol, _, _) in tl.channels.items(): 

101 restore_domestic(protocol.request_missing) 

102 restore_domestic(protocol._shake_channels) 

103 # unsubscribe function to not alter any futher test 

104 hub.unsubscribe('mykey', check_end) 

105 break 

106 

107 # await asyncio.gather(*[tl.running for tl in nodes]) 

108 

109 foo = 1 

110 

111 loop = asyncio.get_event_loop() 

112 

113 t0 = time.time() 

114 N = 20 

115 for tries in range(N): 

116 test_nodes = [] 

117 baseport = random.randint(10000, 20000) 

118 for i in range(2): 

119 uid = f'TL-{baseport}-{i}' 

120 uri = f'>udp://:{baseport + i}' 

121 tl = TL(loop=loop, uri=uri, uid=uid, app=app) 

122 test_nodes.append(tl) 

123 

124 drop_prob = tries / N 

125 loop.run_until_complete(asyncio.gather( 

126 logic(test_nodes, drop_prob), *[tl.main() for tl in test_nodes])) 

127 

128 elapsed = int(time.time() - t0) 

129 logging.info(f"Total elapsed time: {elapsed} secs") 

130 assert elapsed < 180 * 2, "Test is taking too much time" 

131 

132 foo = 1 

133 

134def test_1(): 

135 pass 

136 

137def test_2(): 

138 pass 

139 

140def test_3(): 

141 pass 

142 

143def test_4(): 

144 pass 

145 

146def test_5(): 

147 pass 

148 

149def test_6(): 

150 pass 

151 

152def test_7(): 

153 pass 

154 

155def test_8(): 

156 pass 

157 

158def test_9(): 

159 pass 

160 

161def test_A(): 

162 pass 

163