Create API and command to create a influxDB container 13/25013/4
authorchenjiankun <chenjiankun1@huawei.com>
Mon, 28 Nov 2016 01:51:47 +0000 (01:51 +0000)
committerchenjiankun <chenjiankun1@huawei.com>
Wed, 30 Nov 2016 03:05:23 +0000 (03:05 +0000)
JIRA: YARDSTICK-425

This API is used to create a influxDB Container
Add command line to create a influxDB Container, too

Change-Id: If9c2d04b779924d492a5d5ea91f7968fa959570e
Signed-off-by: chenjiankun <chenjiankun1@huawei.com>
15 files changed:
api/actions/env.py [new file with mode: 0644]
api/api-prepare.sh
api/urls.py
api/views.py
install.sh
requirements.txt
tests/unit/api/actions/test_env.py [new file with mode: 0644]
tests/unit/api/test_views.py
tests/unit/cmd/commands/test_env.py [new file with mode: 0644]
tests/unit/common/test_httpClient.py [new file with mode: 0644]
yardstick/cmd/cli.py
yardstick/cmd/commands/env.py [new file with mode: 0644]
yardstick/common/constants.py
yardstick/common/httpClient.py [new file with mode: 0644]
yardstick/common/utils.py

diff --git a/api/actions/env.py b/api/actions/env.py
new file mode 100644 (file)
index 0000000..3216499
--- /dev/null
@@ -0,0 +1,85 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import logging
+import threading
+import time
+
+from docker import Client
+
+from yardstick.common import constants as config
+from yardstick.common import utils as yardstick_utils
+from api import conf as api_conf
+from api.utils import common as common_utils
+from api.utils import influx
+
+logger = logging.getLogger(__name__)
+
+
+def createInfluxDBContainer(args):
+    try:
+        container = _create_influxdb_container()
+        _config_output_file()
+        thread = threading.Thread(target=_config_influxdb)
+        thread.start()
+        return common_utils.result_handler('success', container)
+    except Exception as e:
+        message = 'Failed to create influxdb container: %s' % e
+        return common_utils.error_handler(message)
+
+
+def _create_influxdb_container():
+    client = Client(base_url=config.DOCKER_URL)
+
+    ports = [8083, 8086]
+    port_bindings = {k: k for k in ports}
+    host_config = client.create_host_config(port_bindings=port_bindings)
+
+    container = client.create_container(image='tutum/influxdb',
+                                        ports=ports,
+                                        detach=True,
+                                        tty=True,
+                                        host_config=host_config)
+    client.start(container)
+    return container
+
+
+def _config_influxdb():
+    time.sleep(20)
+    try:
+        client = influx.get_data_db_client()
+        client.create_user(config.USER, config.PASSWORD, config.DATABASE)
+        client.create_database(config.DATABASE)
+        logger.info('Success to config influxDB')
+    except Exception as e:
+        logger.debug('Failed to config influxDB: %s', e)
+
+
+def _config_output_file():
+    yardstick_utils.makedirs('/etc/yardstick')
+    with open('/etc/yardstick/yardstick.conf', 'w') as f:
+        f.write("""\
+[DEFAULT]
+debug = True
+dispatcher = influxdb
+
+[dispatcher_file]
+file_path = /tmp/yardstick.out
+
+[dispatcher_http]
+timeout = 5
+# target = http://127.0.0.1:8000/results
+
+[dispatcher_influxdb]
+timeout = 5
+target = http://%s:8086
+db_name = yardstick
+username = root
+password = root
+"""
+                % api_conf.GATEWAY_IP)
index 075d787..c05dbb5 100755 (executable)
@@ -1,41 +1,19 @@
 #!/bin/bash
-
-# yardstick output config
-output_config='/etc/yardstick/yardstick.conf'
-
-if [[ ! -e "${output_config}" ]];then
-    gateway_ip=$(ip route | grep default | awk '{print $3}')
-    echo "${gateway_ip}"
-
-    install -d /etc/yardstick -m 0755 -o root
-
-    cat << EOF > "${output_config}"
-[DEFAULT]
-debug = True
-dispatcher = influxdb
-
-[dispatcher_file]
-file_path = /tmp/yardstick.out
-
-[dispatcher_http]
-timeout = 5
-# target = http://127.0.0.1:8000/results
-
-[dispatcher_influxdb]
-timeout = 5
-target = http://${gateway_ip}:8086
-db_name = yardstick
-username = root
-password = root
-EOF
-fi
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
 
 # nginx config
 nginx_config='/etc/nginx/conf.d/yardstick.conf'
 
 if [[ ! -e "${nginx_config}" ]];then
 
