
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# Distributed under the OpenFlow Software License (see LICENSE)
# Copyright (c) 2010 The Board of Trustees of The Leland Stanford Junior University
# Copyright (c) 2012, 2013 Big Switch Networks, Inc.
"""
Flow stats test cases

These tests check the behavior of the flow stats request.
"""

import logging
import random

from oftest import config
import oftest.base_tests as base_tests
import ofp
import oftest.packet as scapy

from oftest.testutils import *
from oftest.parse import parse_ipv6

class AllFlowStats(base_tests.SimpleDataPlane):
    """
    Retrieve all flows and verify the stats entries match the flow-mods sent
    """
    def runTest(self):
        port1, port2, port3 = openflow_ports(3)
        table_id = test_param_get("table", 0)
        delete_all_flows(self.controller)

        flow1 = ofp.message.flow_add(
                table_id=table_id,
                priority=0x11,
                idle_timeout=0x21,
                hard_timeout=0x31,
                flags=ofp.OFPFF_NO_PKT_COUNTS,
                cookie=1,
                match=ofp.match([
                    ofp.oxm.in_port(port1),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|1)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port1,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flow2 = ofp.message.flow_add(
                table_id=table_id,
                priority=0x12,
                idle_timeout=0x22,
                hard_timeout=0x32,
                flags=ofp.OFPFF_NO_BYT_COUNTS,
                cookie=2,
                match=ofp.match([
                    ofp.oxm.in_port(port2),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|2)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port2,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flow3 = ofp.message.flow_add(
                table_id=table_id,
                priority=0x13,
                idle_timeout=0x23,
                hard_timeout=0x33,
                flags=ofp.OFPFF_CHECK_OVERLAP,
                cookie=3,
                match=ofp.match([
                    ofp.oxm.in_port(port3),
                    ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|3)]),
                instructions=[
                    ofp.instruction.write_actions(
                        actions=[
                            ofp.action.output(
                                port=port3,
                                max_len=ofp.OFPCML_NO_BUFFER)])],
                buffer_id=ofp.OFP_NO_BUFFER)

        flows = [flow1, flow2, flow3]
        for flow in flows:
            logging.debug(flow.show())
            self.controller.message_send(flow)

        flows_by_cookie = { flow.cookie: flow for flow in flows }

        do_barrier(self.controller)

        logging.info("Sending flow stats request")
        stats = get_flow_stats(self, ofp.match())
        logging.info("Received %d flow stats entries", len(stats))

        seen_cookies = set()
        for entry in stats:
            logging.debug(entry.show())
            self.assertTrue(entry.cookie in flows_by_cookie, "Unexpected cookie")
            self.assertTrue(entry.cookie not in seen_cookies, "Duplicate cookie")
            flow = flows_by_cookie[entry.cookie]
            seen_cookies.add(entry.cookie)

            self.assertEqual(entry.table_id, flow.table_id)
            self.assertEqual(entry.priority, flow.priority)
            self.assertEqual(entry.idle_timeout, flow.idle_timeout)
            self.assertEqual(entry.hard_timeout, flow.hard_timeout)
            self.assertEqual(entry.flags, flow.flags)
            self.assertEqual(entry.cookie, flow.cookie)
            self.assertEqual(sorted(entry.match.oxm_list), sorted(flow.match.oxm_list))
            self.assertEqual(sorted(entry.instructions), sorted(flow.instructions))

        self.assertEqual(seen_cookies, set([1,2,3]))

class CookieFlowStats(base_tests.SimpleDataPlane):
    """
    Retrieve flows using various masks on the cookie
    """
    def runTest(self):
        delete_all_flows(self.controller)

        # Also used as masks
        cookies = [
            0x0000000000000000,
            0xDDDDDDDD00000000,
            0x00000000DDDDDDDD,
            0xDDDDDDDDDDDDDDDD,
            0xDDDD0000DDDD0000,
            0x0000DDDD0000DDDD,
            0xDD00DD00DD00DD00,
            0xD0D0D0D0D0D0D0D0,
            0xF000000000000000,
            0xFF00000000000000,
            0xFFF0000000000000,
            0xFFFF000000000000,
        ]

        for i in range(0, 10):
            cookies.append(random.getrandbits(64))

        # Generate the matching cookies for each combination of cookie and mask
        matches = {}
        for mask in cookies:
            for cookie in cookies:
                matching = []
                for cookie2 in cookies:
                    if cookie & mask == cookie2 & mask:
                        matching.append(cookie2)
                matches[(cookie, mask)] = sorted(matching)

        # Generate a flow for each cookie
        flows = {}
        table_id = test_param_get("table", 0)
        for idx, cookie in enumerate(cookies):
            flows[cookie] = ofp.message.flow_add(
                table_id=table_id,
                cookie=cookie,
                match=ofp.match([ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT|idx)]),
                buffer_id=ofp.OFP_NO_BUFFER)

        # Install flows
        for flow in flows.values():
            self.controller.message_send(flow)
        do_barrier(self.controller)

        # For each combination of cookie and match, verify the correct flows
        # are retrieved
        for (cookie, mask), expected_cookies in matches.iteritems():
            stats = get_flow_stats(self, ofp.match(), cookie=cookie, cookie_mask=mask)
            received_cookies = sorted([entry.cookie for entry in stats])
            logging.debug("expected 0x%016x/0x%016x: %s", cookie, mask,
                          ' '.join(["0x%016x" % x for x in expected_cookies]))
            logging.debug("received 0x%016x/0x%016x: %s", cookie, mask,
                          ' '.join(["0x%016x" % x for x in received_cookies]))
            self.assertEqual(expected_cookies, received_cookies)
