Esempio n. 1
0
def test_record_removal():
    """
    Test the recording of an idle-timeout flow removal message
    sent by a switch into the flow_rems database collection

    Synthesise flow removal messages to test with.
    """
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    logger.debug("msg_tx=%s", msg_tx)

    #*** Call our method that we're testing with the synthesised flow rems:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Check that messages recorded correctly in database collection:
    db_data_tx = {'ip_A': '10.1.0.1', 'tp_B': 80}
    result = flow.flow_rems.find(db_data_tx).sort('$natural', -1).limit(1)
    result_tx = list(result)[0]
    logger.debug("result=%s", result_tx)
    assert result_tx['table_id'] == 1
    assert result_tx['ip_B'] == '10.1.0.2'
    assert result_tx['tp_A'] == 43297
    assert result_tx['packet_count'] == 10
    assert result_tx['flow_hash'] == nethash.hash_flow(('10.1.0.1',
                                                     '10.1.0.2', 43297, 80, 6))
    assert result_tx['cookie'] == 23
    assert result_tx['direction'] == 'forward'

    #*** Return leg of flow:
    db_data_tx = {'ip_B': '10.1.0.1', 'tp_A': 80}
    result = flow.flow_rems.find(db_data_tx).sort('$natural', -1).limit(1)
    result_tx = list(result)[0]
    logger.debug("result=%s", result_tx)
    assert result_tx['table_id'] == 1
    assert result_tx['ip_A'] == '10.1.0.2'
    assert result_tx['tp_B'] == 43297
    assert result_tx['packet_count'] == 9
    assert result_tx['flow_hash'] == nethash.hash_flow(('10.1.0.2',
                                                     '10.1.0.1', 80, 43297, 6))
    assert result_tx['cookie'] == 1000000023
    assert result_tx['direction'] == 'reverse'
Esempio n. 2
0
def test_record_removal():
    """
    Test the recording of an idle-timeout flow removal message
    sent by a switch into the flow_rems database collection

    Synthesise flow removal messages to test with.
    """
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    logger.debug("msg_tx=%s", msg_tx)

    #*** Call our method that we're testing with the synthesised flow rems:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Check that messages recorded correctly in database collection:
    db_data_tx = {'ip_A': '10.1.0.1', 'tp_B': 80}
    result = flow.flow_rems.find(db_data_tx).sort('$natural', -1).limit(1)
    result_tx = list(result)[0]
    logger.debug("result=%s", result_tx)
    assert result_tx['table_id'] == 1
    assert result_tx['ip_B'] == '10.1.0.2'
    assert result_tx['tp_A'] == 43297
    assert result_tx['packet_count'] == 10
    assert result_tx['flow_hash'] == nethash.hash_flow(
        ('10.1.0.1', '10.1.0.2', 43297, 80, 6))
    assert result_tx['cookie'] == 23
    assert result_tx['direction'] == 'forward'

    #*** Return leg of flow:
    db_data_tx = {'ip_B': '10.1.0.1', 'tp_A': 80}
    result = flow.flow_rems.find(db_data_tx).sort('$natural', -1).limit(1)
    result_tx = list(result)[0]
    logger.debug("result=%s", result_tx)
    assert result_tx['table_id'] == 1
    assert result_tx['ip_A'] == '10.1.0.2'
    assert result_tx['tp_B'] == 43297
    assert result_tx['packet_count'] == 9
    assert result_tx['flow_hash'] == nethash.hash_flow(
        ('10.1.0.2', '10.1.0.1', 80, 43297, 6))
    assert result_tx['cookie'] == 1000000023
    assert result_tx['direction'] == 'reverse'
