Soft Patch Panel
 help / color / Atom feed
* [spp] [PATCH 0/3] Introduce unit test for SPP processes
@ 2019-12-17  2:37 yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 1/3] test: add test for spp_nfv yasufum.o
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: yasufum.o @ 2019-12-17  2:37 UTC (permalink / raw)
  To: spp, ferruh.yigit, yasufum.o

From: Yasufumi Ogawa <yasufum.o@gmail.com>

This series of patches is to add unit tests for spp_nfv and spp_primary.
This feature is just an experimental and still fail to pass some tests
actually because some of PMDs, such as vhost, do not work for some
cases. Hoewver, the tests are expected to be passed wihtout errors after
the problems are fixed.

Yasufumi Ogawa (3):
  test: add test for spp_nfv
  test: add spp_nfv test for forwarding
  test: add test for spp_primary

 test/config.ini          |  12 +++
 test/test_spp_nfv.py     | 226 +++++++++++++++++++++++++++++++++++++++
 test/test_spp_primary.py | 177 ++++++++++++++++++++++++++++++
 3 files changed, 415 insertions(+)
 create mode 100644 test/config.ini
 create mode 100644 test/test_spp_nfv.py
 create mode 100644 test/test_spp_primary.py

-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [spp] [PATCH 1/3] test: add test for spp_nfv
  2019-12-17  2:37 [spp] [PATCH 0/3] Introduce unit test for SPP processes yasufum.o
