def test_txtmeta_parse(): """ Test the txtmeta parsing feature of the TopologyManager object. """ topology = TopologyManager(engine='debug') dictmeta = topology.parse(TOPOLOGY, load=False) expected = { 'nodes': [{ 'attributes': OrderedDict([('shell', 'vtysh')]), 'nodes': ['sw1', 'sw2'] }, { 'attributes': OrderedDict([('type', 'host')]), 'nodes': ['hs1'] }, { 'attributes': OrderedDict(), 'nodes': ['hs2'] }], 'ports': [], 'links': [{ 'attributes': OrderedDict(), 'endpoints': (('sw1', '1'), ('hs1', '1')) }, { 'attributes': OrderedDict(), 'endpoints': (('sw1', 'a'), ('hs1', 'a')) }, { 'attributes': OrderedDict([('attr1', 1)]), 'endpoints': (('sw1', '4'), ('hs2', 'a')) }] } ddiff = DeepDiff(dictmeta, expected) assert not ddiff
def test_build(): """ Test building and unbuilding a topology using the Mininet engine. """ topology = TopologyManager(engine='debug') # Create topology using the NMLManager sw1 = topology.nml.create_node(identifier='sw1', name='My Switch 1') hs1 = topology.nml.create_node(identifier='hs1', name='My Host 1', type='host') sw1p1 = topology.nml.create_biport(sw1) sw1p2 = topology.nml.create_biport(sw1) sw1p3 = topology.nml.create_biport(sw1) # noqa hs1p1 = topology.nml.create_biport(hs1) hs1p2 = topology.nml.create_biport(hs1) hs1p3 = topology.nml.create_biport(hs1) # noqa sw1p1_hs1p1 = topology.nml.create_bilink(sw1p1, hs1p1) # noqa sw1p2_hs1p2 = topology.nml.create_bilink(sw1p2, hs1p2) # noqa # Build topology topology.build() # Get an engine node assert topology.get('sw1') is not None assert topology.get('hs1') is not None # Unbuild topology topology.unbuild()
def test_txtmeta_parse(): """ Test the txtmeta parsing feature of the TopologyManager object. """ topology = TopologyManager(engine='debug') dictmeta = topology.parse(TOPOLOGY, load=False) expected = { 'nodes': [ { 'attributes': OrderedDict([('shell', 'vtysh')]), 'nodes': ['sw1', 'sw2'] }, { 'attributes': OrderedDict([('type', 'host')]), 'nodes': ['hs1'] }, { 'attributes': OrderedDict(), 'nodes': ['hs2'] } ], 'ports': [], 'links': [ { 'attributes': OrderedDict(), 'endpoints': (('sw1', '1'), ('hs1', '1')) }, { 'attributes': OrderedDict(), 'endpoints': (('sw1', 'a'), ('hs1', 'a')) }, { 'attributes': OrderedDict([('attr1', 1)]), 'endpoints': (('sw1', '4'), ('hs2', 'a')) } ] } ddiff = DeepDiff(dictmeta, expected) assert not ddiff
def test_autoport(): """ Test the autoport feature. """ topodesc = """ [port_number=5] hs1:oobm hs1:a -- hs2:x hs1:2 -- hs2:2 hs1:4 -- hs2:4 hs1:b -- hs2:y """ topology = TopologyManager(engine='debug') topology.parse(topodesc) topology.build() assert topology.get('hs1') is not None assert topology.get('hs2') is not None ports = {k: dict(v) for k, v in topology.ports.items()} expected = { 'hs1': { 'oobm': 'oobm', 'a': 'a', '2': '2', '4': '4', 'b': 'b', }, 'hs2': { 'x': 'x', '2': '2', '4': '4', 'y': 'y', } } topology.unbuild() ddiff = DeepDiff(ports, expected) assert not ddiff
def test_build(): """ Test building and unbuilding a topology using the Mininet engine. """ # Create a graph graph = TopologyGraph() # Create some nodes graph.create_node('sw1', name='My Switch 1') graph.create_node('hs1', name='My Host 1', type='host') # Create some ports graph.create_port('p1', 'sw1') graph.create_port('p2', 'sw1') graph.create_port('p3', 'sw1') graph.create_port('p1', 'hs1') graph.create_port('p2', 'hs1') graph.create_port('p3', 'hs1') # Create the links graph.create_link('sw1', 'p1', 'hs1', 'p1') graph.create_link('sw1', 'p2', 'hs1', 'p2') # Check consistency of the graph graph.check_consistency() # Create the topology and set the graph topology = TopologyManager(engine='debug') topology.graph = graph # Build the topology topology.build() # Get an engine node assert topology.get('sw1') is not None assert topology.get('hs1') is not None # Unbuild topology topology.unbuild()
def test_attribute_injection(tmpdir): """ Test the configuration file is parsed correctly. """ workdir = str(tmpdir) search_path = str(tmpdir.mkdir('test')) try: # Write matching topologies for count, content in enumerate(TOPOLOGY_MATCHES): output_filename = join( search_path, 'test_topology_match_{}.py'.format(count) ) with open(output_filename, 'w') as fd: fd.write('TOPOLOGY = """\n') fd.write(content) fd.write('"""') # Write the attributes injection file injection_path = join(workdir, 'attributes_injection.json') with open(injection_path, 'w') as fd: fd.write(INJECTION_FILE.format(search_path=search_path)) # Change keys of the expected parsed injection file expected = OrderedDict() for key, value in EXPECTED_PARSED_INJECTION_FILE.items(): expected[key.format(search_path=search_path)] = value # Actually parse the injection file actual = parse_attribute_injection( injection_path, search_path=search_path ) # Compare the actual and the expected differences = DeepDiff(actual, expected) # from pprint import pprint # print('--------------------') # pprint(actual) # print('--------------------') # pprint(expected) # print('--------------------') assert not differences # Test building with injected attributes injected_attributes = actual[ '{search_path}/test_topology_match_0.py'.format( search_path=search_path ) ] topology = TopologyManager() topology.parse( TOPOLOGY_TO_BUILD, inject=injected_attributes ) topology.build() sw9 = topology.get('sw9') sw2 = topology.get('sw2') hs3 = topology.get('hs3') hs2 = topology.get('hs2') assert sw9.metadata == { 'shell': 'vtysh', 'name': 'Switch 9' } # [shell=vtysh name="new_name" image=image_for_sw2] sw2 assert sw2.metadata == { 'image': 'image_for_sw2', 'shell': 'vtysh', 'name': 'new_name' } assert hs3.metadata == { 'type': 'host', 'name': 'Host 3' } assert hs2.metadata == { 'type': 'host', 'name': 'Host 2', 'image': 'image_for_all_hosts', 'hardware': 'hardware_for_sw1_sw3_hs1_hs2' } finally: try: rmtree(workdir) except: pass
def test_unlink_relink(): """ Test the unlink and relink calls. Creates a topology with two hosts with a port each one and a named link between them. During execution the link gets down and up again and the connection is asserted in all stages. """ topology = "[identifier=thelink] hs1:a -- hs2:b" mgr = TopologyManager(engine='docker') mgr.parse(topology) mgr.build() hs1 = mgr.get('hs1') hs2 = mgr.get('hs2') try: assert hs1 is not None assert hs2 is not None # Configure IPs hs1('ip link set dev a up') hs1('ip addr add 10.0.15.1/24 dev a') hs2('ip link set dev b up') hs2('ip addr add 10.0.15.2/24 dev b') # Test connection ping_result = hs1('ping -c 1 10.0.15.2') assert '1 packets transmitted, 1 received' in ping_result # Unlink mgr.unlink('thelink') # Test connection ping_result = hs1('ping -c 1 10.0.15.2') assert 'Network is unreachable' in ping_result # Relink mgr.relink('thelink') # Test connection ping_result = hs1('ping -c 1 10.0.15.2') assert '1 packets transmitted, 1 received' in ping_result finally: mgr.unbuild()
def test_unlink_relink(): """ Test the unlink and relink calls. Creates a topology with two hosts with a port each one and a named link between them. During execution the link gets down and up again and the connection is asserted in all stages. """ # Setup which shell to use shell = 'bash' topology = '[identifier=thelink] hs1:a -- hs2:b' mgr = TopologyManager(engine='docker') mgr.parse(topology) mgr.build() hs1 = mgr.get('hs1') hs2 = mgr.get('hs2') try: assert hs1 is not None assert hs2 is not None # Configure IPs hs1('ip link set dev a up', shell=shell) hs1('ip addr add 10.0.15.1/24 dev a', shell=shell) hs2('ip link set dev b up', shell=shell) hs2('ip addr add 10.0.15.2/24 dev b', shell=shell) # Test connection ping_result = hs1('ping -c 1 10.0.15.2', shell=shell) assert '1 packets transmitted, 1 received' in ping_result # Unlink mgr.unlink('thelink') # Test connection ping_result = hs1('ping -c 1 10.0.15.2', shell=shell) assert 'Network is unreachable' in ping_result # Relink mgr.relink('thelink') # Test connection ping_result = hs1('ping -c 1 10.0.15.2', shell=shell) assert '1 packets transmitted, 1 received' in ping_result finally: mgr.unbuild()
def test_attribute_injection(tmpdir): """ Test the configuration file is parsed correctly. """ workdir = str(tmpdir) search_path = str(tmpdir.mkdir('test')) subfolder = str(tmpdir.mkdir('test/subfolder')) try: # Write matching topologies for basepath, matches in ((search_path, TOPOLOGY_MATCHES), (subfolder, TOPOLOGY_MATCHES_FOLDER)): for count, content in matches.items(): output_filename = join( basepath, 'test_topology_match_{}.py'.format(count)) with open(output_filename, 'w') as fd: fd.write('TOPOLOGY = """\n') fd.write(content) fd.write('"""') # Write the attributes injection file injection_path = join(workdir, 'attributes_injection.json') with open(injection_path, 'w') as fd: fd.write(INJECTION_FILE.format(search_path=search_path)) # Change keys of the expected parsed injection file expected = OrderedDict() for key, value in EXPECTED_PARSED_INJECTION_FILE.items(): expected[key.format(search_path=search_path)] = value # Actually parse the injection file actual = parse_attribute_injection(injection_path, search_paths=[search_path]) # Compare the actual and the expected differences = DeepDiff(actual, expected) assert not differences # Test building with injected attributes injected_attributes = actual['{search_path}/test_topology_match_0.py'. format(search_path=search_path)] topology = TopologyManager() topology.parse(TOPOLOGY_TO_BUILD, inject=injected_attributes) topology.build() sw9 = topology.get('sw9') sw2 = topology.get('sw2') sw8 = topology.get('sw8') hs3 = topology.get('hs3') hs2 = topology.get('hs2') assert sw9.metadata == {'shell': 'vtysh', 'name': 'Switch 9'} assert sw2.metadata == { 'image': 'image_for_sw2', 'shell': 'vtysh', 'name': 'new_name' } assert sw8.metadata == { 'type': 'switch', 'name': 'Switch 8', 'chassis': 'chassis_for_sw8' } assert hs3.metadata == {'type': 'host', 'name': 'Host 3'} assert hs2.metadata == { 'type': 'host', 'name': 'Host 2', 'image': 'image_for_all_hosts', 'hardware': 'hardware_for_sw1_sw3_hs1_hs2' } finally: try: rmtree(workdir) except: pass