tests: replace pycodestyle with black
[vpp.git] / test / test_stats_client.py
index 7d0c91f..7b62b29 100644 (file)
@@ -1,13 +1,16 @@
 #!/usr/bin/env python3
 
 import unittest
-import time
 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"""
 
@@ -19,11 +22,18 @@ class StatsClientTestCase(VppTestCase):
     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'),
-                         [0])
+        self.assertEqual(
+            self.statistics.get_counter("/err/ethernet-input/no error"), [0]
+        )
 
     def test_client_fd_leak(self):
         """Test file descriptor count - VPP-1486"""
@@ -33,35 +43,120 @@ class StatsClientTestCase(VppTestCase):
         initial_fds = p.num_fds()
 
         for _ in range(100):
-            stats = VPPStats(socketname=cls.stats_sock)
+            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))
+        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')
+            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')
+        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'))
+        print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     unittest.main(testRunner=VppTestRunner)