@ 2019-12-17  2:37 ` yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 2/3] test: add spp_nfv test for forwarding yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 3/3] test: add test for spp_primary yasufum.o
  2 siblings, 0 replies; 4+ messages in thread
From: yasufum.o @ 2019-12-17  2:37 UTC (permalink / raw)
  To: spp, ferruh.yigit, yasufum.o

From: Yasufumi Ogawa <yasufum.o@gmail.com>

This patch is to add a unit test code for spp_nfv. Test cases are
defined by following SPP REST API, such as checking status, adding port
or so.

Configurations for the tests are defined as `test/config.ini`. Host IP
or assignment of resouces can be changed in the config.

Unit tests are expected to be run in the `test` dir.

  $ cd /path/to/spp/test
  $ python3 -m unittest  # or add `-v` for showing details

Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
---
 test/config.ini      |  12 +++
 test/test_spp_nfv.py | 179 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 191 insertions(+)
 create mode 100644 test/config.ini
 create mode 100644 test/test_spp_nfv.py

diff --git a/test/config.ini b/test/config.ini
new file mode 100644
index 0000000..8890413
--- /dev/null
+++ b/test/config.ini
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Nippon Telegraph and Telephone Corporation
+
+[spp-ctl]
+host = 127.0.0.1
+ctl_api_port = 7777
+api_version = v1
+
+# spp_nfv mainly tested
+[spp_nfv]
+lcores = 1,2
+mem = 512
diff --git a/test/test_spp_nfv.py b/test/test_spp_nfv.py
new file mode 100644
index 0000000..1ebb3d3
--- /dev/null
+++ b/test/test_spp_nfv.py
@@ -0,0 +1,179 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Nippon Telegraph and Telephone Corporation
+
+import configparser
+import json
+import requests
+import time
+import unittest
+
+
+class TestSppNfv(unittest.TestCase):
+    """Test spp_nfv.
+
+    Test as following the REST API reference. It does not include terminating
+    spp_nfv process because it is done as tearDown() task.
+    """
+
+    def setUp(self):
+        """Launch default spp_nfv used for the tests."""
+
+        self.sec_type = 'nfvs'
+        self.default_sec_id = 1
+
+        self.config = configparser.ConfigParser()
+        self.config.read('config.ini')
+
+        host = self.config['spp-ctl']['host']
+        ctl_api_port = self.config['spp-ctl']['ctl_api_port']
+        api_version = self.config['spp-ctl']['api_version']
+
+        self.base_url = 'http://{host}:{port}/{api_ver}'.format(
+                host=host, port=ctl_api_port, api_ver=api_version)
+
+        # Launch default spp_nfv
+        sec_port = '6666'
+        nfv = {'mem': self.config['spp_nfv']['mem'],
+               'lcores': self.config['spp_nfv']['lcores']}
+        params = {
+                'proc_name': 'spp_nfv',
+                'client_id': str(self.default_sec_id),
+                'eal': {
+                    '-m': nfv['mem'], '-l': nfv['lcores'],
+                    '--proc-type': 'secondary'},
+                'app': {
+                    '-s': '{}:{}'.format(host, sec_port),
+                    '-n': str(self.default_sec_id)}
+                }
+        url = '{baseurl}/primary/launch'.format(baseurl=self.base_url)
+        requests.put(url, data=json.dumps(params))
+        time.sleep(0.2)  # wait until be launched
+
+    def tearDown(self):
+        """Shutdown default spp_nfv."""
+
+        url = '{baseurl}/{sec_type}/{sec_id}'.format(
+                baseurl=self.base_url,
+                sec_type=self.sec_type,
+                sec_id=self.default_sec_id)
+        response = requests.delete(url)
+
+    def _get_status(self):
+        """Get status of default spp_nfv process."""
+
+        url = "{baseurl}/{sec_type}/{sec_id}".format(
+                baseurl=self.base_url,
+                sec_type=self.sec_type,
+                sec_id=self.default_sec_id)
+        response = requests.get(url)
+        return response.json()
+
+    def _set_forwarding_status(self, action):
+        """Set forwarding status as start or stop."""
+
+        if action in ['start', 'stop']:
+            url = "{baseurl}/{sec_type}/{sec_id}/forward".format(
+                    baseurl=self.base_url,
+                    sec_type=self.sec_type,
+                    sec_id=self.default_sec_id)
+            params = {'action': action}
+            response = requests.put(url, data=json.dumps(params))
+            return True
+        else:
+            return False
+
+    def _add_or_del_port(self, action, res_uid):
+        if action in ['add', 'del']:
+            url = "{baseurl}/{sec_type}/{sec_id}/ports".format(
+                    baseurl=self.base_url,
+                    sec_type=self.sec_type,
+                    sec_id=self.default_sec_id)
+            params = {'action': action, 'port': res_uid}
+            requests.put(url, data=json.dumps(params))
+            return True
+        else:
+            return False
+
+    def _add_port(self, res_uid):
+        self._add_or_del_port('add', res_uid)
+
+    def _del_port(self, res_uid):
+        self._add_or_del_port('del', res_uid)
+
+    def _assert_add_del_port(self, port):
+        self._add_port(port)
+        nfv = self._get_status()
+        self.assertTrue(port in nfv['ports'])
+
+        self._del_port(port)
+        nfv = self._get_status()
+        self.assertFalse(port in nfv['ports'])
+
+    def _patch(self, src, dst):
+        """Set patch between given ports."""
+
+        url = "{baseurl}/{sec_type}/{sec_id}/patches".format(
+                baseurl=self.base_url,
+                sec_type=self.sec_type,
+                sec_id=self.default_sec_id)
+        params = {'src': src, 'dst': dst}
+        requests.put(url, data=json.dumps(params))
+
+    def _reset_patches(self):
+        url = "{baseurl}/{sec_type}/{sec_id}/patches".format(
+                baseurl=self.base_url,
+                sec_type=self.sec_type,
+                sec_id=self.default_sec_id)
+        requests.delete(url)
+
+    # Test methods for testing spp_nfv from here.
+    def test_sec_id(self):
+        """Confirm sec ID is expected value."""
+
+        nfv = self._get_status()
+        self.assertEqual(nfv['client-id'], 1)
+
+    def test_forward_stop(self):
+        """Confirm forwarding is started and stopped."""
+
+        self._set_forwarding_status('start')
+        nfv = self._get_status()
+        self.assertEqual(nfv['status'], 'running')
+
+        self._set_forwarding_status('stop')
+        nfv = self._get_status()
+        self.assertEqual(nfv['status'], 'idling')
+
+    def test_add_del_ring(self):
+        """Check if ring PMD is added."""
+
+        port = 'ring:0'
+        self._assert_add_del_port(port)
+
+    def test_add_del_vhost(self):
+        """Check if vhost PMD is added."""
+
+        port = 'vhost:1'
+        self._assert_add_del_port(port)
+
+    def test_add_del_pcap(self):
+        """Check if pcap PMD is added."""
+
+        # TODO(yasufum): pcap cannot be adde because I do not know why...
+        port = 'pcap:1'
+        pass
+
+    def test_make_patch(self):
+        """Check if patch between ports is created and reseted."""
+
+        ports = ['ring:1', 'ring:2']
+
+        for port in ports:
+            self._add_port(port)
+        self._patch(ports[0], ports[1])
+        nfv = self._get_status()
+        self.assertTrue({'src': ports[0], 'dst': ports[1]} in nfv['patches'])
+
+        self._reset_patches()
+        nfv = self._get_status()
+        self.assertEqual(nfv['patches'], [])
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [spp] [PATCH 2/3] test: add spp_nfv test for forwarding
  2019-12-17  2:37 [spp] [PATCH 0/3] Introduce unit test for SPP processes yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 1/3] test: add test for spp_nfv yasufum.o
@ 2019-12-17  2:37 ` yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 3/3] test: add test for spp_primary yasufum.o
  2 siblings, 0 replies; 4+ messages in thread
From: yasufum.o @ 2019-12-17  2:37 UTC (permalink / raw)
  To: spp, ferruh.yigit, yasufum.o

From: Yasufumi Ogawa <yasufum.o@gmail.com>

This update is to add a test for checking if packet is forwarded between
ports. In this test, it sends packets from src nullpmd to dst nullpmd
via ring, and number of forwarded packets is checked by referring status
of spp_primary.

Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
---
 test/test_spp_nfv.py | 47 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/test/test_spp_nfv.py b/test/test_spp_nfv.py
index 1ebb3d3..1376df7 100644
--- a/test/test_spp_nfv.py
+++ b/test/test_spp_nfv.py
@@ -126,6 +126,14 @@ class TestSppNfv(unittest.TestCase):
                 sec_id=self.default_sec_id)
         requests.delete(url)
 
+    def _get_pri_status(self):
+        """Get status of spp_primary"""
+
+        url = "{baseurl}/primary/status".format(
+                baseurl=self.base_url)
+        response = requests.get(url)
+        return response.json()
+
     # Test methods for testing spp_nfv from here.
     def test_sec_id(self):
         """Confirm sec ID is expected value."""
@@ -177,3 +185,42 @@ class TestSppNfv(unittest.TestCase):
         self._reset_patches()
         nfv = self._get_status()
         self.assertEqual(nfv['patches'], [])
+
+        for port in ports:
+            self._del_port(port)
+
+    def test_forwarding(self):
+        """Check if forwarding packet is counted up.
+
+        This test confirm that packet counter on ring PMD is counted up
+        after forwarding is started. It waits about 1sec so that
+        certain amount of packets are forwarded.
+        """
+
+        wait_time = 1  # sec, wait for forwarding
+        ring_idx = 1
+        ports = {
+                'src': 'nullpmd:1',
+                'dst': 'nullpmd:2',
+                'ring': 'ring:{}'.format(ring_idx)
+                }
+
+        for port in ports.values():
+            self._add_port(port)
+
+        self._patch(ports['src'], ports['ring'])
+        self._patch(ports['ring'], ports['dst'])
+        self._set_forwarding_status('start')
+
+        # NOTE: this test is failed if sleep time is too small.
+        time.sleep(wait_time)  # wait to start forwarding
+
+        self._set_forwarding_status('stop')
+        self._reset_patches()
+        for port in ports.values():
+            self._del_port(port)
+
+        pri = self._get_pri_status()
+
+        self.assertTrue(pri['ring_ports'][ring_idx]['rx'] > 0)
+        self.assertTrue(pri['ring_ports'][ring_idx]['tx'] > 0)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [spp] [PATCH 3/3] test: add test for spp_primary
  2019-12-17  2:37 [spp] [PATCH 0/3] Introduce unit test for SPP processes yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 1/3] test: add test for spp_nfv yasufum.o
  2019-12-17  2:37 ` [spp] [PATCH 2/3] test: add spp_nfv test for forwarding yasufum.o
@ 2019-12-17  2:37 ` yasufum.o
  2 siblings, 0 replies; 4+ messages in thread
From: yasufum.o @ 2019-12-17  2:37 UTC (permalink / raw)
  To: spp, ferruh.yigit, yasufum.o

From: Yasufumi Ogawa <yasufum.o@gmail.com>

This patch is to add a unit test code for spp_primary. Test cases are
defined by following SPP REST API as similar to spp_nfv.

Unit tests are expected to be run in the `test` dir. Specify the name
of test if you run tests for a process, or all processes without the
name.

  $ cd /path/to/spp/test
  $ python3 -m unittest test_spp_primary  # test only spp_primary
  # or
  $ python3 -m unittest  # test all

Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
---
 test/test_spp_nfv.py     |  24 +++---
 test/test_spp_primary.py | 177 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 189 insertions(+), 12 deletions(-)
 create mode 100644 test/test_spp_primary.py

diff --git a/test/test_spp_nfv.py b/test/test_spp_nfv.py
index 1376df7..cf2cae4 100644
--- a/test/test_spp_nfv.py
+++ b/test/test_spp_nfv.py
@@ -5,10 +5,10 @@ import configparser
 import json
 import requests
 import time
-import unittest
+from unittest import TestCase
 
 
-class TestSppNfv(unittest.TestCase):
+class TestSppNfv(TestCase):
     """Test spp_nfv.
 
     Test as following the REST API reference. It does not include terminating
@@ -58,7 +58,7 @@ class TestSppNfv(unittest.TestCase):
                 sec_id=self.default_sec_id)
         response = requests.delete(url)
 
-    def _get_status(self):
+    def _get_nfv_status(self):
         """Get status of default spp_nfv process."""
 
         url = "{baseurl}/{sec_type}/{sec_id}".format(
@@ -102,11 +102,11 @@ class TestSppNfv(unittest.TestCase):
 
     def _assert_add_del_port(self, port):
         self._add_port(port)
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertTrue(port in nfv['ports'])
 
         self._del_port(port)
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertFalse(port in nfv['ports'])
 
     def _patch(self, src, dst):
@@ -138,28 +138,28 @@ class TestSppNfv(unittest.TestCase):
     def test_sec_id(self):
         """Confirm sec ID is expected value."""
 
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertEqual(nfv['client-id'], 1)
 
     def test_forward_stop(self):
         """Confirm forwarding is started and stopped."""
 
         self._set_forwarding_status('start')
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertEqual(nfv['status'], 'running')
 
         self._set_forwarding_status('stop')
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertEqual(nfv['status'], 'idling')
 
     def test_add_del_ring(self):
-        """Check if ring PMD is added."""
+        """Check if ring PMD is added and deleted."""
 
         port = 'ring:0'
         self._assert_add_del_port(port)
 
     def test_add_del_vhost(self):
-        """Check if vhost PMD is added."""
+        """Check if vhost PMD is added and deleted."""
 
         port = 'vhost:1'
         self._assert_add_del_port(port)
@@ -179,11 +179,11 @@ class TestSppNfv(unittest.TestCase):
         for port in ports:
             self._add_port(port)
         self._patch(ports[0], ports[1])
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertTrue({'src': ports[0], 'dst': ports[1]} in nfv['patches'])
 
         self._reset_patches()
-        nfv = self._get_status()
+        nfv = self._get_nfv_status()
         self.assertEqual(nfv['patches'], [])
 
         for port in ports:
diff --git a/test/test_spp_primary.py b/test/test_spp_primary.py
new file mode 100644
index 0000000..c93ac85
--- /dev/null
+++ b/test/test_spp_primary.py
@@ -0,0 +1,177 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Nippon Telegraph and Telephone Corporation
+
+import configparser
+import json
+import requests
+import time
+from unittest import TestCase
+
+
+class TestSppPrimary(TestCase):
+    """Test spp_primary.
+
+    Test sernarios are following the REST API reference.
+    """
+
+    def setUp(self):
+        """Initialization before the tests."""
+
+        self.config = configparser.ConfigParser()
+        self.config.read('config.ini')
+
+        host = self.config['spp-ctl']['host']
+        ctl_api_port = self.config['spp-ctl']['ctl_api_port']
+        api_version = self.config['spp-ctl']['api_version']
+
+        self.base_url = 'http://{host}:{port}/{api_ver}'.format(
+                host=host, port=ctl_api_port, api_ver=api_version)
+
+    def tearDown(self):
+        """Finalization."""
+
+        pass
+
+    def _get_status(self):
+        """Get status of default spp_primary process."""
+
+        url = "{baseurl}/primary/status".format(
+                baseurl=self.base_url)
+        response = requests.get(url)
+        return response.json()
+
+    def _set_forwarding_status(self, action):
+        """Set forwarding status as start or stop."""
+
+        if action in ['start', 'stop']:
+            url = "{baseurl}/primary/forward".format(
+                    baseurl=self.base_url)
+            params = {'action': action}
+            response = requests.put(url, data=json.dumps(params))
+            return True
+        else:
+            return False
+
+    def _add_or_del_port(self, action, res_uid):
+        if action in ['add', 'del']:
+            url = "{baseurl}/primary/ports".format(
+                    baseurl=self.base_url)
+            params = {'action': action, 'port': res_uid}
+            requests.put(url, data=json.dumps(params))
+            return True
+        else:
+            return False
+
+    def _add_port(self, res_uid):
+        self._add_or_del_port('add', res_uid)
+
+    def _del_port(self, res_uid):
+        self._add_or_del_port('del', res_uid)
+
+    def _assert_add_del_port(self, port):
+        self._add_port(port)
+        stat = self._get_status()
+        self.assertTrue(port in stat['forwarder']['ports'])
+
+        self._del_port(port)
+        stat = self._get_status()
+        self.assertFalse(port in stat['forwarder']['ports'])
+
+    def _patch(self, src, dst):
+        """Set patch between given ports."""
+
+        url = "{baseurl}/primary/patches".format(
+                baseurl=self.base_url)
+        params = {'src': src, 'dst': dst}
+        requests.put(url, data=json.dumps(params))
+
+    def _reset_patches(self):
+        url = "{baseurl}/primary/patches".format(
+                baseurl=self.base_url)
+        requests.delete(url)
+
+    # Test methods for testing spp_primary from here.
+    def test_forward_stop(self):
+        """Confirm forwarding is started and stopped."""
+
+        self._set_forwarding_status('start')
+        stat = self._get_status()
+        self.assertEqual(stat['forwarder']['status'], 'running')
+
+        self._set_forwarding_status('stop')
+        stat = self._get_status()
+        self.assertEqual(stat['forwarder']['status'], 'idling')
+
+    def test_add_del_ring(self):
+        """Check if ring PMD is added or deleted."""
+
+        port = 'ring:0'
+        self._assert_add_del_port(port)
+
+    def test_add_del_vhost(self):
+        """Check if vhost PMD is added or deleted."""
+
+        port = 'vhost:1'
+        self._assert_add_del_port(port)
+
+    def test_add_del_pcap(self):
+        """Check if pcap PMD is added or deleted."""
+
+        # TODO(yasufum): pcap cannot be adde because I do not know why...
+        port = 'pcap:1'
+        pass
+
+    def test_make_patch(self):
+        """Check if patch between ports is created and reseted."""
+
+        ports = ['ring:1', 'ring:2']
+
+        for port in ports:
+            self._add_port(port)
+        self._patch(ports[0], ports[1])
+        stat = self._get_status()
+        self.assertTrue(
+                {'src': ports[0], 'dst': ports[1]} in stat['forwarder']['patches'])
+
+        self._reset_patches()
+        stat = self._get_status()
+        self.assertEqual(stat['forwarder']['patches'], [])
+
+        for port in ports:
+            self._del_port(port)
+
+    def test_forwarding(self):
+        """Check if forwarding packet is counted up.
+
+        This test confirm that packet counter on ring PMD is counted up
+        after forwarding is started. It waits about 1sec so that
+        certain amount of packets are forwarded.
+        """
+
+        wait_time = 1  # sec, wait for forwarding
+        ring_idx = 1
+        ports = {
+                'src': 'nullpmd:1',
+                'dst': 'nullpmd:2',
+                'ring': 'ring:{}'.format(ring_idx)
+                }
+
+        for port in ports.values():
+            self._add_port(port)
+
+        self._patch(ports['src'], ports['ring'])
+        self._patch(ports['ring'], ports['dst'])
+        self._set_forwarding_status('start')
+
+        # NOTE: this test is failed if sleep time is too small.
+        time.sleep(wait_time)  # wait to start forwarding
+
+        self._set_forwarding_status('stop')
+        self._reset_patches()
+        for port in ports.values():
+            self._del_port(port)
+
+        pri = self._get_status()
+
+        self.assertTrue(pri['ring_ports'][ring_idx]['rx'] > 0)
+        self.assertTrue(pri['ring_ports'][ring_idx]['tx'] > 0)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-17  2:37 [spp] [PATCH 0/3] Introduce unit test for SPP processes yasufum.o
2019-12-17  2:37 ` [spp] [PATCH 1/3] test: add test for spp_nfv yasufum.o
2019-12-17  2:37 ` [spp] [PATCH 2/3] test: add spp_nfv test for forwarding yasufum.o
2019-12-17  2:37 ` [spp] [PATCH 3/3] test: add test for spp_primary yasufum.o

Soft Patch Panel

Archives are clonable:
	git clone --mirror http://inbox.dpdk.org/spp/0 spp/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 spp spp/ http://inbox.dpdk.org/spp \
		spp@dpdk.org
	public-inbox-index spp


Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.spp


AGPL code for this site: git clone https://public-inbox.org/ public-inbox