Esempio n. 3
0
def test_flows_removed_stats_count():
    """
    Test the flows_removed API stats count by ingesting flow removal messages
    then checking that the API response correctly specifies message count
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(target=api.run, args=())
    api_ps.start()

    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 0

    #*** Record flow removal to flow_rems database collection:
    flow.record_removal(msg_tx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 1

    #*** Record flow removal to flow_rems database collection:
    flow.record_removal(msg_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 2

    #*** Stop api_external sub-process:
    api_ps.terminate()
Esempio n. 4
0
def test_get_flow_data_xfer():
    """
    Test the get_flow_data_xfer method.

    Synthesise flow removal messages to test with.
    """
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)
    flow.ingest_packet(DPID1, INPORT1, pkts.RAW[0], datetime.datetime.now())
    flow.ingest_packet(DPID1, INPORT2, pkts.RAW[1], datetime.datetime.now())

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    logger.debug("msg_tx=%s", msg_tx)

    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Now, test the get_flow_data_xfer method:

    record = {
        'ip_src': '10.1.0.1',
        'ip_dst': '10.1.0.2',
        'tp_src': 43297,
        'tp_dst': 80,
        'proto': 6,
        'flow_hash': '9822b2867652ee0957892482b9f004c3'
    }
    xfer = api.get_flow_data_xfer(record)
    logger.debug("xfer=%s", xfer)

    assert xfer['tx_found'] == 1
    assert xfer['tx_bytes'] == 744
    assert xfer['tx_pkts'] == 10
    assert xfer['rx_found'] == 1
    assert xfer['rx_bytes'] == 6644
    assert xfer['rx_pkts'] == 9
Esempio n. 5
0
def test_get_flow_data_xfer():
    """
    Test the get_flow_data_xfer method.

    Synthesise flow removal messages to test with.
    """
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)
    flow.ingest_packet(DPID1, INPORT1, pkts.RAW[0], datetime.datetime.now())
    flow.ingest_packet(DPID1, INPORT2, pkts.RAW[1], datetime.datetime.now())

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    logger.debug("msg_tx=%s", msg_tx)

    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Now, test the get_flow_data_xfer method:

    record = {'ip_src': '10.1.0.1',
              'ip_dst': '10.1.0.2',
              'tp_src': 43297,
              'tp_dst': 80,
              'proto': 6,
              'flow_hash': '9822b2867652ee0957892482b9f004c3'}
    xfer = api.get_flow_data_xfer(record)
    logger.debug("xfer=%s", xfer)

    assert xfer['tx_found'] == 1
    assert xfer['tx_bytes'] == 744
    assert xfer['tx_pkts'] == 10
    assert xfer['rx_found'] == 1
    assert xfer['rx_bytes'] == 6644
    assert xfer['rx_pkts'] == 9
Esempio n. 6
0
def _print(filename):
    """Prints the JSON flow table from a file in a human readable format"""
    with open(filename, 'r') as f:
        msg = json.load(f)
    dp = FakeRyuDp()
    ofmsg = ofp_parser.ofp_msg_from_jsondict(dp, msg)
    table = FakeOFTable(1)
    table.apply_ofmsgs([ofmsg])
    print(table)
Esempio n. 7
0
def _print(filename, **_kwargs):
    """Prints the JSON flow table from a file in a human readable format"""
    with open(filename, 'r') as file_handle:
        msg = json.load(file_handle)
    datapath = FakeRyuDp()
    ofmsg = ofp_parser.ofp_msg_from_jsondict(datapath, msg)
    table = FakeOFTable(1)
    table.apply_ofmsgs([ofmsg])
    print(table)
Esempio n. 8
0
def probe(filename, packet):
    """Prints the actions applied to packet by the table from the file"""
    with open(filename, 'r') as f:
        msg = json.load(f)
    dp = FakeRyuDp()
    ofmsg = ofp_parser.ofp_msg_from_jsondict(dp, msg)
    table = FakeOFTable(1)
    table.apply_ofmsgs([ofmsg])
    instructions, out_packet = table.lookup(packet)
    print(packet)
    for instruction in instructions:
        print(instruction)
    print(out_packet)
Esempio n. 9
0
def ruleset_from_ryu_json(f_handle):
    """ Loads a ryu ruleset from json

        The ruleset can be compressed, either .gz or .bz2 and are
        decompressed based on their extension.

        The ryu ruleset can be a dump of flow stats, or flow mods.

        f_handle: An open file handle, or path
        return: A list of Rules
    """
    stats = json.load(f_handle)

    # Find something that looks about right
    while isinstance(stats, dict):
        first = next(iter(stats))
        if len(stats) != 1:
            print(
                "ruleset_from_ryu_json: Warning found multiple values in a dict, using the first",
                file=sys.stderr)
            print(next(iter(stats)), file=sys.stdout)
        if isinstance(first, six.string_types) and first.startswith("OFP"):
            break  # This should work and return a ruleset
        print("ruleset_from_ryu_json: Unknown value in json",
              first,
              ". Skipping into contents.",
              file=sys.stderr)
        stats = stats[first]

    if isinstance(stats, dict):
        # Could be a OFPFlowStatsReply message, untested code path
        msg = ofp_msg_from_jsondict(DP, stats)
        stats = msg.body
    else:
        assert isinstance(stats, list)
        stats = [ryu_from_jsondict(r) for r in stats]

    ruleset = [rule_from_ryu(r) for r in stats]
    return ruleset
Esempio n. 10
0
 def _jsondict_to_msg(dp, jsondict):
     return ofproto_parser.ofp_msg_from_jsondict(dp, jsondict)
Esempio n. 11
0
def test_flows_removed():
    """
    Test the flows_removed API by ingesting flow removal messages
    then checking that the API response correctly lists them
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(target=api.run, args=())
    api_ps.start()

    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['dpid'] == 1
    #*** Note: can't easily test 'removal_time' as is dynamic, so skipping...
    assert api_result['_items'][0]['cookie'] == 23
    assert api_result['_items'][0]['priority'] == 1
    assert api_result['_items'][0]['reason'] == 0
    assert api_result['_items'][0]['table_id'] == 1
    assert api_result['_items'][0]['duration_sec'] == 5
    assert api_result['_items'][0]['idle_timeout'] == 5
    assert api_result['_items'][0]['hard_timeout'] == 0
    assert api_result['_items'][0]['packet_count'] == 10
    assert api_result['_items'][0]['byte_count'] == 744
    assert api_result['_items'][0]['eth_A'] == ''
    assert api_result['_items'][0]['eth_B'] == ''
    assert api_result['_items'][0]['eth_type'] == 2048
    assert api_result['_items'][0]['ip_A'] == '10.1.0.1'
    assert api_result['_items'][0]['ip_B'] == '10.1.0.2'
    assert api_result['_items'][0]['ip_proto'] == 6
    assert api_result['_items'][0]['tp_A'] == 43297
    assert api_result['_items'][0]['tp_B'] == 80
    assert api_result['_items'][0][
        'flow_hash'] == '9822b2867652ee0957892482b9f004c3'
    assert api_result['_items'][0]['direction'] == 'forward'

    #*** Validate API Response parameters for second flow removal:
    assert api_result['_items'][1]['dpid'] == 1
    #*** Note: can't easily test 'removal_time' as is dynamic, so skipping...
    assert api_result['_items'][1]['cookie'] == 1000000023
    assert api_result['_items'][1]['priority'] == 1
    assert api_result['_items'][1]['reason'] == 0
    assert api_result['_items'][1]['table_id'] == 1
    assert api_result['_items'][1]['duration_sec'] == 5
    assert api_result['_items'][1]['idle_timeout'] == 5
    assert api_result['_items'][1]['hard_timeout'] == 0
    assert api_result['_items'][1]['packet_count'] == 9
    assert api_result['_items'][1]['byte_count'] == 6644
    assert api_result['_items'][1]['eth_A'] == ''
    assert api_result['_items'][1]['eth_B'] == ''
    assert api_result['_items'][1]['eth_type'] == 2048
    assert api_result['_items'][1]['ip_A'] == '10.1.0.2'
    assert api_result['_items'][1]['ip_B'] == '10.1.0.1'
    assert api_result['_items'][1]['ip_proto'] == 6
    assert api_result['_items'][1]['tp_A'] == 80
    assert api_result['_items'][1]['tp_B'] == 43297
    assert api_result['_items'][1][
        'flow_hash'] == '9822b2867652ee0957892482b9f004c3'
    assert api_result['_items'][1]['direction'] == 'reverse'

    #*** Stop api_external sub-process:
    api_ps.terminate()
