From 870fb4ff222f6547ef24e712dd10ada0d6c7073c Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 25 Aug 2016 12:04:50 +0300 Subject: [PATCH] Create initial infrastructure for fuel-qa refactoring: .core package Create initial unittest infrastructure: Create root packages: .core .core._tests Checkers (and gates): tox.ini: cover env requires: pytest-cov mock /core/pytest.ini /.coveragerc Example changes: add collector client as initial target for refactor and testing unit tests for HTTPClient (http.py) as example Blueprint: fuel-qa-join-helpers Change-Id: I35207eb7bb45ec20d1b61f28be564097420c9f27 --- .coveragerc | 5 ++ .gitignore | 4 ++ core/__init__.py | 0 core/_tests/__init__.py | 0 core/_tests/helpers/__init__.py | 0 core/_tests/helpers/test_http.py | 19 ++++++ core/helpers/__init__.py | 0 core/helpers/http.py | 43 +++++++++++++ core/models/__init__.py | 0 core/models/collector_client.py | 80 +++++++++++++++++++++++++ core/pytest.ini | 3 + fuelweb_test/helpers/http.py | 37 ++++-------- fuelweb_test/models/collector_client.py | 73 ++++------------------ fuelweb_test/models/environment.py | 3 +- tox.ini | 11 +++- 15 files changed, 192 insertions(+), 86 deletions(-) create mode 100644 .coveragerc create mode 100644 core/__init__.py create mode 100644 core/_tests/__init__.py create mode 100644 core/_tests/helpers/__init__.py create mode 100644 core/_tests/helpers/test_http.py create mode 100644 core/helpers/__init__.py create mode 100644 core/helpers/http.py create mode 100644 core/models/__init__.py create mode 100644 core/models/collector_client.py create mode 100644 core/pytest.ini diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..23d4372c7 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,5 @@ +[run] +source = + core +omit = + core/_tests/* diff --git a/.gitignore b/.gitignore index 1780d5f0a..69e84b8ec 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ pip-log.txt .coverage .tox nosetests.xml +unit.xml +/htmlcov/ # Translations *.mo @@ -56,3 +58,5 @@ sys_test.log # Cache /.cache +/core/.cache +__pycache__ diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/_tests/__init__.py b/core/_tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/_tests/helpers/__init__.py b/core/_tests/helpers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/_tests/helpers/test_http.py b/core/_tests/helpers/test_http.py new file mode 100644 index 000000000..f9c018d36 --- /dev/null +++ b/core/_tests/helpers/test_http.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import unittest + +from mock import patch +from mock import call + +from core.helpers.http import HTTPClientZabbix + + +@patch('core.helpers.http.request') +class TestHTTPClientZabbix(unittest.TestCase): + def test_init(self, req): + url = 'http://localhost' + client = HTTPClientZabbix(url=url) + self.assertEqual(client.url, url) + req.assert_has_calls(( + call.build_opener(req.HTTPHandler), + )) diff --git a/core/helpers/__init__.py b/core/helpers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/helpers/http.py b/core/helpers/http.py new file mode 100644 index 000000000..5530b392d --- /dev/null +++ b/core/helpers/http.py @@ -0,0 +1,43 @@ +# Copyright 2013 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +# pylint: disable=import-error +# noinspection PyUnresolvedReferences +from six.moves.urllib import request +# pylint: enable=import-error + + +class HTTPClientZabbix(object): + """HTTPClientZabbix.""" # TODO documentation + + def __init__(self, url): + self.url = url + self.opener = request.build_opener(request.HTTPHandler) + + def get(self, endpoint=None, cookie=None): + req = request.Request(self.url + endpoint) + if cookie: + req.add_header('cookie', cookie) + return self.opener.open(req) + + def post(self, endpoint=None, data=None, content_type="text/css", + cookie=None): + if not data: + data = {} + req = request.Request(self.url + endpoint, data=json.dumps(data)) + req.add_header('Content-Type', content_type) + if cookie: + req.add_header('cookie', cookie) + return self.opener.open(req) diff --git a/core/models/__init__.py b/core/models/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/core/models/collector_client.py b/core/models/collector_client.py new file mode 100644 index 000000000..7b3ea2f8f --- /dev/null +++ b/core/models/collector_client.py @@ -0,0 +1,80 @@ +# Copyright 2013 Mirantis, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from core.helpers.http import HTTPClientZabbix +# TODO(astepanov): switch to requests library +from fuelweb_test import logwrap +from fuelweb_test.helpers.decorators import json_parse + + +class CollectorClient(object): + """CollectorClient.""" # TODO documentation + + def __init__(self, collector_ip, endpoint): + url = "http://{0}/{1}".format(collector_ip, endpoint) + self._client = HTTPClientZabbix(url=url) + super(CollectorClient, self).__init__() + + @property + def client(self): + return self._client + + @logwrap + @json_parse + def get_oswls(self, master_node_uid): + return self.client.get("/oswls/{0}".format(master_node_uid)) + + @logwrap + @json_parse + def get_installation_info(self, master_node_uid): + return self.client.get("/installation_info/{0}".format( + master_node_uid)) + + @logwrap + @json_parse + def get_action_logs(self, master_node_uid): + return self.client.get("/action_logs/{0}".format( + master_node_uid)) + + @logwrap + @json_parse + def get_oswls_by_resource(self, master_node_uid, resource): + return self.client.get("/oswls/{0}/{1}".format(master_node_uid, + resource)) + + @logwrap + def get_oswls_by_resource_data(self, master_node_uid, resource): + return self.get_oswls_by_resource(master_node_uid, + resource)['objs'][0]['resource_data'] + + @logwrap + def get_action_logs_ids(self, master_node_uid): + return [actions['id'] + for actions in self.get_action_logs(master_node_uid)] + + @logwrap + def get_action_logs_count(self, master_node_uid): + return len([actions['id'] + for actions in self.get_action_logs(master_node_uid)]) + + @logwrap + def get_action_logs_additional_info_by_id( + self, master_node_uid, action_id): + return [actions['body']['additional_info'] + for actions in self.get_action_logs(master_node_uid) + if actions['id'] == action_id] + + @logwrap + def get_installation_info_data(self, master_node_uid): + return self.get_installation_info(master_node_uid)['structure'] diff --git a/core/pytest.ini b/core/pytest.ini new file mode 100644 index 000000000..e967bfdc9 --- /dev/null +++ b/core/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +addopts = -vvv -s -p no:django -p no:ipdb +testpaths = _tests diff --git a/fuelweb_test/helpers/http.py b/fuelweb_test/helpers/http.py index 5530b392d..08dfb8bb1 100644 --- a/fuelweb_test/helpers/http.py +++ b/fuelweb_test/helpers/http.py @@ -12,32 +12,21 @@ # License for the specific language governing permissions and limitations # under the License. -import json -# pylint: disable=import-error -# noinspection PyUnresolvedReferences -from six.moves.urllib import request -# pylint: enable=import-error +from __future__ import absolute_import +from traceback import print_stack +from warnings import warn -class HTTPClientZabbix(object): - """HTTPClientZabbix.""" # TODO documentation +from fuelweb_test import logger - def __init__(self, url): - self.url = url - self.opener = request.build_opener(request.HTTPHandler) +from core.helpers.http import HTTPClientZabbix - def get(self, endpoint=None, cookie=None): - req = request.Request(self.url + endpoint) - if cookie: - req.add_header('cookie', cookie) - return self.opener.open(req) +msg = ( + 'fuelweb_test.helpers.http is deprecated and will be dropped ' + 'on 14.09.2016. Please use core.models.collector_client instead' +) +warn(msg) +print_stack() +logger.critical(msg) - def post(self, endpoint=None, data=None, content_type="text/css", - cookie=None): - if not data: - data = {} - req = request.Request(self.url + endpoint, data=json.dumps(data)) - req.add_header('Content-Type', content_type) - if cookie: - req.add_header('cookie', cookie) - return self.opener.open(req) +__all__ = ['HTTPClientZabbix'] diff --git a/fuelweb_test/models/collector_client.py b/fuelweb_test/models/collector_client.py index 5f7d314fe..53ddcfb57 100644 --- a/fuelweb_test/models/collector_client.py +++ b/fuelweb_test/models/collector_client.py @@ -12,68 +12,21 @@ # License for the specific language governing permissions and limitations # under the License. -from fuelweb_test import logwrap -from fuelweb_test.helpers.decorators import json_parse -from fuelweb_test.helpers.http import HTTPClientZabbix +from __future__ import absolute_import +from traceback import print_stack +from warnings import warn -class CollectorClient(object): - """CollectorClient.""" # TODO documentation +from fuelweb_test import logger - def __init__(self, collector_ip, endpoint): - url = "http://{0}/{1}".format(collector_ip, endpoint) - self._client = HTTPClientZabbix(url=url) - super(CollectorClient, self).__init__() +from core.models.collector_client import CollectorClient - @property - def client(self): - return self._client +msg = ( + 'fuelweb_test.models.collector_client is deprecated and will be dropped ' + 'on 14.09.2016. Please use core.models.collector_client instead' +) +warn(msg) +print_stack() +logger.critical(msg) - @logwrap - @json_parse - def get_oswls(self, master_node_uid): - return self.client.get("/oswls/{0}".format(master_node_uid)) - - @logwrap - @json_parse - def get_installation_info(self, master_node_uid): - return self.client.get("/installation_info/{0}".format( - master_node_uid)) - - @logwrap - @json_parse - def get_action_logs(self, master_node_uid): - return self.client.get("/action_logs/{0}".format( - master_node_uid)) - - @logwrap - @json_parse - def get_oswls_by_resource(self, master_node_uid, resource): - return self.client.get("/oswls/{0}/{1}".format(master_node_uid, - resource)) - - @logwrap - def get_oswls_by_resource_data(self, master_node_uid, resource): - return self.get_oswls_by_resource(master_node_uid, - resource)['objs'][0]['resource_data'] - - @logwrap - def get_action_logs_ids(self, master_node_uid): - return [actions['id'] - for actions in self.get_action_logs(master_node_uid)] - - @logwrap - def get_action_logs_count(self, master_node_uid): - return len([actions['id'] - for actions in self.get_action_logs(master_node_uid)]) - - @logwrap - def get_action_logs_additional_info_by_id( - self, master_node_uid, action_id): - return [actions['body']['additional_info'] - for actions in self.get_action_logs(master_node_uid) - if actions['id'] == action_id] - - @logwrap - def get_installation_info_data(self, master_node_uid): - return self.get_installation_info(master_node_uid)['structure'] +__all__ = ['CollectorClient'] diff --git a/fuelweb_test/models/environment.py b/fuelweb_test/models/environment.py index 12bec4704..7de57b074 100644 --- a/fuelweb_test/models/environment.py +++ b/fuelweb_test/models/environment.py @@ -29,6 +29,8 @@ from proboscis.asserts import assert_equal from proboscis.asserts import assert_true import six +from core.models.collector_client import CollectorClient + from fuelweb_test.helpers.decorators import revert_info from fuelweb_test.helpers.decorators import update_rpm_packages from fuelweb_test.helpers.decorators import upload_manifests @@ -45,7 +47,6 @@ from fuelweb_test.helpers.utils import TimeStat from fuelweb_test.helpers.utils import YamlEditor from fuelweb_test.helpers import multiple_networks_hacks from fuelweb_test.models.fuel_web_client import FuelWebClient -from fuelweb_test.models.collector_client import CollectorClient from fuelweb_test import settings from fuelweb_test.settings import CUSTOM_FUEL_SETTING_YAML from fuelweb_test.settings import iface_alias diff --git a/tox.ini b/tox.ini index 906ac6baa..204637b06 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ [tox] skipsdist = True -envlist = pep8, py27, pylint, docs, pep8-py{34,35}, pylint-py{27}-{fuelweb,system,gates,fuel} +envlist = pep8, py27, pylint, docs, cover, pep8-py{34,35}, pylint-py{27}-{fuelweb,system,gates,fuel} skip_missing_interpreters = True [testenv] @@ -83,3 +83,12 @@ deps = {[testenv]deps} sphinx commands = sphinx-build -b html -d _build/doctrees . _build/html + +[testenv:cover] +deps = + mock>=1.2 + pytest-cov + {[testenv]deps} +commands = + py.test --cov-config .coveragerc --cov-report html --cov=core core/_tests + coverage report