Merge "Add send socket commands function"
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Tue, 10 Jul 2018 07:48:43 +0000 (07:48 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 10 Jul 2018 07:48:43 +0000 (07:48 +0000)
yardstick/common/utils.py
yardstick/tests/functional/common/test_utils.py
yardstick/tests/unit/common/test_utils.py

index f9fe0e3..85cecc7 100644 (file)
@@ -527,3 +527,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
index b5333bb..b9f1f77 100644 (file)
 # 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'))
index 6247afd..446afdd 100644 (file)
@@ -16,6 +16,7 @@ import mock
 import os
 import six
 from six.moves import configparser
+import socket
 import time
 import unittest
 
@@ -1282,3 +1283,29 @@ class WaitUntilTrueTestCase(ut_base.BaseUnitTestCase):
             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()