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
This commit is contained in:
Alexey Stepanov 2016-08-25 12:04:50 +03:00
parent 033c82f7fb
commit 870fb4ff22
15 changed files with 192 additions and 86 deletions

5
.coveragerc Normal file
View File

@ -0,0 +1,5 @@
[run]
source =
core
omit =
core/_tests/*

4
.gitignore vendored
View File

@ -27,6 +27,8 @@ pip-log.txt
.coverage .coverage
.tox .tox
nosetests.xml nosetests.xml
unit.xml
/htmlcov/
# Translations # Translations
*.mo *.mo
@ -56,3 +58,5 @@ sys_test.log
# Cache # Cache
/.cache /.cache
/core/.cache
__pycache__

0
core/__init__.py Normal file
View File

0
core/_tests/__init__.py Normal file
View File

View File

View File

@ -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),
))

0
core/helpers/__init__.py Normal file
View File

43
core/helpers/http.py Normal file
View File

@ -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)

0
core/models/__init__.py Normal file
View File

View File

@ -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']

3
core/pytest.ini Normal file
View File

@ -0,0 +1,3 @@
[pytest]
addopts = -vvv -s -p no:django -p no:ipdb
testpaths = _tests

View File

@ -12,32 +12,21 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import json from __future__ import absolute_import
# pylint: disable=import-error
# noinspection PyUnresolvedReferences
from six.moves.urllib import request
# pylint: enable=import-error
from traceback import print_stack
from warnings import warn
class HTTPClientZabbix(object): from fuelweb_test import logger
"""HTTPClientZabbix.""" # TODO documentation
def __init__(self, url): from core.helpers.http import HTTPClientZabbix
self.url = url
self.opener = request.build_opener(request.HTTPHandler)
def get(self, endpoint=None, cookie=None): msg = (
req = request.Request(self.url + endpoint) 'fuelweb_test.helpers.http is deprecated and will be dropped '
if cookie: 'on 14.09.2016. Please use core.models.collector_client instead'
req.add_header('cookie', cookie) )
return self.opener.open(req) warn(msg)
print_stack()
logger.critical(msg)
def post(self, endpoint=None, data=None, content_type="text/css", __all__ = ['HTTPClientZabbix']
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)

View File

@ -12,68 +12,21 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from fuelweb_test import logwrap from __future__ import absolute_import
from fuelweb_test.helpers.decorators import json_parse
from fuelweb_test.helpers.http import HTTPClientZabbix
from traceback import print_stack
from warnings import warn
class CollectorClient(object): from fuelweb_test import logger
"""CollectorClient.""" # TODO documentation
def __init__(self, collector_ip, endpoint): from core.models.collector_client import CollectorClient
url = "http://{0}/{1}".format(collector_ip, endpoint)
self._client = HTTPClientZabbix(url=url)
super(CollectorClient, self).__init__()
@property msg = (
def client(self): 'fuelweb_test.models.collector_client is deprecated and will be dropped '
return self._client 'on 14.09.2016. Please use core.models.collector_client instead'
)
warn(msg)
print_stack()
logger.critical(msg)
@logwrap __all__ = ['CollectorClient']
@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']

View File

@ -29,6 +29,8 @@ from proboscis.asserts import assert_equal
from proboscis.asserts import assert_true from proboscis.asserts import assert_true
import six import six
from core.models.collector_client import CollectorClient
from fuelweb_test.helpers.decorators import revert_info from fuelweb_test.helpers.decorators import revert_info
from fuelweb_test.helpers.decorators import update_rpm_packages from fuelweb_test.helpers.decorators import update_rpm_packages
from fuelweb_test.helpers.decorators import upload_manifests 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.utils import YamlEditor
from fuelweb_test.helpers import multiple_networks_hacks from fuelweb_test.helpers import multiple_networks_hacks
from fuelweb_test.models.fuel_web_client import FuelWebClient 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 import settings
from fuelweb_test.settings import CUSTOM_FUEL_SETTING_YAML from fuelweb_test.settings import CUSTOM_FUEL_SETTING_YAML
from fuelweb_test.settings import iface_alias from fuelweb_test.settings import iface_alias

11
tox.ini
View File

@ -5,7 +5,7 @@
[tox] [tox]
skipsdist = True 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 skip_missing_interpreters = True
[testenv] [testenv]
@ -83,3 +83,12 @@ deps =
{[testenv]deps} {[testenv]deps}
sphinx sphinx
commands = sphinx-build -b html -d _build/doctrees . _build/html 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