lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xnet/lonet/lonet_test.py (about) 1 # -*- coding: utf-8 -*- 2 # Copyright (C) 2018 Nexedi SA and Contributors. 3 # Kirill Smelkov <kirr@nexedi.com> 4 # 5 # This program is free software: you can Use, Study, Modify and Redistribute 6 # it under the terms of the GNU General Public License version 3, or (at your 7 # option) any later version, as published by the Free Software Foundation. 8 # 9 # You can also Link and Combine this program with other software covered by 10 # the terms of any of the Free Software licenses or any of the Open Source 11 # Initiative approved licenses and Convey the resulting work. Corresponding 12 # source of such a combination shall include the source code for all other 13 # software used. 14 # 15 # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 # 18 # See COPYING file for full licensing terms. 19 # See https://www.nexedi.com/licensing for rationale and options. 20 21 from golang import gimport, defer, func 22 xerr = gimport('lab.nexedi.com/kirr/go123/xerr') 23 lonet = gimport('lab.nexedi.com/kirr/go123/xnet/lonet') 24 25 from threading import Thread 26 from cStringIO import StringIO 27 import errno, logging as log 28 29 30 def xread(sk): 31 # XXX might get only part of sent data 32 return sk.recv(4096) 33 34 def xwrite(sk, data): 35 sk.sendall(data) 36 37 38 # TODO test that fd of listener can be used in select/epoll 39 # TODO non-blocking mode 40 41 42 # _test_virtnet_basic runs basic tests on a virtnet network implementation. 43 # (this follows virtnettest.TestBasic) 44 @func 45 def _test_virtnet_basic(subnet): 46 # (verifying that error log stays empty) 47 errorlog = StringIO() 48 errorlogh = log.StreamHandler(errorlog) 49 l = log.getLogger() 50 l.addHandler(errorlogh) 51 def _(): 52 l.removeHandler(errorlogh) 53 assert errorlog.getvalue() == "" 54 defer(_) 55 56 defer(subnet.close) 57 58 def xaddr(addr): 59 return lonet.Addr.parse(subnet.network(), addr) 60 61 ha = subnet.new_host("α") 62 hb = subnet.new_host("β") 63 64 assert ha.network() == subnet.network() 65 assert hb.network() == subnet.network() 66 assert ha.name() == "α" 67 assert hb.name() == "β" 68 69 try: 70 ha.dial(":0") 71 except Exception as e: 72 assert xerr.cause(e) is lonet.ErrConnRefused 73 assert str(e) == "dial %s α:1->α:0: [Errno %d] connection refused" % (subnet.network(), errno.ECONNREFUSED) 74 else: 75 assert 0, "connection not refused" 76 77 l1 = ha.listen("") 78 assert l1.addr() == xaddr("α:1") 79 80 try: 81 ha.dial(":0") 82 except Exception as e: 83 assert xerr.cause(e) is lonet.ErrConnRefused 84 assert str(e) == "dial %s α:2->α:0: [Errno %d] connection refused" % (subnet.network(), errno.ECONNREFUSED) 85 else: 86 assert 0, "connection not refused" 87 88 89 def Tsrv(): 90 c1s = l1.accept() 91 assert c1s.local_addr() == xaddr("α:2") 92 assert c1s.getsockname() == ("α", 2) 93 assert c1s.remote_addr() == xaddr("β:1") 94 assert c1s.getpeername() == ("β", 1) 95 96 assert xread(c1s) == "ping" 97 xwrite(c1s, "pong") 98 99 c2s = l1.accept() 100 assert c2s.local_addr() == xaddr("α:3") 101 assert c2s.getsockname() == ("α", 3) 102 assert c2s.remote_addr() == xaddr("β:2") 103 assert c2s.getpeername() == ("β", 2) 104 105 assert xread(c2s) == "hello" 106 xwrite(c2s, "world") 107 108 109 tsrv = Thread(target=Tsrv) 110 tsrv.start() 111 112 c1c = hb.dial("α:1") 113 assert c1c.local_addr() == xaddr("β:1") 114 assert c1c.getsockname() == ("β", 1) 115 assert c1c.remote_addr() == xaddr("α:2") 116 assert c1c.getpeername() == ("α", 2) 117 118 xwrite(c1c, "ping") 119 assert xread(c1c) == "pong" 120 121 c2c = hb.dial("α:1") 122 assert c2c.local_addr() == xaddr("β:2") 123 assert c2c.getsockname() == ("β", 2) 124 assert c2c.remote_addr() == xaddr("α:3") 125 assert c2c.getpeername() == ("α", 3) 126 127 xwrite(c2c, "hello") 128 assert xread(c2c) == "world" 129 130 tsrv.join() 131 132 l2 = ha.listen(":0") 133 assert l2.addr() == xaddr("α:4") 134 135 subnet.close() 136 137 138 def test_lonet_py_basic(): 139 subnet = lonet.join("") 140 _test_virtnet_basic(subnet) 141 142 143 # test interaction with lonet.go 144 @func 145 def test_lonet_py_go(network): 146 subnet = lonet.join(network) 147 defer(subnet.close) 148 149 def xaddr(addr): 150 return lonet.Addr.parse(subnet.network(), addr) 151 152 hb = subnet.new_host("β") 153 lb = hb.listen(":1") 154 155 c1 = hb.dial("α:1") 156 assert c1.local_addr() == xaddr("β:2") 157 assert c1.remote_addr() == xaddr("α:2") 158 assert xread(c1) == "hello py" 159 xwrite(c1, "hello go") 160 c1.close() 161 162 c2 = lb.accept() 163 assert c2.local_addr() == xaddr("β:2") 164 assert c2.remote_addr() == xaddr("α:2") 165 xwrite(c2, "hello2 go") 166 assert xread(c2) == "hello2 py" 167 c2.close() 168 169 170 171 # go created a registry. verify we can read values from it and write something back too. 172 # go side will check what we wrote. 173 def test_registry_pygo(registry_dbpath): 174 try: 175 lonet.SQLiteRegistry(registry_dbpath, "ddd") 176 except lonet.RegistryError as e: 177 assert 'network name mismatch: want "ddd"; have "ccc"' in str(e) 178 else: 179 assert 0, 'network name mismatch not detected' 180 181 r = lonet.SQLiteRegistry(registry_dbpath, "ccc") 182 assert r.query("α") == "alpha:1234" 183 assert r.query("β") is None 184 r.announce("β", "beta:py") 185 assert r.query("β") == "beta:py" 186 187 try: 188 r.announce("β", "beta:py2") 189 except lonet.RegistryError as e: 190 # XXX py escapes utf-8 with \ 191 #assert "announce ('β', 'beta:py2'): host already registered" in str(e) 192 assert ": host already registered" in str(e) 193 else: 194 assert 0, 'duplicate host announce not detected' 195 196 # ok - hand over checks back to go side.