Commit 61149ff9 authored by zhifan huang's avatar zhifan huang

add brdige device test

parent 5100b8e3
...@@ -45,9 +45,26 @@ class Device(object): ...@@ -45,9 +45,26 @@ class Device(object):
self.ips.append(address) self.ips.append(address)
self.net.run(['ip', 'addr', 'add', ip, 'dev', self.name]) self.net.run(['ip', 'addr', 'add', ip, 'dev', self.name])
class Bridge(Device):
def __init__(self, netns, name=None):
super(Bridge, self).__init__("bridge", name)
netns.add_device(self)
netns.run(['ip', 'link', 'add', self.name, 'type', 'bridge'])
self.up = True
class Netns(object): class Netns(object):
"""a network namespace""" """a network namespace"""
@property
def ip(self):
return self.out.ips[-1]
@property
def out(self):
return self.devices[-1]
def __init__(self): def __init__(self):
self.devices = [] self.devices = []
self.app = subprocess.Popen(['unshare', '-n'], stdin=subprocess.PIPE) self.app = subprocess.Popen(['unshare', '-n'], stdin=subprocess.PIPE)
...@@ -70,12 +87,13 @@ class Netns(object): ...@@ -70,12 +87,13 @@ class Netns(object):
""" wrapper for subprocess.checkout""" """ wrapper for subprocess.checkout"""
subprocess.check_call(['nsenter', '-t', str(self.pid), '-n'] + cmd, stdout=stdout, stderr=stderr, **kw) subprocess.check_call(['nsenter', '-t', str(self.pid), '-n'] + cmd, stdout=stdout, stderr=stderr, **kw)
def add_device(self, dev): def add_device(self, dev):
self.devices.append(dev) self.devices.append(dev)
dev.net = weakref.proxy(self) dev.net = weakref.proxy(self)
@staticmethod @staticmethod
def connect_direct(node1, node2): def connect_direct(node1, node2):
"""connect 2 node by veth""" """connect 2 node by veth"""
...@@ -83,18 +101,24 @@ class Netns(object): ...@@ -83,18 +101,24 @@ class Netns(object):
dev2 = Device("veth") dev2 = Device("veth")
node1.add_device(dev1) node1.add_device(dev1)
node2.add_device(dev2) node2.add_device(dev2)
subprocess.check_call(['ip', 'link', 'add', dev1.name, 'netns', str(node1.pid) ,'type', 'veth', 'peer', dev2.name, 'netns', str(node2.pid)]) subprocess.check_call(['ip', 'link', 'add', dev1.name, 'netns', str(node1.pid) ,'type', 'veth', 'peer', dev2.name, 'netns', str(node2.pid)])
dev1.add_ip4("10.1.1.1", prefix=24) dev1.add_ip4("10.1.1.1", prefix=24)
dev2.add_ip4("10.1.1.2", prefix=24) dev2.add_ip4("10.1.1.2", prefix=24)
dev1.up = dev2.up = True dev1.up = dev2.up = True
return dev1, dev2
@property def connect_bridge(self, bridge):
def ip(self): dev1 = Device("veth")
return self.out.ips[-1] dev2 = Device("veth")
self.add_device(dev1)
bridge.net.add_device(dev2)
subprocess.check_call(['ip', 'link', 'add', dev1.name, 'netns', str(self.pid) ,'type', 'veth', 'peer', dev2.name, 'netns', str(bridge.net.pid)])
bridge.net.run(['ip', 'link', 'set', dev2.name, 'master', bridge.name])
dev1.up = dev2.up = True
return dev1, dev2
@property
def out(self):
return self.devices[-1]
def main(): def main():
...@@ -103,15 +127,11 @@ def main(): ...@@ -103,15 +127,11 @@ def main():
print("pid, 1:{}, 2:{}".format(app1.pid, app2.pid)) print("pid, 1:{}, 2:{}".format(app1.pid, app2.pid))
Netns.connect_direct(app1, app2) Netns.connect_direct(app1, app2)
# subprocess.check_call(['nsenter', '-t', str(app1.pid), '-n','ip', 'route', 'add', '10.1.1.0/24', 'via', '10.1.1.1']) # subprocess.check_call(['nsenter', '-t', str(app1.pid), '-n','ip', 'route', 'add', '10.1.1.0/24', 'via', '10.1.1.1'])
# subprocess.check_call(['ip', 'route', 'add', '10.1.1.0/24', 'via', '10.1.1.2']) # subprocess.check_call(['ip', 'route', 'add', '10.1.1.0/24', 'via', '10.1.1.2'])
subprocess.check_call(['nsenter', '-t', str(app2.pid), '-n'] + ["ping", "10.1.1.1"]) subprocess.check_call(['nsenter', '-t', str(app2.pid), '-n'] + ["ping", "10.1.1.1"])
def net_simple(): def net_simple():
nm = NetManager() nm = NetManager()
node1 = Netns() node1 = Netns()
...@@ -120,9 +140,48 @@ def net_simple(): ...@@ -120,9 +140,48 @@ def net_simple():
# subprocess.check_call(['nsenter', '-t', str(node2.pid), '-n'] + ["ping", '-c', '1', "10.1.1.1"]) # subprocess.check_call(['nsenter', '-t', str(node2.pid), '-n'] + ["ping", '-c', '1', "10.1.1.1"])
nm.registrys[node1] = [node2] nm.registrys[node1] = [node2]
for reg in nm.registrys:
for node in nm.registrys[reg]:
app0 = node.Popen(["ping", "-c", "1", reg.ip], stdout=subprocess.PIPE)
ret = app0.wait()
assert ret == 0, "network construct failed"
return nm
def net_route():
"""netns connect by a route(bridge)"""
nm = NetManager()
router = Netns()
br = Bridge(router)
registry = Netns()
node1 = Netns()
node2 = Netns()
veth_r, _ = registry.connect_bridge(br)
veth_n1, _ = node1.connect_bridge(br)
veth_n2, _ = node2.connect_bridge(br)
veth_r.add_ip4("192.168.1.1", 24)
veth_n1.add_ip4("192.168.1.2", 24)
veth_n2.add_ip4("192.168.1.3", 24)
nm.object.append(router)
nm.registrys[registry] = [node1, node2]
for reg in nm.registrys:
for node in nm.registrys[reg]:
app0 = node.Popen(["ping", "-c", "1", reg.ip], stdout=subprocess.PIPE)
ret = app0.wait()
assert ret == 0, "network construct failed"
return nm return nm
if __name__ == "__main__": if __name__ == "__main__":
main() net_route()
print("good bye!") print("good bye!")
...@@ -7,9 +7,11 @@ import weakref ...@@ -7,9 +7,11 @@ import weakref
import ipaddress import ipaddress
import time import time
import re import re
import tempfile
from subprocess import PIPE, call from subprocess import PIPE, call
from pathlib2 import Path from pathlib2 import Path
import re6st.tests.tools as tools import re6st.tests.tools as tools
WORK_DIR = Path(__file__).parent.resolve() / "temp_net_test" WORK_DIR = Path(__file__).parent.resolve() / "temp_net_test"
...@@ -52,7 +54,7 @@ class Re6stRegistry(object): ...@@ -52,7 +54,7 @@ class Re6stRegistry(object):
self.ca_crt = self.path / "ca.cert" self.ca_crt = self.path / "ca.cert"
self.log = self.path / "registry.log" self.log = self.path / "registry.log"
self.db = self.path / "registry.db" self.db = self.path / "registry.db"
self.run_path = self.path / "run" self.run_path = tempfile.mkdtemp()
if recreate and self.path.exists(): if recreate and self.path.exists():
shutil.rmtree(str(self.path)) shutil.rmtree(str(self.path))
...@@ -69,8 +71,16 @@ class Re6stRegistry(object): ...@@ -69,8 +71,16 @@ class Re6stRegistry(object):
self.run() self.run()
# wait the servcice started # wait the servcice started
while(not self.log.exists()): self.node.Popen(['python', '-c', """if 1:
time.sleep(0.1) import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
try:
s.connect(('localhost', 80))
break
except socket.error:
time.sleep(.1)
"""]).wait()
@classmethod @classmethod
def generate_name(cls): def generate_name(cls):
...@@ -102,6 +112,7 @@ class Re6stRegistry(object): ...@@ -102,6 +112,7 @@ class Re6stRegistry(object):
def __del__(self): def __del__(self):
try: try:
self.proc.terminate() self.proc.terminate()
shutil.rmtree(self.run_path)
except: except:
pass pass
...@@ -121,10 +132,10 @@ class Re6stNode(object): ...@@ -121,10 +132,10 @@ class Re6stNode(object):
self.path = WORK_DIR / self.name self.path = WORK_DIR / self.name
self.email = self.name + "@example.com" self.email = self.name + "@example.com"
self.run_path = self.path / "run" self.run_path = tempfile.mkdtemp()
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"
self.data_file = self.path / "data.json" # contain data for restart node self.data_file = self.path / "data.json" # contain data for restart node
...@@ -176,8 +187,10 @@ class Re6stNode(object): ...@@ -176,8 +187,10 @@ class Re6stNode(object):
(self.email,)).fetchone() (self.email,)).fetchone()
count += 1 count += 1
if count > 100: if count > 100:
p.terminate()
raise Exception("can't connect to the Register") raise Exception("can't connect to the Register")
out, _ = p.communicate(str(token[0])) out, _ = p.communicate(str(token[0]))
print "output: {}".format(out)
self.ip6 = re.search('(?<=subnet: )[0-9:a-z]+', out).group(0) self.ip6 = re.search('(?<=subnet: )[0-9:a-z]+', out).group(0)
data = {'ip6': self.ip6, 'hash': self.registry.ident} data = {'ip6': self.ip6, 'hash': self.registry.ident}
...@@ -201,5 +214,6 @@ class Re6stNode(object): ...@@ -201,5 +214,6 @@ class Re6stNode(object):
def __del__(self): def __del__(self):
try: try:
self.proc.terminate() self.proc.terminate()
shutil.rmtree(self.run_path)
except: except:
pass pass
...@@ -11,6 +11,23 @@ import my_net ...@@ -11,6 +11,23 @@ import my_net
PING_PATH = str(Path(__file__).parent.resolve() / "ping.py") PING_PATH = str(Path(__file__).parent.resolve() / "ping.py")
def deploy_re6st(nm):
net = nm.registrys
nodes = []
registrys = []
for registry in net:
reg = re6st_wrap.Re6stRegistry(registry, "2001:db8:42::", recreate=True)
reg_node = re6st_wrap.Re6stNode(registry, reg, name=reg.name)
registrys.append(reg)
reg_node.run("--gateway", "--disable-proto", "none", "--ip", registry.ip)
nodes.append(reg_node)
print("add nodes")
for m in net[registry]:
node = re6st_wrap.Re6stNode(m, reg)
node.run("-i" + m.out.name)
nodes.append(node)
return nodes, registrys
def wait_stable(nodes, timeout=180): def wait_stable(nodes, timeout=180):
sys.stderr.write("wait stalbe\n") sys.stderr.write("wait stalbe\n")
now = time.time() now = time.time()
...@@ -31,6 +48,8 @@ def wait_stable(nodes, timeout=180): ...@@ -31,6 +48,8 @@ def wait_stable(nodes, timeout=180):
node.ping_proc.wait() node.ping_proc.wait()
time.sleep(0.5) time.sleep(0.5)
if time.time() - now > timeout: if time.time() - now > timeout:
for node in unfinished:
node.ping_proc.terminate()
raise Exception("wait network stable timeout") raise Exception("wait network stable timeout")
def ping_test(nodes): def ping_test(nodes):
...@@ -73,25 +92,26 @@ class TestPing(unittest.TestCase): ...@@ -73,25 +92,26 @@ class TestPing(unittest.TestCase):
proc = proc.split()[1] proc = proc.split()[1]
subprocess.call(["kill", "-15", proc]) subprocess.call(["kill", "-15", proc])
def test_sample(self): def test_sample(self):
"""create a network demo, test the connectivity by ping """create a network demo, test the connectivity by ping
wait the network stable then ping 3 times wait the network stable then ping 3 times
""" """
nm = my_net.net_simple() nm = my_net.net_simple()
net = nm.registrys nodes, registrys = deploy_re6st(nm)
nodes = []
registrys = [] wait_stable(nodes)
for registry in net: for i in range(3):
reg = re6st_wrap.Re6stRegistry(registry, "2001:db8:42::", recreate=True) time.sleep(20)
reg_node = re6st_wrap.Re6stNode(registry, reg, name=reg.name) self.assertFalse(ping_test(nodes), "N.{} ping test failed".format(i))
registrys.append(registry)
reg_node.run("--gateway", "--disable-proto", "none", "--ip", registry.ip)
nodes.append(reg_node) def test_routeur(self):
for m in net[registry]: """create a network demo, test the connectivity by ping
print("add nodes") wait the network stable then ping 3 times
node = re6st_wrap.Re6stNode(m, reg) """
node.run("-i" + m.out.name) nm = my_net.net_route()
nodes.append(node) nodes, registrys = deploy_re6st(nm)
wait_stable(nodes) wait_stable(nodes)
for i in range(3): for i in range(3):
......
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