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
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
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
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
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
def composeview(): """ Create a new composed opimization, solve and return the :return: """ try: data = request.get_json() logger.debug(data) apps_json = data['apps'] # THIS IS PARSING TOPOLOGY INCORRECTLY # topology = Topology.from_json(data['topology']) topology = _topology print("Topology from POST Request") print(data['topology']) print("Parsed topology using json_graph.node_link_graph()") print(topology.to_json()) except KeyError: # todo: is this right exception? abort(400) # TODO: take predicate into account apps = [] for aj in apps_json: aj = AttrDict(aj) tcs = [] for tcj in aj.traffic_classes: tc = TrafficClass(tcj.tcid, u'tc', tcj.src, tcj.dst, numpy.array([tcj.vol_flows])) tcs.append(tc) pptc = assign_to_tc(tcs, _paths, aj.id) # pptc = generate_paths_tc(topology, tcs, _predicatedict[aj.predicate], 20, # float('inf'), name=aj.id) # objective if aj.objective.get('resource') is None: objective = (aj.objective.name) else: objective = (aj.objective.name, aj.objective.resource) logger.debug("Objective: " + str(objective)) for r in map(AttrDict, aj.resource_costs): logger.debug("Resource type: " + str(r.resource)) # [TODO: NEED TO UNDERSTAND THE DIFFERENCE BETWEEN THE MODES (NODES/MBOXES/LINKS)] # resource : (mode, cost_value, cost_function) resource_cost = { r.resource: (LINKS, r.cost, 0) for r in map(AttrDict, aj.resource_costs) } logger.debug("Printing Constraints: " + str(list(aj.constraints))) wrap_constraints = [] for con in list(aj.constraints): if con == u'route_all': wrap_constraints.append([Constraint.ROUTE_ALL, [], {}]) elif con == u'allocate_flow': do_nothing = 1 # do nothing here because allocate_flow is called when opt is initialized elif con == u'req_all_links': wrap_constraints.append([Constraint.REQ_ALL_LINKS, [], {}]) elif con == u'req_all_nodes': wrap_constraints.append([Constraint.REQ_ALL_NODES, [], {}]) elif con == u'req_some_links': wrap_constraints.append([Constraint.REQ_SOME_LINKS, [], {}]) elif con == u'req_some_nodes': wrap_constraints.append([Constraint.REQ_SOME_NODES, [], {}]) elif con == u'cap_links': wrap_constraints.append([Constraint.CAP_LINKS, [], {}]) elif con == u'cap_nodes': wrap_constraints.append([Constraint.CAP_NODES, [], {}]) elif con == u'fix_path': wrap_constraints.append([Constraint.FIX_PATHS, [], {}]) elif con == u'mindiff': wrap_constraints.append([Constraint.MINDIFF, [], {}]) elif con == u'node_budget': wrap_constraints.append([Constraint.NODE_BUDGET, [], {}]) else: logger.debug("Received Unknown Constraint for Map: " + str(con)) wrap_objectives = [] if objective[0] == u'minlinkload': wrap_objectives.append(Objective.MIN_LINK_LOAD) elif objective[0] == u'minnodeload': wrap_objectives.append(Objective.MIN_NODE_LOAD) elif objective[0] == u'minlatency': wrap_objectives.append(Objective.MIN_LATENCY) elif objective[0] == u'maxflow': wrap_objectives.append(Objective.MAX_FLOW) elif objective[0] == u'minenablednodes': wrap_objectives.append(Objective.MIN_ENABLED_NODES) else: logger.debug("Couldn't find Objective Name") obj_name = None wrap_objectives.append([objective[1]]) #*args wrap_objectives.append({}) #**kwargs apps.append( App(pptc, wrap_constraints, resource_cost, wrap_objectives, name=aj.id)) ncaps = NetworkCaps(topology) for r in resource_cost.keys(): ncaps.add_cap(r, None, 1) opt = compose_apps(apps, topology, NetworkConfig(networkcaps=ncaps), epoch_mode=EpochComposition.WORST, fairness=Fairness.WEIGHTED, weights=None) opt.solve() result = [] for app in apps: result_app = {"app": app.name, "tcs": []} result_pptc = opt.get_paths(0) it = (app.pptc).tcs() while True: try: tc = it.next() obj = {"tcid": tc.ID, "paths": []} for p in result_pptc.paths(tc): if p.flow_fraction() != 0: obj["paths"].append({ "nodes": p.nodes().tolist(), "fraction": p.flow_fraction() }) result_app["tcs"].append(obj) except StopIteration: break result.append(result_app) logger.debug(result) return jsonify(result)
def t3(): return TrafficClass(1, u'ssh', 2, 1)
def t2(): return TrafficClass(2, u'web', 1, 2)
def t(): return TrafficClass(1, u'web', 1, 2)