Ejemplo n.º 1
0
def test_min_latency_app():
    """Test a single min latency app"""
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([1]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    appconfig = {
        'name': u'te',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_LATENCY, (), {}),
        'resource_cost': {
            BANDWIDTH: (LINKS, 1, None)
        }
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(BANDWIDTH, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()

    # norm factor for latency is diameter * n^2
    norm = topo.diameter() * 16
    # the objective is 1-normalized latency, and latency is 1.
    # because 1 path with flow fraction of 1.
    solution = opt.get_solved_objective(app)[0]
    assert solution == 1 - 1 / norm or abs(solution -
                                           (1 - 1 / norm)) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == 1 - 1 / norm or abs(solution -
                                           (1 - 1 / norm)) <= EPSILON
Ejemplo n.º 2
0
def test_maxflow(cap):
    """ Check that maxflow works correctly, for a single traffic class """
    # Generate a topology:
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([3]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)

    appconfig = {
        'name': u'mf',
        'constraints': [],
        'obj': (Objective.MAX_FLOW, (), {}),
        'resource_cost': {
            BANDWIDTH: (LINKS, 1, None)
        }
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(BANDWIDTH, cap=cap)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()
    # Ensure that both app objective and global objective are the same
    # Also, use abs(actual - exprected) because floating point errors
    solution = opt.get_solved_objective(app)[0]
    assert solution == cap or abs(solution - cap) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == cap or abs(solution - cap) <= EPSILON
Ejemplo n.º 3
0
def test_mbox_load_balancing():
    """Test the middlebox loadbalancing"""

    topo = complete_topology(4)
    for n in topo.nodes():
        topo.set_resource(n, CPU, 1)
        topo.set_mbox(n)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([1]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo,
                             tcs,
                             has_mbox_predicate,
                             modify_func=use_mbox_modifier,
                             cutoff=100)
    appconfig = {
        'name': u'mb_lb',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_NODE_LOAD, (CPU, ), {}),
        'resource_cost': {
            CPU: (MBOXES, 1, None)
        }
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(CPU, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()
    # THE solution is 1-objective because of the maximization flip
    solution = 1 - opt.get_solved_objective(app)[0]
    # Use abs(actual - exprected) because floating point errors
    assert solution == .25 or abs(solution - .25) <= EPSILON
    solution = 1 - opt.get_solved_objective()
    assert solution == .25 or abs(solution - .25) <= EPSILON
Ejemplo n.º 4
0
def test_te_app():
    """ Test a single traffic engineering app"""
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([1]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    appconfig = {
        'name': u'te',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_LINK_LOAD, (BANDWIDTH,), {}),
        'resource_cost': {BANDWIDTH: (LINKS, 1, None)}
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(BANDWIDTH, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()
    # THE solution is 1-objective because of the maximization flip
    solution = 1 - opt.get_solved_objective(app)[0]
    # Use abs(actual - exprected) because floating point errors
    assert solution == .333333 or abs(solution - .33333) <= EPSILON
    solution = 1 - opt.get_solved_objective()
    assert solution == .333333 or abs(solution - .33333) <= EPSILON
Ejemplo n.º 5
0
def test_maxflow_inapp_caps(cap):
    """Text maxflow, but use the CAP constraint instead of global network caps"""
    # Generate a topology:
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([3]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    caps = {link: cap for link in topo.links()}
    appconfig = {
        'name': u'mf',
        'constraints': [(Constraint.CAP_LINKS, (BANDWIDTH, caps), {})],
        'obj': (Objective.MAX_FLOW, (), {}),
        'resource_cost': {BANDWIDTH: (LINKS, 1, None)}
    }
    app = App(pptc, **appconfig)
    opt = from_app(topo, app, NetworkConfig())
    opt.solve()
    assert opt.is_solved()
    # Ensure that both app objective and global objective are the same
    # Also, use abs(actual - exprected) because floating point errors
    solution = opt.get_solved_objective(app)[0]
    assert solution == cap or abs(solution - cap) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == cap or abs(solution - cap) <= EPSILON
Ejemplo n.º 6
0
def test_mbox_load_balancing_all_tcs():
    """Test the middlebox loadbalancing"""

    topo = complete_topology(4)
    for n in topo.nodes():
        topo.set_resource(n, CPU, 1)
        topo.set_mbox(n)
    tcs = [TrafficClass(0, u'classname', s, t, array([1])) for (s, t) in product(topo.nodes(), repeat=2)]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, has_mbox_predicate, modify_func=use_mbox_modifier, cutoff=100)
    appconfig = {
        'name': u'mb_lb',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_NODE_LOAD, (CPU,), {}),
        'resource_cost': {CPU: (MBOXES, 1, None)}
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(CPU, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()
    # THE solution is 1-objective because of the maximization flip
    solution = 1 - opt.get_solved_objective(app)[0]
    # Use abs(actual - exprected) because floating point errors
    assert solution == 1 or abs(solution - 1) <= EPSILON
    solution = 1 - opt.get_solved_objective()
    assert solution == 1 or abs(solution - 1) <= EPSILON
Ejemplo n.º 7
0
def test_te_app():
    """ Test a single traffic engineering app"""
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([1]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    appconfig = {
        'name': u'te',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_LINK_LOAD, (BANDWIDTH, ), {}),
        'resource_cost': {
            BANDWIDTH: (LINKS, 1, None)
        }
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(BANDWIDTH, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()
    # THE solution is 1-objective because of the maximization flip
    solution = 1 - opt.get_solved_objective(app)[0]
    # Use abs(actual - exprected) because floating point errors
    assert solution == .333333 or abs(solution - .33333) <= EPSILON
    solution = 1 - opt.get_solved_objective()
    assert solution == .333333 or abs(solution - .33333) <= EPSILON
Ejemplo n.º 8
0
def test_min_latency_app():
    """Test a single min latency app"""
    topo = complete_topology(4)
    for link in topo.links():
        topo.set_resource(link, BANDWIDTH, 1)
    tcs = [TrafficClass(0, u'classname', 0, 2, array([1]))]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    appconfig = {
        'name': u'te',
        'constraints': [(Constraint.ROUTE_ALL, (), {})],
        'obj': (Objective.MIN_LATENCY, (), {}),
        'resource_cost': {BANDWIDTH: (LINKS, 1, None)}
    }
    app = App(pptc, **appconfig)
    caps = NetworkCaps(topo)
    caps.add_cap(BANDWIDTH, cap=1)
    opt = from_app(topo, app, NetworkConfig(caps))
    opt.solve()
    assert opt.is_solved()

    # norm factor for latency is diameter * n^2
    norm = topo.diameter() * 16
    # the objective is 1-normalized latency, and latency is 1.
    # because 1 path with flow fraction of 1.
    solution = opt.get_solved_objective(app)[0]
    assert solution == 1 - 1 / norm or abs(solution - (1 - 1 / norm)) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == 1 - 1 / norm or abs(solution - (1 - 1 / norm)) <= EPSILON
Ejemplo n.º 9
0
def test_switch_labels():
    """
    Ensure that switches are labeled appropriately by default
    """
    for topo in [complete_topology(5), chain_topology(5)]:
        for node in topo.nodes():
            assert SWITCH in topo.get_service_types(node)
Ejemplo n.º 10
0
def test_graph_directed():
    """
    Insure we keep newly constructed topologies as directed graph
    """
    topo = complete_topology(5)
    assert isinstance(topo.get_graph(), networkx.DiGraph)
    # even if original graph is undirected
    topo = Topology('noname', networkx.star_graph(8))
    assert topo.get_graph().is_directed()
Ejemplo n.º 11
0
def MaxFlow():
    # ==============
    # Let's generate some example data; SOL has some functions to help with that.
    # ==============
    # A complete topology
    topo = complete_topology(5)
    # ingress-egress pairs, between which the traffic will flow
    iePairs = [(0, 3)]
    # generate a traffic matrix, in this case, a uniform traffic matrix with a million flows
    trafficMatrix = provisioning.uniformTM(
        iePairs, 10 ** 6)
    # compute traffic classes. We will only have one class that encompasses all the traffic;
    # assume that each flow consumes 2000 units of bandwidth
    trafficClasses = generateTrafficClasses(iePairs, trafficMatrix, {'allTraffic': 1},
                                            {'allTraffic': 2000})
    # since our topology is "fake", provision our links and generate link capacities in our network
    linkcaps = provisioning.provision_links(topo, trafficClasses, 1)
    # these will be our link constraints: do not load links more than 50%
    linkConstrCaps = {(u, v): .5 for u, v in topo.links()}

    # ==============
    # Optimization
    # ==============

    # Start our optimization.
    # SOL automatically takes care of the path generation, but it needs the topology, traffic classes, path predicate
    # and path selection strategy.
    # nullPredicate means any path will do, no specific service chaining or policy requirements.
    # Then, SOL will choose maximum of 5 shortest paths for each traffic class to route traffic on.
    opt, pptc = initOptimization(topo, trafficClasses, nullPredicate, 'shortest', 5, backend='CPLEX')

    # Now, our constraints.
    # First, we must allocate some amount of flow (i.e, tell SOL to route things frorm ingress to egress)
    opt.allocate_flow(pptc)

    # Traffic must not overload links -- so cap links according to our link constraints (recall the 50%)
    # linkcapfunc defines how bandwidth is consumed.
    linkcapfunc = lambda link, tc, path, resource: tc.volBytes / linkcaps[link]
    opt.capLinks(pptc, 'bandwidth', linkConstrCaps, linkcapfunc)

    # Push as much traffic as we can
    opt.maxFlow(pptc)

    # Solve the optimization
    opt.solve()

    # For simple applications we can interface with ONOS and setup forwarding routes automatically:
    # Insert correct address to the web interface here;
    # You must ensure that ONOS is running the SOL app to be able to install rules in a batch
    onos = ONOSInterface("localhost:8181")
    routes = {}
    for tc, paths in opt.get_path_fractions(pptc).iteritems():
        routes.update(computeSplit(tc, paths, 0))
    onos.push_routes(routes)
    print("Done")
Ejemplo n.º 12
0
def test_complete_generators(size):
    """
    Some basic tests for complete topology generators. Ensure we return correct types
    and correct number of nodes.
    """
    topo = complete_topology(size)
    assert isinstance(topo, Topology)
    assert isinstance(topo.get_graph(), networkx.DiGraph)
    assert topo.num_nodes() == size
    assert networkx.is_isomorphic(topo.get_graph().to_undirected(),
                                  networkx.complete_graph(size))
Ejemplo n.º 13
0
def MaxFlow():
    # ==============
    # Let's generate some example data; SOL has some functions to help with that.
    # ==============
    # A complete topology
    topo = complete_topology(5)
    # ingress-egress pairs, between which the traffic will flow
    iePairs = [(0, 3)]
    # generate a traffic matrix, in this case, a uniform traffic matrix with a million flows
    trafficMatrix = provisioning.uniformTM(
        iePairs, 10 ** 6)
    # compute traffic classes. We will only have one class that encompasses all the traffic;
    # assume that each flow consumes 2000 units of bandwidth
    trafficClasses = generateTrafficClasses(iePairs, trafficMatrix, {'allTraffic': 1},
                                            {'allTraffic': 2000})
    # since our topology is "fake", provision our links and generate link capacities in our network
    linkcaps = provisioning.provision_links(topo, trafficClasses, 1)
    # these will be our link constraints: do not load links more than 50%
    linkConstrCaps = {(u, v): .5 for u, v in topo.links()}

    # ==============
    # Optimization
    # ==============

    # Start our optimization.
    # SOL automatically takes care of the path generation, but it needs the topology, traffic classes, path predicate
    # and path selection strategy.
    # nullPredicate means any path will do, no specific service chaining or policy requirements.
    # Then, SOL will choose maximum of 5 shortest paths for each traffic class to route traffic on.
    opt, pptc = initOptimization(topo, trafficClasses, nullPredicate, 'shortest', 5, backend='CPLEX')

    # Now, our constraints.
    # First, we must allocate some amount of flow (i.e, tell SOL to route things frorm ingress to egress)
    opt.allocate_flow(pptc)

    # Traffic must not overload links -- so cap links according to our link constraints (recall the 50%)
    # linkcapfunc defines how bandwidth is consumed.
    linkcapfunc = lambda link, tc, path, resource: tc.volBytes / linkcaps[link]
    opt.capLinks(pptc, 'bandwidth', linkConstrCaps, linkcapfunc)

    # Push as much traffic as we can
    opt.maxFlow(pptc)

    # Solve the optimization
    opt.solve()

    ### Results
    # Print the objective function --- this is the flow fraction we managed to send through the network
    print opt.get_solved_objective()

    # pretty-print the paths on which the traffic is routed, along with the fraction for each traffic class
    for tc, paths in opt.get_path_fractions(pptc).iteritems():
        print 'src:', tc.src, 'dst:', tc.dst, 'paths:', pprint.pformat(paths)
Ejemplo n.º 14
0
def pptc():
    """
    An example paths per traffic class
    """
    # get a complete topology
    topo = complete_topology(5)
    # generate a dummy TM and traffic classes
    tm = tmgen.uniform_tm(5, 20, 50, 1)
    tc = traffic_classes(tm, {u'all': 1}, as_dict=False)
    # generate all possibe paths
    res = generate_paths_tc(topo, tc, null_predicate, 10, numpy.inf)
    return res
Ejemplo n.º 15
0
def test_num_nodes(size, some_text):
    """
    Check that num_nodes functions correctly regardless of topology size and service type
    :param size: size of the topology
    :param some_text: service type to test the absense of. So anything except 'switch'
    :return:
    """
    assume(some_text)
    topo = complete_topology(size)
    assert topo.num_nodes() == size  # size of the network
    assert topo.num_nodes(SWITCH) == size  # everyting is a switch
    assert topo.num_nodes(some_text) == 0  # no other functions present
Ejemplo n.º 16
0
def test_write_read(tmpdir):
    """Check that writing topology to disk and restoring it produces the expected result"""
    dirname = u(os.path.abspath(tmpdir.dirname))
    topo = complete_topology(5)
    for l in topo.links():
        topo.set_resource(l, 'myresource', 4)
    topo.write_graph(dirname + os.path.sep + u'testgml.gml')
    topo2 = Topology(topo.name)
    topo2.load_graph(dirname + os.path.sep + u'testgml.gml')
    assert networkx.is_isomorphic(topo.get_graph(), topo2.get_graph())
    assert topo.name == topo2.name

    # Check that resources are preserved
    for n in topo.nodes():
        assert topo.get_resources(n) == topo2.get_resources(n)
    for l in topo.links():
        assert topo.get_resources(n) == topo2.get_resources(n)
Ejemplo n.º 17
0
def test_shortest_path():
    """ Check that we can correctly implement shortest path routing """
    # Generate a topology:
    topo = complete_topology(5)

    # Generate a single traffic class:
    # TrafficClass (id, name, source node, destination node)
    tcs = [TrafficClass(0, u'classname', 0, 2)]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    # Application configuration
    appconfig = {
        'name': u'minLatencyApp',
        'constraints': [(Constraint.ROUTE_ALL, (pptc.tcs(),), {})],
        'obj': (Objective.MIN_LATENCY, (), {}),
        'resource_cost': {}
    }

    # Create an application based on our config
    app = App(pptc, **appconfig)

    # Create and solve an optimization based on the app
    # No link capacities will just result in a single shortest path
    opt = from_app(topo, app, NetworkConfig(None))
    opt.solve()
    assert opt.is_solved()

    paths = opt.get_paths()
    for pi, p in enumerate(paths.paths(tcs[0])):
        if list(p.nodes()) == [0, 2]:
            assert p.flow_fraction() == 1
        else:
            assert p.flow_fraction() == 0

    # norm factor for latency is diameter * n^2
    norm = topo.diameter() * 25
    # the objective is 1-normalized latency, and latency is 1.
    # because 1 path with flow fraction of 1.
    solution = opt.get_solved_objective(app)[0]
    assert solution == 1 - 1 / norm or abs(solution - 1 - 1 / norm) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == 1 - 1 / norm or abs(solution - 1 - 1 / norm) <= EPSILON
Ejemplo n.º 18
0
def test_shortest_path():
    """ Check that we can correctly implement shortest path routing """
    # Generate a topology:
    topo = complete_topology(5)

    # Generate a single traffic class:
    # TrafficClass (id, name, source node, destination node)
    tcs = [TrafficClass(0, u'classname', 0, 2)]
    # Generate all paths for this traffic class
    pptc = generate_paths_tc(topo, tcs, null_predicate, cutoff=100)
    # Application configuration
    appconfig = {
        'name': u'minLatencyApp',
        'constraints': [(Constraint.ROUTE_ALL, (pptc.tcs(), ), {})],
        'obj': (Objective.MIN_LATENCY, (), {}),
        'resource_cost': {}
    }

    # Create an application based on our config
    app = App(pptc, **appconfig)

    # Create and solve an optimization based on the app
    # No link capacities will just result in a single shortest path
    opt = from_app(topo, app, NetworkConfig(None))
    opt.solve()
    assert opt.is_solved()

    paths = opt.get_paths()
    for pi, p in enumerate(paths.paths(tcs[0])):
        if list(p.nodes()) == [0, 2]:
            assert p.flow_fraction() == 1
        else:
            assert p.flow_fraction() == 0

    # norm factor for latency is diameter * n^2
    norm = topo.diameter() * 25
    # the objective is 1-normalized latency, and latency is 1.
    # because 1 path with flow fraction of 1.
    solution = opt.get_solved_objective(app)[0]
    assert solution == 1 - 1 / norm or abs(solution - 1 - 1 / norm) <= EPSILON
    solution = opt.get_solved_objective()
    assert solution == 1 - 1 / norm or abs(solution - 1 - 1 / norm) <= EPSILON
Ejemplo n.º 19
0
def topo():
    return complete_topology(8)
Ejemplo n.º 20
0
def topo(request):
    n = request.param
    t = complete_topology(n)
    for l in t.links():
        t.set_resource(l, BANDWIDTH, n * (n - 1))
    return t
Ejemplo n.º 21
0
def topo(request):
    n = request.param
    t = complete_topology(n)
    for l in t.links():
        t.set_resource(l, BANDWIDTH, n * (n - 1))
    return t
Ejemplo n.º 22
0
def topo():
    return complete_topology(8)