Minor refactor
1. SingletonMeta -> modified to allow handling multiple classes and moved to metaclasses too. 2. @logwrap : process asserts too Changes reason: @logwrap was changed during test debug (was assert in wrapped function and stacktrace was not enough for reason understand) and moved out of test changest due to not mandatory for this test. Pros: Now assert, raised in wrapped function is recorded in log with details. SingletonMeta: was changed as "nice to have" during work on plugin helpers. Later plugin helpers was moved out of SshManager, and all code changes was moved to this changeset. Pros: Single way for handling the same tasks in different places. Previously SshManager used Metaclass, which could not be reused for more, than one class and Environment used __new__ directly written in class code. Related-Bug: #1518979 Related-Bug: #1519050 Change-Id: I798302879400747909229cc208f97a669f25bbf3
This commit is contained in:
parent
54974cad78
commit
fec8282ec4
|
@ -28,6 +28,11 @@ Decorators
|
|||
.. automodule:: fuelweb_test.helpers.decorators
|
||||
:members:
|
||||
|
||||
Metaclasses
|
||||
-----------
|
||||
.. automodule:: fuelweb_test.helpers.metaclasses
|
||||
:members:
|
||||
|
||||
Eb tables
|
||||
---------
|
||||
.. automodule:: fuelweb_test.helpers.eb_tables
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
import functools
|
||||
import logging
|
||||
import traceback
|
||||
import os
|
||||
from fuelweb_test.settings import LOGS_DIR
|
||||
|
||||
|
@ -54,9 +55,17 @@ def debug(logger):
|
|||
func.__name__, args, kwargs
|
||||
)
|
||||
)
|
||||
result = func(*args, **kwargs)
|
||||
logger.debug(
|
||||
"Done: {} with result: {}".format(func.__name__, result))
|
||||
try:
|
||||
result = func(*args, **kwargs)
|
||||
logger.debug(
|
||||
"Done: {} with result: {}".format(func.__name__, result))
|
||||
except BaseException as e:
|
||||
tb = traceback.format_exc()
|
||||
logger.error(
|
||||
'{func} raised: {exc!r}\n'
|
||||
'Traceback: {tb!s}'.format(
|
||||
func=func.__name__, exc=e, tb=tb))
|
||||
raise
|
||||
return result
|
||||
return wrapped
|
||||
return wrapper
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright 2016 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.
|
||||
|
||||
|
||||
class SingletonMeta(type):
|
||||
"""Metaclass for Singleton
|
||||
|
||||
Main goals: not need to implement __new__ in singleton classes
|
||||
"""
|
||||
_instances = {}
|
||||
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(
|
||||
SingletonMeta, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015 Mirantis, Inc.
|
||||
# Copyright 2016 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
|
||||
|
@ -20,32 +20,27 @@ import json
|
|||
from paramiko import RSAKey
|
||||
from devops.models.node import SSHClient
|
||||
from fuelweb_test import logger
|
||||
|
||||
|
||||
class SingletonMeta(type):
|
||||
def __init__(cls, name, bases, dict):
|
||||
super(SingletonMeta, cls).__init__(name, bases, dict)
|
||||
cls.instance = None
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
if self.instance is None:
|
||||
self.instance = super(SingletonMeta, self).__call__(*args, **kw)
|
||||
return self.instance
|
||||
|
||||
def __getattr__(cls, name):
|
||||
return getattr(cls(), name)
|
||||
from fuelweb_test.helpers import metaclasses
|
||||
|
||||
|
||||
class SSHManager(object):
|
||||
__metaclass__ = SingletonMeta
|
||||
__metaclass__ = metaclasses.SingletonMeta
|
||||
# Slots is used to prevent uncontrolled attributes set or remove.
|
||||
__slots__ = [
|
||||
'__connections', 'admin_ip', 'admin_port', 'login', '__password'
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
logger.debug('SSH_MANAGER: Run constructor SSHManager')
|
||||
self.connections = {}
|
||||
self.__connections = {} # Disallow direct type change and deletion
|
||||
self.admin_ip = None
|
||||
self.admin_port = None
|
||||
self.login = None
|
||||
self.password = None
|
||||
self.__password = None
|
||||
|
||||
@property
|
||||
def connections(self):
|
||||
return self.__connections
|
||||
|
||||
def initialize(self, admin_ip, login, password):
|
||||
""" It will be moved to __init__
|
||||
|
@ -58,7 +53,7 @@ class SSHManager(object):
|
|||
self.admin_ip = admin_ip
|
||||
self.admin_port = 22
|
||||
self.login = login
|
||||
self.password = password
|
||||
self.__password = password
|
||||
|
||||
def _connect(self, remote):
|
||||
""" Check if connection is stable and return this one
|
||||
|
@ -97,7 +92,7 @@ class SSHManager(object):
|
|||
host=ip,
|
||||
port=port,
|
||||
username=self.login,
|
||||
password=self.password,
|
||||
password=self.__password,
|
||||
private_keys=keys
|
||||
)
|
||||
logger.debug('SSH_MANAGER:Return existed connection for '
|
||||
|
@ -192,6 +187,10 @@ class SSHManager(object):
|
|||
|
||||
return result
|
||||
|
||||
def execute_async_on_remote(self, ip, cmd, port=22):
|
||||
remote = self._get_remote(ip=ip, port=port)
|
||||
return remote.execute_async(cmd)
|
||||
|
||||
def _json_deserialize(self, json_string):
|
||||
""" Deserialize json_string and return object
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ from proboscis.asserts import assert_true
|
|||
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
|
||||
from fuelweb_test.helpers.metaclasses import SingletonMeta
|
||||
from fuelweb_test.helpers.eb_tables import Ebtables
|
||||
from fuelweb_test.helpers.fuel_actions import AdminActions
|
||||
from fuelweb_test.helpers.fuel_actions import BaseActions
|
||||
|
@ -51,13 +52,7 @@ from fuelweb_test import logger
|
|||
class EnvironmentModel(object):
|
||||
"""EnvironmentModel.""" # TODO documentation
|
||||
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls._instance:
|
||||
cls._instance = super(EnvironmentModel, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
return cls._instance
|
||||
__metaclass__ = SingletonMeta
|
||||
|
||||
def __init__(self, config=None):
|
||||
if not hasattr(self, "_virt_env"):
|
||||
|
|
Loading…
Reference in New Issue