Esempio n. 12
0
def test_response_flows_removed_FLOWDIR_bytes_TXRX():
    """
    Test the flows_removed API various flavours of src/dst bytes
    sent/received by ingesting flow removal messages then checking
    that the API response correctly specifies appropriate
    stats for bytes sent, including identity enrichment
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(target=api.run, args=())
    api_ps.start()

    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate supporting classes:
    flow = flows_module.Flow(config)
    policy = policy_module.Policy(config)
    identities = identities_module.Identities(config, policy)

    #*** Client to Server DHCP Request:
    flow.ingest_packet(DPID1, INPORT1, pkts_dhcp.RAW[2],
                       datetime.datetime.now())
    identities.harvest(pkts_dhcp.RAW[2], flow.packet)

    #*** Server to Client DHCP ACK:
    flow.ingest_packet(DPID1, INPORT2, pkts_dhcp.RAW[3],
                       datetime.datetime.now())
    identities.harvest(pkts_dhcp.RAW[3], flow.packet)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx_1 = json_file.read()
        json_dict_tx_1 = json.loads(json_str_tx_1)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx_1 = json_file.read()
        json_dict_rx_1 = json.loads(json_str_rx_1)
    with open('OFPMsgs/OFPFlowRemoved_3.json', 'r') as json_file:
        json_str_tx_2 = json_file.read()
        json_dict_tx_2 = json.loads(json_str_tx_2)
    with open('OFPMsgs/OFPFlowRemoved_4.json', 'r') as json_file:
        json_str_rx_2 = json_file.read()
        json_dict_rx_2 = json.loads(json_str_rx_2)
    with open('OFPMsgs/OFPFlowRemoved_5.json', 'r') as json_file:
        json_str_tx_3 = json_file.read()
        json_dict_tx_3 = json.loads(json_str_tx_3)
    with open('OFPMsgs/OFPFlowRemoved_6.json', 'r') as json_file:
        json_str_rx_3 = json_file.read()
        json_dict_rx_3 = json.loads(json_str_rx_3)

    #*** Switch 1:
    #*** Set up fake datapaths and synthesise messages:
    datapath1 = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath1.id = 1
    msg_tx_1_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_tx_1)
    msg_rx_1_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_rx_1)
    msg_tx_2_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_tx_2)
    msg_rx_2_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_rx_2)
    msg_tx_3_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_tx_3)
    msg_rx_3_sw1 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_rx_3)
    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx_1_sw1)
    flow.record_removal(msg_rx_1_sw1)
    flow.record_removal(msg_tx_2_sw1)
    flow.record_removal(msg_rx_2_sw1)
    flow.record_removal(msg_tx_3_sw1)
    flow.record_removal(msg_rx_3_sw1)

    #*** Switch 2 (same flows to check dedup for multiple switches works):
    #*** Set up fake datapaths and synthesise messages:
    datapath2 = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath2.id = 2
    msg_tx_1_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath2, json_dict_tx_1)
    msg_rx_1_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath2, json_dict_rx_1)
    msg_tx_2_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath2, json_dict_tx_2)
    msg_rx_2_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath2, json_dict_rx_2)
    msg_tx_3_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_tx_3)
    msg_rx_3_sw2 = ofproto_parser.ofp_msg_from_jsondict(
        datapath1, json_dict_rx_3)
    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx_1_sw2)
    flow.record_removal(msg_rx_1_sw2)
    flow.record_removal(msg_tx_2_sw2)
    flow.record_removal(msg_rx_2_sw2)
    flow.record_removal(msg_tx_3_sw2)
    flow.record_removal(msg_rx_3_sw2)

    #*** Test flows_removed_src_bytes_sent API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_SRC_BYTES_SENT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.2'
    assert api_result['_items'][0]['total_bytes_sent'] == 12345
    assert api_result['_items'][0]['identity'] == '10.1.0.2'
    assert api_result['_items'][1]['_id'] == '10.1.0.1'
    assert api_result['_items'][1]['total_bytes_sent'] == 5533
    assert api_result['_items'][1]['identity'] == 'pc1'

    #*** Test flows_removed_src_bytes_received API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_SRC_BYTES_RECEIVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.1'
    assert api_result['_items'][0]['total_bytes_received'] == 8628
    assert api_result['_items'][0]['identity'] == 'pc1'
    assert api_result['_items'][1]['_id'] == '10.1.0.2'
    assert api_result['_items'][1]['total_bytes_received'] == 543
    assert api_result['_items'][1]['identity'] == '10.1.0.2'

    #*** Test flows_removed_dst_bytes_sent API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_DST_BYTES_SENT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.2'
    assert api_result['_items'][0]['total_bytes_sent'] == 8628
    assert api_result['_items'][0]['identity'] == '10.1.0.2'
    assert api_result['_items'][1]['_id'] == '10.1.0.1'
    assert api_result['_items'][1]['total_bytes_sent'] == 543
    assert api_result['_items'][1]['identity'] == 'pc1'

    #*** Test flows_removed_src_bytes_received API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_DST_BYTES_RECEIVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.1'
    assert api_result['_items'][0]['total_bytes_received'] == 12345
    assert api_result['_items'][0]['identity'] == 'pc1'
    assert api_result['_items'][1]['_id'] == '10.1.0.2'
    assert api_result['_items'][1]['total_bytes_received'] == 5533
    assert api_result['_items'][1]['identity'] == '10.1.0.2'

    #*** Stop api_external sub-process:
    api_ps.terminate()
Esempio n. 13
0
def test_response_flows_removed_FLOWDIR_bytes_TXRX():
    """
    Test the flows_removed API various flavours of src/dst bytes
    sent/received by ingesting flow removal messages then checking
    that the API response correctly specifies appropriate
    stats for bytes sent, including identity enrichment
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(
                        target=api.run,
                        args=())
    api_ps.start()
    
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate supporting classes:
    flow = flows_module.Flow(config)
    policy = policy_module.Policy(config)
    identities = identities_module.Identities(config, policy)

    #*** Client to Server DHCP Request:
    flow.ingest_packet(DPID1, INPORT1, pkts_dhcp.RAW[2], datetime.datetime.now())
    identities.harvest(pkts_dhcp.RAW[2], flow.packet)

    #*** Server to Client DHCP ACK:
    flow.ingest_packet(DPID1, INPORT2, pkts_dhcp.RAW[3], datetime.datetime.now())
    identities.harvest(pkts_dhcp.RAW[3], flow.packet)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx_1 = json_file.read()
        json_dict_tx_1 = json.loads(json_str_tx_1)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx_1 = json_file.read()
        json_dict_rx_1 = json.loads(json_str_rx_1)
    with open('OFPMsgs/OFPFlowRemoved_3.json', 'r') as json_file:
        json_str_tx_2 = json_file.read()
        json_dict_tx_2 = json.loads(json_str_tx_2)
    with open('OFPMsgs/OFPFlowRemoved_4.json', 'r') as json_file:
        json_str_rx_2 = json_file.read()
        json_dict_rx_2 = json.loads(json_str_rx_2)
    with open('OFPMsgs/OFPFlowRemoved_5.json', 'r') as json_file:
        json_str_tx_3 = json_file.read()
        json_dict_tx_3 = json.loads(json_str_tx_3)
    with open('OFPMsgs/OFPFlowRemoved_6.json', 'r') as json_file:
        json_str_rx_3 = json_file.read()
        json_dict_rx_3 = json.loads(json_str_rx_3)

    #*** Switch 1:
    #*** Set up fake datapaths and synthesise messages:
    datapath1 = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath1.id = 1
    msg_tx_1_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_tx_1)
    msg_rx_1_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_rx_1)
    msg_tx_2_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_tx_2)
    msg_rx_2_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_rx_2)
    msg_tx_3_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_tx_3)
    msg_rx_3_sw1 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_rx_3)
    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx_1_sw1)
    flow.record_removal(msg_rx_1_sw1)
    flow.record_removal(msg_tx_2_sw1)
    flow.record_removal(msg_rx_2_sw1)
    flow.record_removal(msg_tx_3_sw1)
    flow.record_removal(msg_rx_3_sw1)

    #*** Switch 2 (same flows to check dedup for multiple switches works):
    #*** Set up fake datapaths and synthesise messages:
    datapath2 = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath2.id = 2
    msg_tx_1_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath2, json_dict_tx_1)
    msg_rx_1_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath2, json_dict_rx_1)
    msg_tx_2_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath2, json_dict_tx_2)
    msg_rx_2_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath2, json_dict_rx_2)
    msg_tx_3_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_tx_3)
    msg_rx_3_sw2 = ofproto_parser.ofp_msg_from_jsondict(datapath1, json_dict_rx_3)
    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx_1_sw2)
    flow.record_removal(msg_rx_1_sw2)
    flow.record_removal(msg_tx_2_sw2)
    flow.record_removal(msg_rx_2_sw2)
    flow.record_removal(msg_tx_3_sw2)
    flow.record_removal(msg_rx_3_sw2)

    #*** Test flows_removed_src_bytes_sent API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_SRC_BYTES_SENT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.2'
    assert api_result['_items'][0]['total_bytes_sent'] == 12345
    assert api_result['_items'][0]['identity'] == '10.1.0.2'
    assert api_result['_items'][1]['_id'] == '10.1.0.1'
    assert api_result['_items'][1]['total_bytes_sent'] == 5533
    assert api_result['_items'][1]['identity'] == 'pc1'

    #*** Test flows_removed_src_bytes_received API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_SRC_BYTES_RECEIVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.1'
    assert api_result['_items'][0]['total_bytes_received'] == 8628
    assert api_result['_items'][0]['identity'] == 'pc1'
    assert api_result['_items'][1]['_id'] == '10.1.0.2'
    assert api_result['_items'][1]['total_bytes_received'] == 543
    assert api_result['_items'][1]['identity'] == '10.1.0.2'

    #*** Test flows_removed_dst_bytes_sent API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_DST_BYTES_SENT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.2'
    assert api_result['_items'][0]['total_bytes_sent'] == 8628
    assert api_result['_items'][0]['identity'] == '10.1.0.2'
    assert api_result['_items'][1]['_id'] == '10.1.0.1'
    assert api_result['_items'][1]['total_bytes_sent'] == 543
    assert api_result['_items'][1]['identity'] == 'pc1'

    #*** Test flows_removed_src_bytes_received API:
    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_DST_BYTES_RECEIVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['_id'] == '10.1.0.1'
    assert api_result['_items'][0]['total_bytes_received'] == 12345
    assert api_result['_items'][0]['identity'] == 'pc1'
    assert api_result['_items'][1]['_id'] == '10.1.0.2'
    assert api_result['_items'][1]['total_bytes_received'] == 5533
    assert api_result['_items'][1]['identity'] == '10.1.0.2'

    #*** Stop api_external sub-process:
    api_ps.terminate()
