Commit 388566e8 authored by zhifan huang's avatar zhifan huang Committed by Xiaowu Zhang

fix: fix problem in merge request

modify fixnemu device name comment, remove extra line, space, remove dup
definition, eek
parent fea1061c
...@@ -75,16 +75,15 @@ get_addr_data.func_code = _get_addr_data.func_code ...@@ -75,16 +75,15 @@ get_addr_data.func_code = _get_addr_data.func_code
@staticmethod @staticmethod
def _gen_if_name(): def _gen_if_name():
n = Interface._gen_next_id() n = Interface._gen_next_id()
# The maximum size of the interface name is 15(char [IFNAMSIZ(16)]) # Max 15 chars
# len(NETNSbr-) = 8, So we need to limit the part "%.4x%.3x" % (os.getpid(), n) # XXX: We truncate pid to not exceed IFNAMSIZ on systems with 32-bits pids
# to size 7. That means PID < 0xffff, n < 0xfff # but we should find something better to avoid possible collision.
# PID often exceeds 0xffff, so use mod 0xffff to limit it length.
return "NETNSif-%.4x%.3x" % (os.getpid() % 0xffff, n) return "NETNSif-%.4x%.3x" % (os.getpid() % 0xffff, n)
Interface._gen_if_name = _gen_if_name Interface._gen_if_name = _gen_if_name
@staticmethod @staticmethod
def _gen_br_name(): def _gen_br_name():
n = Switch._gen_next_id() n = Switch._gen_next_id()
# Max 15 chars # XXX: same as for _gen_if_name
return "NETNSbr-%.4x%.3x" % (os.getpid() % 0xffff, n) return "NETNSbr-%.4x%.3x" % (os.getpid() % 0xffff, n)
Switch._gen_br_name = _gen_br_name Switch._gen_br_name = _gen_br_name
import json
import os import os
import unittest
import time
import sqlite3 import sqlite3
from pathlib2 import Path
import subprocess import subprocess
import tempfile import tempfile
import json import time
import unittest
import zlib import zlib
from re6st import registry, x509 from re6st import registry, x509
...@@ -15,7 +15,7 @@ from re6st.tests import DEMO_PATH ...@@ -15,7 +15,7 @@ from re6st.tests import DEMO_PATH
DH_FILE = DEMO_PATH / "dh2048.pem" DH_FILE = DEMO_PATH / "dh2048.pem"
class dummyNode(): class DummyNode(object):
"""fake node to reuse Re6stRegistry """fake node to reuse Re6stRegistry
error: node.Popen has destory method which not in subprocess.Popen error: node.Popen has destory method which not in subprocess.Popen
...@@ -37,7 +37,7 @@ class TestRegistryClentInteract(unittest.TestCase): ...@@ -37,7 +37,7 @@ class TestRegistryClentInteract(unittest.TestCase):
def setUp(self): def setUp(self):
self.port = 18080 self.port = 18080
self.url = "http://localhost:{}/".format(self.port) self.url = "http://localhost:{}/".format(self.port)
# not inportant, used in network_config check # not important, used in network_config check
self.max_clients = 10 self.max_clients = 10
def tearDown(self): def tearDown(self):
...@@ -46,13 +46,13 @@ class TestRegistryClentInteract(unittest.TestCase): ...@@ -46,13 +46,13 @@ class TestRegistryClentInteract(unittest.TestCase):
def test_1_main(self): def test_1_main(self):
""" a client interact a server, no re6stnet node test basic function""" """ a client interact a server, no re6stnet node test basic function"""
try: try:
self.server = re6st_wrap.Re6stRegistry(dummyNode(), "2001:db8:42::", self.server = re6st_wrap.Re6stRegistry(DummyNode(), "2001:db8:42::",
self.max_clients, port=self.port, self.max_clients, port=self.port,
recreate=True) recreate=True)
except: except:
self.skipTest("start registry failed") self.skipTest("start registry failed")
client = registry.RegistryClient(self.url) client = registry.RegistryClient(self.url)
email = "m1@miku.com" email = "m1@miku.com"
# simulate the process in conf # simulate the process in conf
...@@ -60,15 +60,15 @@ class TestRegistryClentInteract(unittest.TestCase): ...@@ -60,15 +60,15 @@ class TestRegistryClentInteract(unittest.TestCase):
client.requestToken(email) client.requestToken(email)
# read token from db # read token from db
db = sqlite3.connect(str(self.server.db), isolation_level=None) db = sqlite3.connect(str(self.server.db), isolation_level=None)
count = 0
token = None token = None
while not token: for _ in xrange(100):
time.sleep(.1) time.sleep(.1)
token = db.execute("SELECT token FROM token WHERE email=?", token = db.execute("SELECT token FROM token WHERE email=?",
(email,)).fetchone() (email,)).fetchone()
count += 1 if token:
if count > 100: break
raise Exception("Request token failed, no token in database") else:
raise Exception("Request token failed, no token in database")
# token: tuple[unicode,] # token: tuple[unicode,]
token = str(token[0]) token = str(token[0])
self.assertEqual(client.isToken(token), "1") self.assertEqual(client.isToken(token), "1")
...@@ -119,4 +119,4 @@ class TestRegistryClentInteract(unittest.TestCase): ...@@ -119,4 +119,4 @@ class TestRegistryClentInteract(unittest.TestCase):
#TODO with a registry and some node, test babel_dump related function #TODO with a registry and some node, test babel_dump related function
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
\ No newline at end of file
import time
import nemu
import weakref
import ipaddress import ipaddress
import logging import logging
import nemu
import time
import weakref
from subprocess import PIPE from subprocess import PIPE
from pathlib2 import Path from pathlib2 import Path
...@@ -13,12 +13,15 @@ fix_file = DEMO_PATH / "fixnemu.py" ...@@ -13,12 +13,15 @@ fix_file = DEMO_PATH / "fixnemu.py"
exec(open(str(fix_file)).read()) exec(open(str(fix_file)).read())
IPTABLES = 'iptables-nft' IPTABLES = 'iptables-nft'
class ConnectableError(Exception):
pass
class Node(nemu.Node): class Node(nemu.Node):
"""simple nemu.Node used for registry and nodes""" """simple nemu.Node used for registry and nodes"""
def __init__(self): def __init__(self):
super(Node, self).__init__() super(Node, self).__init__()
self.Popen(('sysctl', '-q', self.Popen(('sysctl', '-q',
'net.ipv4.icmp_echo_ignore_broadcasts=0')).wait() 'net.ipv4.icmp_echo_ignore_broadcasts=0')).wait()
def _add_interface(self, iface): def _add_interface(self, iface):
self.iface = iface self.iface = iface
...@@ -57,12 +60,12 @@ class NetManager(object): ...@@ -57,12 +60,12 @@ class NetManager(object):
Raise: Raise:
AssertionError AssertionError
""" """
for reg, nodes in self.registries.items(): for reg, nodes in self.registries.iteritems():
for node in nodes: for node in nodes:
app0 = node.Popen(["ping", "-c", "1", reg.ip], stdout=PIPE) app0 = node.Popen(["ping", "-c", "1", reg.ip], stdout=PIPE)
ret = app0.wait() ret = app0.wait()
if ret: if ret:
raise ConnectionError( raise ConnectableError(
"network construct failed {} to {}".format(node.ip, reg.ip)) "network construct failed {} to {}".format(node.ip, reg.ip))
logging.debug("each node can ping to their registry") logging.debug("each node can ping to their registry")
...@@ -83,9 +86,9 @@ def net_route(): ...@@ -83,9 +86,9 @@ def net_route():
machine1 = Node() machine1 = Node()
machine2 = Node() machine2 = Node()
r1_if_0 = registry.connect_switch(switch1, "192.168.1.1") registry.connect_switch(switch1, "192.168.1.1")
m1_if_0 = machine1.connect_switch(switch1, "192.168.1.2") machine1.connect_switch(switch1, "192.168.1.2")
m2_if_0 = machine2.connect_switch(switch1, "192.168.1.3") machine2.connect_switch(switch1, "192.168.1.3")
nm.object.append(switch1) nm.object.append(switch1)
nm.registries[registry] = [machine1, machine2] nm.registries[registry] = [machine1, machine2]
...@@ -120,7 +123,7 @@ def net_demo(): ...@@ -120,7 +123,7 @@ def net_demo():
# for node in [g1, m3, m4, m5]: # for node in [g1, m3, m4, m5]:
# print "pid: {}".format(node.pid) # print "pid: {}".format(node.pid)
re_if_0, in_if_0 = nemu.P2PInterface.create_pair(registry,internet) re_if_0, in_if_0 = nemu.P2PInterface.create_pair(registry, internet)
g1_if_0, in_if_1 = nemu.P2PInterface.create_pair(gateway1, internet) g1_if_0, in_if_1 = nemu.P2PInterface.create_pair(gateway1, internet)
g2_if_0, in_if_2 = nemu.P2PInterface.create_pair(gateway2, internet) g2_if_0, in_if_2 = nemu.P2PInterface.create_pair(gateway2, internet)
...@@ -169,11 +172,11 @@ def net_demo(): ...@@ -169,11 +172,11 @@ def net_demo():
MINIUPnP_CONF = Path(__file__).parent / 'miniupnpd.conf' MINIUPnP_CONF = Path(__file__).parent / 'miniupnpd.conf'
gateway1.proc = gateway1.Popen(['miniupnpd', '-d', '-f', MINIUPnP_CONF, gateway1.proc = gateway1.Popen(['miniupnpd', '-d', '-f', MINIUPnP_CONF,
'-P', 'miniupnpd.pid','-a', gateway1.if_s.name, '-P', 'miniupnpd.pid', '-a', gateway1.if_s.name,
'-i', g1_if_0.name], '-i', g1_if_0.name],
stdout=PIPE, stderr=PIPE) stdout=PIPE, stderr=PIPE)
switch1.up = switch2.up = switch3.up =True switch1.up = switch2.up = switch3.up = True
nm.connectable_test() nm.connectable_test()
return nm return nm
...@@ -192,10 +195,7 @@ def network_direct(): ...@@ -192,10 +195,7 @@ def network_direct():
m_if_0.add_v4_address(u"10.1.2.2", prefix_len=24) m_if_0.add_v4_address(u"10.1.2.2", prefix_len=24)
re_if_0.up = m_if_0.up = True re_if_0.up = m_if_0.up = True
for node in [m0]: nm.connectable_test()
app0 = node.Popen(["ping", "-c", "1", "10.1.2.1"], stdout=PIPE)
ret = app0.wait()
assert ret == 0, "network construct failed"
return nm return nm
if __name__ == "__main__": if __name__ == "__main__":
......
"""wrap the deploy of re6st node, ease the creation of cert """wrap the deploy of re6st node, ease the creation of cert
file and run of the node file and run of the node
""" """
import errno
import ipaddress
import json import json
import logging
import re
import shutil import shutil
import sqlite3 import sqlite3
import weakref
import ipaddress
import time
import re
import tempfile import tempfile
import logging import time
import errno import weakref
from subprocess import PIPE from subprocess import PIPE
from pathlib2 import Path from pathlib2 import Path
...@@ -20,11 +20,8 @@ from re6st.tests import DEMO_PATH ...@@ -20,11 +20,8 @@ from re6st.tests import DEMO_PATH
WORK_DIR = Path(__file__).parent / "temp_net_test" WORK_DIR = Path(__file__).parent / "temp_net_test"
DH_FILE = DEMO_PATH / "dh2048.pem" DH_FILE = DEMO_PATH / "dh2048.pem"
RE6STNET = "re6stnet"
RE6STNET = "python -m re6st.cli.node" RE6STNET = "python -m re6st.cli.node"
RE6ST_REGISTRY = "re6st-registry"
RE6ST_REGISTRY = "python -m re6st.cli.registry" RE6ST_REGISTRY = "python -m re6st.cli.registry"
RE6ST_CONF = "re6st-conf"
RE6ST_CONF = "python -m re6st.cli.conf" RE6ST_CONF = "python -m re6st.cli.conf"
def initial(): def initial():
...@@ -112,18 +109,18 @@ class Re6stRegistry(object): ...@@ -112,18 +109,18 @@ class Re6stRegistry(object):
serial=ip_to_serial(self.ip6)) serial=ip_to_serial(self.ip6))
def run(self): def run(self):
cmd =['--ca', self.ca_crt, '--key', self.ca_key, '--dh', DH_FILE, cmd = ['--ca', self.ca_crt, '--key', self.ca_key, '--dh', DH_FILE,
'--ipv4', '10.42.0.0/16', '8', '--logfile', self.log, '--db', self.db, '--ipv4', '10.42.0.0/16', '8', '--logfile', self.log, '--db', self.db,
'--run', self.run_path, '--hello', '4', '--mailhost', 's', '-v4', '--run', self.run_path, '--hello', '4', '--mailhost', 's', '-v4',
'--client-count', (self.client_number+1)//2, '--port', self.port] '--client-count', (self.client_number+1)//2, '--port', self.port]
#convert PosixPath to str, can be remove in python3 #PY3: convert PosixPath to str, can be remove in Python 3
cmd = map(str, cmd) cmd = map(str, cmd)
cmd = RE6ST_REGISTRY.split() + cmd cmd[:0] = RE6ST_REGISTRY.split()
logging.debug("run registry %s at ns: %s with cmd: %s", logging.debug("run registry %s at ns: %s with cmd: %s",
self.name, self.node.pid, " ".join(cmd)) self.name, self.node.pid, " ".join(cmd))
self.proc = self.node.Popen(cmd, stdout=PIPE, stderr=PIPE) self.proc = self.node.Popen(cmd, stdout=PIPE, stderr=PIPE)
def clean(self): def clean(self):
...@@ -151,7 +148,7 @@ class Re6stNode(object): ...@@ -151,7 +148,7 @@ class Re6stNode(object):
node: nemu node node: nemu node
name: name for res6st node name: name for res6st node
""" """
self.name = name if name else self.generate_name() self.name = name or self.generate_name()
self.node = node self.node = node
self.registry = weakref.proxy(registry) self.registry = weakref.proxy(registry)
...@@ -163,7 +160,7 @@ class Re6stNode(object): ...@@ -163,7 +160,7 @@ class Re6stNode(object):
else: else:
self.run_path = tempfile.mkdtemp() self.run_path = tempfile.mkdtemp()
self.log = self.path / "re6stnet.log" self.log = self.path / "re6stnet.log"
self.crt = self.path / "cert.crt" self.crt = self.path / "cert.crt"
self.key = self.path / 'cert.key' self.key = self.path / 'cert.key'
self.console = self.run_path + "/console.sock" self.console = self.run_path + "/console.sock"
...@@ -179,8 +176,8 @@ class Re6stNode(object): ...@@ -179,8 +176,8 @@ class Re6stNode(object):
if self.data_file.exists(): if self.data_file.exists():
with self.data_file.open() as f: with self.data_file.open() as f:
data = json.load(f) data = json.load(f)
self.ip6 = data.get("ip6") self.ip6 = data.get("ip6")
recreate = not data.get('hash') == self.registry.ident recreate = data.get('hash') != self.registry.ident
else: else:
recreate = True recreate = True
...@@ -195,7 +192,6 @@ class Re6stNode(object): ...@@ -195,7 +192,6 @@ class Re6stNode(object):
self.clean() self.clean()
def __repr__(self): def __repr__(self):
return self.name return self.name
...@@ -208,21 +204,21 @@ class Re6stNode(object): ...@@ -208,21 +204,21 @@ class Re6stNode(object):
"""create necessary file for node""" """create necessary file for node"""
logging.info("create dir of node %s", self.name) logging.info("create dir of node %s", self.name)
cmd = ["--registry", self.registry.url, '--email', self.email] cmd = ["--registry", self.registry.url, '--email', self.email]
cmd = RE6ST_CONF.split() + cmd cmd[:0] = RE6ST_CONF.split()
p = self.node.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, p = self.node.Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE,
cwd=str(self.path)) cwd=str(self.path))
# read token # read token
db = sqlite3.connect(str(self.registry.db), isolation_level=None) db = sqlite3.connect(str(self.registry.db), isolation_level=None)
count = 0
token = None token = None
while not token: for _ in xrange(100):
time.sleep(.1) time.sleep(.1)
token = db.execute("SELECT token FROM token WHERE email=?", token = db.execute("SELECT token FROM token WHERE email=?",
(self.email,)).fetchone() (self.email,)).fetchone()
count += 1 if token:
if count > 100: break
p.destroy() else:
raise Exception("can't connect to the Register") p.destroy()
raise Exception("can't connect to the Register")
out, _ = p.communicate(str(token[0])) out, _ = p.communicate(str(token[0]))
# logging.debug("re6st-conf output: {}".format(out)) # logging.debug("re6st-conf output: {}".format(out))
...@@ -239,12 +235,13 @@ class Re6stNode(object): ...@@ -239,12 +235,13 @@ class Re6stNode(object):
'--dh', DH_FILE, '--ca', self.registry.ca_crt, '--cert', self.crt, '--dh', DH_FILE, '--ca', self.registry.ca_crt, '--cert', self.crt,
'--key', self.key, '-v4', '--registry', self.registry.url, '--key', self.key, '-v4', '--registry', self.registry.url,
'--console', self.console] '--console', self.console]
#PY3: same as for Re6stRegistry.run
cmd = map(str, cmd) cmd = map(str, cmd)
cmd = RE6STNET.split() + cmd cmd[:0] = RE6STNET.split()
cmd += args cmd += args
logging.debug("run node %s at ns: %s with cmd: %s", logging.debug("run node %s at ns: %s with cmd: %s",
self.name, self.node.pid, " ".join(cmd)) self.name, self.node.pid, " ".join(cmd))
# if len(args) > 4 : # if len(args) > 4 :
# self.proc = self.node.Popen(cmd) # self.proc = self.node.Popen(cmd)
# else: # else:
...@@ -265,15 +262,14 @@ class Re6stNode(object): ...@@ -265,15 +262,14 @@ class Re6stNode(object):
logging.debug("%s teminate process %s", self.name, self.proc.pid) logging.debug("%s teminate process %s", self.name, self.proc.pid)
self.proc.destroy() self.proc.destroy()
def __del__(self): def __del__(self):
"""teminate process and rm temp dir""" """teminate process and rm temp dir"""
try: try:
self.stop() self.stop()
except Exception as e: except Exception as e:
logging.warn("%s: %s", self.name, e) logging.warning("%s: %s", self.name, e)
# python2 seems auto clean the tempdir # re6stnet seems auto clean the tempdir
# try: # try:
# shutil.rmtree(self.run_path) # shutil.rmtree(self.run_path)
# except Exception as e: # except Exception as e:
......
...@@ -4,12 +4,11 @@ import unittest ...@@ -4,12 +4,11 @@ import unittest
import time import time
import psutil import psutil
import logging import logging
import sqlite3
import random import random
from binascii import b2a_hex
from pathlib2 import Path from pathlib2 import Path
import network_build
import re6st_wrap import re6st_wrap
import network_build
PING_PATH = str(Path(__file__).parent.resolve() / "ping.py") PING_PATH = str(Path(__file__).parent.resolve() / "ping.py")
...@@ -53,7 +52,7 @@ def wait_stable(nodes, timeout=240): ...@@ -53,7 +52,7 @@ def wait_stable(nodes, timeout=240):
# check all the node network can ping each other, in order reverse # check all the node network can ping each other, in order reverse
unfinished = list(nodes) unfinished = list(nodes)
while unfinished: while unfinished:
for i in range(len(unfinished)-1, -1, -1): for i in xrange(len(unfinished)-1, -1, -1):
node = unfinished[i] node = unfinished[i]
if node.ping_proc.poll() is not None: if node.ping_proc.poll() is not None:
logging.debug("%s 's network is stable", node.name) logging.debug("%s 's network is stable", node.name)
...@@ -63,12 +62,12 @@ def wait_stable(nodes, timeout=240): ...@@ -63,12 +62,12 @@ def wait_stable(nodes, timeout=240):
if time.time() - now > timeout: if time.time() - now > timeout:
for node in unfinished: for node in unfinished:
node.ping_proc.destroy() node.ping_proc.destroy()
logging.warn("%s can't ping to all the nodes", unfinished) logging.warning("%s can't ping to all the nodes", unfinished)
return False return False
logging.info("wait time cost: %s", time.time() - now) logging.info("wait time cost: %s", time.time() - now)
return True return True
@unittest.skipIf(os.geteuid() != 0, "require root or create user namespace plz") @unittest.skipIf(os.geteuid(), "Using root or creating a user namespace")
class TestNet(unittest.TestCase): class TestNet(unittest.TestCase):
""" network test case""" """ network test case"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment