summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>2018-05-19 19:31:37 +0100
committerRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>2018-06-14 07:16:06 +0000
commitc70be07682566ae05bafbf05a7e8c85ae4e1297e (patch)
treec5e52918e1e85941898d622eb20487ac39de1c4e
parentc601ff364311f0aae04b40b1672ea47bb487c327 (diff)
Add send socket commands function
Pktgen provides a TCP socket connection to allow the user to control it from a remote console or program [1]. This new method will provide Yardstick the ability to send string commands to a port in a remote host. [1] http://pktgen-dpdk.readthedocs.io/en/latest/socket.html JIRA: YARDSTICK-1186 Change-Id: I9d64ccad662fa3599de65654c5dab02833fcc91d Signed-off-by: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
-rw-r--r--yardstick/common/utils.py22
-rw-r--r--yardstick/tests/functional/common/test_utils.py38
-rw-r--r--yardstick/tests/unit/common/test_utils.py27
3 files changed, 87 insertions, 0 deletions
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py
index 108ee17bc..958ec627c 100644
--- a/yardstick/common/utils.py
+++ b/yardstick/common/utils.py
@@ -492,3 +492,25 @@ def wait_until_true(predicate, timeout=60, sleep=1, exception=None):
if exception and issubclass(exception, Exception):
raise exception # pylint: disable=raising-bad-type
raise exceptions.WaitTimeout
+
+
+def send_socket_command(host, port, command):
+ """Send a string command to a specific port in a host
+
+ :param host: (str) ip or hostname of the host
+ :param port: (int) port number
+ :param command: (str) command to send
+ :return: 0 if success, error number if error
+ """
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ ret = 0
+ try:
+ err_number = sock.connect_ex((host, int(port)))
+ if err_number != 0:
+ return err_number
+ sock.sendall(six.b(command))
+ except Exception: # pylint: disable=broad-except
+ ret = 1
+ finally:
+ sock.close()
+ return ret
diff --git a/yardstick/tests/functional/common/test_utils.py b/yardstick/tests/functional/common/test_utils.py
index b5333bbde..b9f1f773a 100644
--- a/yardstick/tests/functional/common/test_utils.py
+++ b/yardstick/tests/functional/common/test_utils.py
@@ -12,8 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import multiprocessing
import unittest
+import socket
import sys
+import time
from yardstick.common import utils
@@ -32,3 +35,38 @@ class ImportModulesFromPackageTestCase(unittest.TestCase):
library_obj = getattr(module_obj, library_name)
class_obj = getattr(library_obj, class_name)
self.assertEqual(class_name, class_obj().__class__.__name__)
+
+
+class SendSocketCommandTestCase(unittest.TestCase):
+
+ @staticmethod
+ def _run_socket_server(port):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.bind(('localhost', port))
+ sock.listen(1)
+ conn = None
+ while not conn:
+ conn, _ = sock.accept()
+ sock.close()
+
+ @staticmethod
+ def _terminate_server(socket_server):
+ # Wait until the socket server closes the open port.
+ time.sleep(1)
+ if socket_server and socket_server.is_alive():
+ socket_server.terminate()
+
+ def test_send_command(self):
+ port = 47001
+
+ socket_server = multiprocessing.Process(
+ name='run_socket_server',
+ target=SendSocketCommandTestCase._run_socket_server,
+ args=(port, )).start()
+
+ self.addCleanup(self._terminate_server, socket_server)
+
+ # Wait until the socket is open.
+ time.sleep(0.5)
+ self.assertEqual(
+ 0, utils.send_socket_command('localhost', port, 'test_command'))
diff --git a/yardstick/tests/unit/common/test_utils.py b/yardstick/tests/unit/common/test_utils.py
index 5fd91c87f..10ad0a67a 100644
--- a/yardstick/tests/unit/common/test_utils.py
+++ b/yardstick/tests/unit/common/test_utils.py
@@ -16,6 +16,7 @@ import mock
import os
import six
from six.moves import configparser
+import socket
import time
import unittest
@@ -1194,3 +1195,29 @@ class WaitUntilTrueTestCase(unittest.TestCase):
self.assertIsNone(
utils.wait_until_true(lambda: False, timeout=1, sleep=1,
exception=MyTimeoutException))
+
+
+class SendSocketCommandTestCase(unittest.TestCase):
+
+ @mock.patch.object(socket, 'socket')
+ def test_execute_correct(self, mock_socket):
+ mock_socket_obj = mock.Mock()
+ mock_socket_obj.connect_ex.return_value = 0
+ mock_socket.return_value = mock_socket_obj
+ self.assertEqual(0, utils.send_socket_command('host', 22, 'command'))
+ mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
+ mock_socket_obj.connect_ex.assert_called_once_with(('host', 22))
+ mock_socket_obj.sendall.assert_called_once_with(six.b('command'))
+ mock_socket_obj.close.assert_called_once()
+
+ @mock.patch.object(socket, 'socket')
+ def test_execute_exception(self, mock_socket):
+ mock_socket_obj = mock.Mock()
+ mock_socket_obj.connect_ex.return_value = 0
+ mock_socket.return_value = mock_socket_obj
+ mock_socket_obj.sendall.side_effect = socket.error
+ self.assertEqual(1, utils.send_socket_command('host', 22, 'command'))
+ mock_socket.assert_called_once_with(socket.AF_INET, socket.SOCK_STREAM)
+ mock_socket_obj.connect_ex.assert_called_once_with(('host', 22))
+ mock_socket_obj.sendall.assert_called_once_with(six.b('command'))
+ mock_socket_obj.close.assert_called_once()