Esempio n. 14
0
 def _jsonfile_to_msg(datapath, jsonfile):
     return ofproto_parser.ofp_msg_from_jsondict(
         datapath, json.load(open(jsonfile)))
Esempio n. 15
0
def test_flows_removed():
    """
    Test the flows_removed API by ingesting flow removal messages
    then checking that the API response correctly lists them
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(
                        target=api.run,
                        args=())
    api_ps.start()
    
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    #*** Record flow removals to flow_rems database collection:
    flow.record_removal(msg_tx)
    flow.record_removal(msg_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['_items'][0]['dpid'] == 1
    #*** Note: can't easily test 'removal_time' as is dynamic, so skipping...
    assert api_result['_items'][0]['cookie'] == 23
    assert api_result['_items'][0]['priority'] == 1
    assert api_result['_items'][0]['reason'] == 0
    assert api_result['_items'][0]['table_id'] == 1
    assert api_result['_items'][0]['duration_sec'] == 5
    assert api_result['_items'][0]['idle_timeout'] == 5
    assert api_result['_items'][0]['hard_timeout'] == 0
    assert api_result['_items'][0]['packet_count'] == 10
    assert api_result['_items'][0]['byte_count'] == 744
    assert api_result['_items'][0]['eth_A'] == ''
    assert api_result['_items'][0]['eth_B'] == ''
    assert api_result['_items'][0]['eth_type'] == 2048
    assert api_result['_items'][0]['ip_A'] == '10.1.0.1'
    assert api_result['_items'][0]['ip_B'] == '10.1.0.2'
    assert api_result['_items'][0]['ip_proto'] == 6
    assert api_result['_items'][0]['tp_A'] == 43297
    assert api_result['_items'][0]['tp_B'] == 80
    assert api_result['_items'][0]['flow_hash'] == '9822b2867652ee0957892482b9f004c3'
    assert api_result['_items'][0]['direction'] == 'forward'

    #*** Validate API Response parameters for second flow removal:
    assert api_result['_items'][1]['dpid'] == 1
    #*** Note: can't easily test 'removal_time' as is dynamic, so skipping...
    assert api_result['_items'][1]['cookie'] == 1000000023
    assert api_result['_items'][1]['priority'] == 1
    assert api_result['_items'][1]['reason'] == 0
    assert api_result['_items'][1]['table_id'] == 1
    assert api_result['_items'][1]['duration_sec'] == 5
    assert api_result['_items'][1]['idle_timeout'] == 5
    assert api_result['_items'][1]['hard_timeout'] == 0
    assert api_result['_items'][1]['packet_count'] == 9
    assert api_result['_items'][1]['byte_count'] == 6644
    assert api_result['_items'][1]['eth_A'] == ''
    assert api_result['_items'][1]['eth_B'] == ''
    assert api_result['_items'][1]['eth_type'] == 2048
    assert api_result['_items'][1]['ip_A'] == '10.1.0.2'
    assert api_result['_items'][1]['ip_B'] == '10.1.0.1'
    assert api_result['_items'][1]['ip_proto'] == 6
    assert api_result['_items'][1]['tp_A'] == 80
    assert api_result['_items'][1]['tp_B'] == 43297
    assert api_result['_items'][1]['flow_hash'] == '9822b2867652ee0957892482b9f004c3'
    assert api_result['_items'][1]['direction'] == 'reverse'

    #*** Stop api_external sub-process:
    api_ps.terminate()
Esempio n. 16
0
 def _jsonfile_to_msg(datapath, jsonfile):
     return ofproto_parser.ofp_msg_from_jsondict(
         datapath, json.load(open(jsonfile)))
Esempio n. 17
0
 def _jsondict_to_msg(dp, jsondict):
     return ofproto_parser.ofp_msg_from_jsondict(dp, jsondict)
Esempio n. 18
0
def test_flows_removed_stats_count():
    """
    Test the flows_removed API stats count by ingesting flow removal messages
    then checking that the API response correctly specifies message count
    """
    #*** Start api_external as separate process:
    logger.info("Starting api_external")
    api_ps = multiprocessing.Process(
                        target=api.run,
                        args=())
    api_ps.start()
    
    #*** Supports OpenFlow version 1.3:
    OFP_VERSION = ofproto_v1_3.OFP_VERSION

    #*** Instantiate Flow class:
    flow = flows_module.Flow(config)

    #*** Load JSON representations of flow removed messages:
    with open('OFPMsgs/OFPFlowRemoved_1.json', 'r') as json_file:
        json_str_tx = json_file.read()
        json_dict_tx = json.loads(json_str_tx)
    with open('OFPMsgs/OFPFlowRemoved_2.json', 'r') as json_file:
        json_str_rx = json_file.read()
        json_dict_rx = json.loads(json_str_rx)

    #*** Set up fake datapath and synthesise messages:
    datapath = ofproto_protocol.ProtocolDesc(version=OFP_VERSION)
    datapath.id = 1
    msg_tx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_tx)
    msg_rx = ofproto_parser.ofp_msg_from_jsondict(datapath, json_dict_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 0

    #*** Record flow removal to flow_rems database collection:
    flow.record_removal(msg_tx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 1

    #*** Record flow removal to flow_rems database collection:
    flow.record_removal(msg_rx)

    #*** Call the external API:
    api_result = get_api_result(URL_TEST_FLOWS_REMOVED_STATS_COUNT)
    logger.debug("api_result=%s", api_result)

    #*** Validate API Response parameters:
    assert api_result['flows_removed'] == 2

    #*** Stop api_external sub-process:
    api_ps.terminate()