#!/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)
