stats: adding symlinks for nodes and interfaces in the stat segment
[vpp.git] / test / test_stats_client.py
index bdc9811..7e17e2a 100644 (file)
@@ -6,6 +6,8 @@ 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
@@ -20,6 +22,12 @@ 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(), {})
@@ -44,6 +52,94 @@ class StatsClientTestCase(VppTestCase):
                          "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():