#!/usr/bin/env python3

import unittest
import psutil
from vpp_papi.vpp_stats import VPPStats

from framework import tag_fixme_vpp_workers
from framework import VppTestCase, VppTestRunner
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP


@tag_fixme_vpp_workers
class StatsClientTestCase(VppTestCase):
    """Test Stats Client"""

    @classmethod
    def setUpClass(cls):
        super(StatsClientTestCase, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(StatsClientTestCase, cls).tearDownClass()

    @classmethod
    def setUpConstants(cls):
        cls.extra_vpp_statseg_config = "per-node-counters on"
        cls.extra_vpp_statseg_config += "update-interval 0.05"
        super(StatsClientTestCase, cls).setUpConstants()

    def test_set_errors(self):
        """Test set errors"""
        self.assertEqual(self.statistics.set_errors(), {})
        self.assertEqual(
            self.statistics.get_counter("/err/ethernet-input/no error"), [0]
        )

    def test_client_fd_leak(self):
        """Test file descriptor count - VPP-1486"""

        cls = self.__class__
        p = psutil.Process()
        initial_fds = p.num_fds()

        for _ in range(100):
            stats = VPPStats(socketname=cls.get_stats_sock_path())
            stats.disconnect()

        ending_fds = p.num_fds()
        self.assertEqual(
            initial_fds,
            ending_fds,
            "initial client side file descriptor count: %s "
            "is not equal to "
            "ending client side file descriptor count: %s" % (initial_fds, ending_fds),
        )

    def test_symlink_values(self):
        """Test symlinks reported values"""
        self.create_pg_interfaces(range(2))

        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()

        p = list()
        for i in range(5):
            packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
                src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
            )
            p.append(packet)

        self.send_and_expect(self.pg0, p, self.pg1)
        pg1_tx = self.statistics.get_counter("/interfaces/pg1/tx")
        if_tx = self.statistics.get_counter("/if/tx")

        self.assertEqual(pg1_tx[0]["bytes"], if_tx[0][self.pg1.sw_if_index]["bytes"])
        for i in self.pg_interfaces:
            i.unconfig()
            i.admin_down()

    def test_symlink_add_del_interfaces(self):
        """Test symlinks when adding and deleting interfaces"""
        # We first create and delete interfaces
        self.create_loopback_interfaces(1)
        self.create_pg_interfaces(range(1))
        self.loop0.remove_vpp_config()
        self.create_pg_interfaces(range(2))

        for i in self.pg_interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()

        p = list()
        bytes_to_send = 0
        for i in range(5):
            packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
                src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
            )
            bytes_to_send += len(packet)
            p.append(packet)

        tx_before_sending = self.statistics.get_counter("/interfaces/pg1/tx")
        rx_before_sending = self.statistics.get_counter("/interfaces/pg0/rx")
        self.send_and_expect(self.pg0, p, self.pg1)
        tx = self.statistics.get_counter("/interfaces/pg1/tx")
        rx = self.statistics.get_counter("/interfaces/pg0/rx")

        # We wait for nodes symlinks to update (interfaces created/deleted).
        # ... and packets to be sent
        self.sleep(0.1)
        vectors = self.statistics.get_counter("/nodes/pg1-tx/vectors")

        self.assertEqual(tx[0]["bytes"] - tx_before_sending[0]["bytes"], bytes_to_send)
        self.assertEqual(tx[0]["packets"] - tx_before_sending[0]["packets"], 5)
        self.assertEqual(rx[0]["bytes"] - rx_before_sending[0]["bytes"], bytes_to_send)
        self.assertEqual(rx[0]["packets"] - rx_before_sending[0]["packets"], 5)
        self.assertEqual(vectors[0], rx[0]["packets"])

        for i in self.pg_interfaces:
            i.unconfig()
            i.admin_down()

    def test_index_consistency(self):
        """Test index consistency despite changes in the stats"""
        d = self.statistics.ls(["/if/names"])
        self.create_loopback_interfaces(10)
        for i in range(10):
            try:
                s = self.statistics.dump(d)
                break
            except:
                pass
        k, v = s.popitem()
        self.assertEqual(len(v), 11)

        for i in self.lo_interfaces:
            i.remove_vpp_config()

    @unittest.skip("Manual only")
    def test_mem_leak(self):
        def loop():
            print("Running loop")
            for i in range(50):
                rv = self.vapi.papi.tap_create_v2(id=i, use_random_mac=1)
                self.assertEqual(rv.retval, 0)
                rv = self.vapi.papi.tap_delete_v2(sw_if_index=rv.sw_if_index)
                self.assertEqual(rv.retval, 0)

        before = self.statistics.get_counter("/mem/statseg/used")
        loop()
        self.vapi.cli("memory-trace on stats-segment")
        for j in range(100):
            loop()
        print(self.vapi.cli("show memory stats-segment verbose"))
        print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))


if __name__ == "__main__":
    unittest.main(testRunner=VppTestRunner)