-    cat << EOF >> "${nginx_config}"
+    cat << EOF > "${nginx_config}"
 server {
     listen 5000;
     server_name localhost;
index 2a9e72a..eaaf8b6 100644 (file)
@@ -12,5 +12,6 @@ from api.utils.common import Url
 
 urlpatterns = [
     Url('/yardstick/test/action', views.Test, 'test'),
-    Url('/yardstick/result/action', views.Result, 'result')
+    Url('/yardstick/result/action', views.Result, 'result'),
+    Url('/yardstick/env/action', views.Env, 'env')
 ]
index e78389f..7357625 100644 (file)
@@ -14,6 +14,7 @@ from flask_restful import Resource
 from api.utils import common as common_utils
 from api.actions import test as test_action
 from api.actions import result as result_action
+from api.actions import env as env_action
 
 logger = logging.getLogger(__name__)
 
@@ -40,3 +41,15 @@ class Result(Resource):
             return getattr(result_action, action)(args)
         except AttributeError:
             return common_utils.error_handler('Wrong action')
+
+
+class Env(Resource):
+    def post(self):
+        action = common_utils.translate_to_str(request.json.get('action', ''))
+        args = common_utils.translate_to_str(request.json.get('args', {}))
+        logger.debug('Input args is: action: %s, args: %s', action, args)
+
+        try:
+            return getattr(env_action, action)(args)
+        except AttributeError:
+            return common_utils.error_handler('Wrong action')
index 8fdd075..afb7351 100755 (executable)
@@ -14,7 +14,7 @@ apt-get update && apt-get install -y \
     libxml2-dev \
     libxslt1-dev \
     nginx \
-    uswgi \
+    uwsgi \
     uwsgi-plugin-python \
     python-setuptools && \
     easy_install -U setuptools
index ab20c75..b47951e 100644 (file)
@@ -81,3 +81,4 @@ flask==0.11.1
 flask-restful==0.3.5
 influxdb==3.0.0
 pyroute2==0.4.10
+docker-py==1.10.6
diff --git a/tests/unit/api/actions/test_env.py b/tests/unit/api/actions/test_env.py
new file mode 100644 (file)
index 0000000..e674d73
--- /dev/null
@@ -0,0 +1,50 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import unittest
+import mock
+
+from api.actions import env
+
+
+class CreateInfluxDBContainerTestCase(unittest.TestCase):
+
+    @mock.patch('api.actions.env._create_influxdb_container')
+    def test_create_influxdb_container(self, mock_create_container):
+        env.createInfluxDBContainer({})
+        mock_create_container.assert_called_with()
+
+
+class CreateInfluxdbContainerTestCase(unittest.TestCase):
+
+    @mock.patch('api.actions.env.Client')
+    def test_create_influxdb_container(self, mock_influx_client):
+        env._create_influxdb_container()
+        self.assertFalse(mock_influx_client()._create_container.called)
+
+
+class ConfigInfluxdbTestCase(unittest.TestCase):
+
+    @mock.patch('api.actions.env.influx.get_data_db_client')
+    def test_config_influxdb(self, mock_influx_client):
+        env._config_influxdb()
+        mock_influx_client.assert_called_with()
+
+
+class ConfigOutputFile(unittest.TestCase):
+
+    def test_config_output_file(self):
+        pass
+
+
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
index e57ec08..b835567 100644 (file)
@@ -12,6 +12,7 @@ import json
 
 from api.views import Test
 from api.views import Result
+from api.views import Env
 
 
 class TestTestCase(unittest.TestCase):
@@ -37,6 +38,17 @@ class ResultTestCase(unittest.TestCase):
         self.assertEqual('error', result['status'])
 
 
+class EnvTestCase(unittest.TestCase):
+
+    @mock.patch('api.views.request')
+    def test_post(self, mock_request):
+        mock_request.json.get.side_effect = ['hello', {}]
+
+        result = json.loads(Env().post())
+
+        self.assertEqual('error', result['status'])
+
+
 def main():
     unittest.main()
 
diff --git a/tests/unit/cmd/commands/test_env.py b/tests/unit/cmd/commands/test_env.py
new file mode 100644 (file)
index 0000000..af1ab80
--- /dev/null
@@ -0,0 +1,29 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import unittest
+import mock
+
+from yardstick.cmd.commands.env import EnvCommand
+
+
+class EnvCommandTestCase(unittest.TestCase):
+
+    @mock.patch('yardstick.cmd.commands.env.HttpClient')
+    def test_do_influxdb(self, mock_http_client):
+        env = EnvCommand()
+        env.do_influxdb({})
+        self.assertTrue(mock_http_client().post.called)
+
+
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/unit/common/test_httpClient.py b/tests/unit/common/test_httpClient.py
new file mode 100644 (file)
index 0000000..b39dc23
--- /dev/null
@@ -0,0 +1,33 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import unittest
+import mock
+import json
+
+from yardstick.common import httpClient
+
+
+class HttpClientTestCase(unittest.TestCase):
+
+    @mock.patch('yardstick.common.httpClient.requests')
+    def test_post(self, mock_requests):
+        url = 'http://localhost:5000/hello'
+        data = {'hello': 'world'}
+        headers = {'Content-Type': 'application/json'}
+        httpClient.HttpClient().post(url, data)
+        mock_requests.post.assert_called_with(url, data=json.dumps(data),
+                                              headers=headers)
+
+
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
index ee8d1c5..d141731 100644 (file)
@@ -24,6 +24,7 @@ from yardstick.cmd.commands import runner
 from yardstick.cmd.commands import scenario
 from yardstick.cmd.commands import testcase
 from yardstick.cmd.commands import plugin
+from yardstick.cmd.commands import env
 
 CONF = cfg.CONF
 cli_opts = [
@@ -62,7 +63,8 @@ class YardstickCLI():
         'runner': runner.RunnerCommands,
         'scenario': scenario.ScenarioCommands,
         'testcase': testcase.TestcaseCommands,
-        'plugin': plugin.PluginCommands
+        'plugin': plugin.PluginCommands,
+        'env': env.EnvCommand
     }
 
     def __init__(self):
diff --git a/yardstick/cmd/commands/env.py b/yardstick/cmd/commands/env.py
new file mode 100644 (file)
index 0000000..d9c0c0a
--- /dev/null
@@ -0,0 +1,17 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+from yardstick.common.httpClient import HttpClient
+
+
+class EnvCommand(object):
+
+    def do_influxdb(self, args):
+        url = 'http://localhost:5000/yardstick/env/action'
+        data = {'action': 'createInfluxDBContainer'}
+        HttpClient().post(url, data)
index 40b29a7..8fbc82f 100644 (file)
@@ -1,3 +1,10 @@
 CONFIG_SAMPLE = '/etc/yardstick/config.yaml'
 
 RELENG_DIR = 'releng.dir'
+
+DOCKER_URL = 'unix://var/run/docker.sock'
+
+# database config
+USER = 'root'
+PASSWORD = 'root'
+DATABASE = 'yardstick'
diff --git a/yardstick/common/httpClient.py b/yardstick/common/httpClient.py
new file mode 100644 (file)
index 0000000..b6959b4
--- /dev/null
@@ -0,0 +1,27 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import json
+import logging
+
+import requests
+
+logger = logging.getLogger(__name__)
+
+
+class HttpClient(object):
+
+    def post(self, url, data):
+        data = json.dumps(data)
+        headers = {'Content-Type': 'application/json'}
+        try:
+            response = requests.post(url, data=data, headers=headers)
+            result = response.json()
+            logger.debug('The result is: %s', result)
+        except Exception as e:
+            logger.debug('Failed: %s', e)
index d639fb6..afbe4e8 100644 (file)
@@ -18,6 +18,7 @@
 import os
 import sys
 import yaml
+import errno
 from oslo_utils import importutils
 
 import yardstick
@@ -91,3 +92,11 @@ def get_para_from_yaml(file_path, args):
     else:
         print 'file not exist'
         return None
+
+
+def makedirs(d):
+    try:
+        os.makedirs(d)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            raise