Skip to content

Commit

Permalink
Merge with 2.7.1 and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gregoil committed Mar 7, 2018
1 parent 7b68242 commit f372ec6
Show file tree
Hide file tree
Showing 48 changed files with 1,274 additions and 1,102 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ basicstruct==1.0.3
colorama==0.3.9
configparser==3.5.0
constantly==15.1.0
coverage>=4.4.1
decorator==4.1.2
Django==1.7.11
docopt==0.6.2
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

setup(
name='rotest',
version="2.4.0",
version="2.7.1",
description="Resource oriented testing framework",
long_description=open("README.rst").read(),
license="MIT",
Expand Down
4 changes: 2 additions & 2 deletions src/rotest/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def get_command_line_configuration(configuration_schema, command_line_options):
"""Get configuration, based on the given arguments to the program.
Notes:
* The first argument is ommited, as it's the script path.
* The first argument is omitted, as it's the script path.
* Both '--option=value' and '--option value' formats are supported.
* Both '--<option>' and '-<option>' formats are supported.
Expand All @@ -49,7 +49,7 @@ def get_command_line_configuration(configuration_schema, command_line_options):
Returns:
dict: a match between each target option to the given value.
"""
# Ommiting the first argument, which is the script path
# Omitting the first argument, which is the script path
command_line_options = command_line_options[1:]

# Replacing every form of '--option=value' to '--option value'
Expand Down
36 changes: 18 additions & 18 deletions src/rotest/common/django_utils/fixtures/resource_ut.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
{"pk": 2, "model": "auth.group", "fields": {"name": "GROUP1", "permissions": []}},
{"pk": 3, "model": "auth.group", "fields": {"name": "GROUP2", "permissions": []}},
{"pk": 1, "model": "auth.user", "fields": {"username": "localhost", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2015-09-21T10:29:58", "groups": [["QA"]], "user_permissions": [], "password": "pbkdf2_sha256$12000$v4L5uJ9LnwLW$cmEJ+98ncYMOJunbGyRkUFvGZe8fg1xSQZDrkI2wuys=", "email": "t@d.com", "date_joined": "2015-09-21T10:29:58"}},
{"pk": 1, "model": "management.resourcedata", "fields": {"reserved": "", "name": "available_resource1", "dirty": false, "owner": "", "group": 1}},
{"pk": 1, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.1"}},
{"pk": 2, "model": "management.resourcedata", "fields": {"reserved": "", "name": "available_resource2", "dirty": false, "owner": "", "group": 1}},
{"pk": 2, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 2, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.1"}},
{"pk": 3, "model": "management.resourcedata", "fields": {"reserved": "", "name": "locked_resource1", "dirty": false, "owner": "user1", "group": 1}},
{"pk": 3, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 3, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.1"}},
{"pk": 4, "model": "management.resourcedata", "fields": {"reserved": "", "name": "locked_resource2", "dirty": false, "owner": "user2", "group": 1}},
{"pk": 4, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 4, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.1"}},
{"pk": 5, "model": "management.resourcedata", "fields": {"reserved": "", "name": "complex_resource1", "dirty": false, "owner": "", "group": 1}},
{"pk": 5, "model": "management.democomplexresourcedata", "fields": {"demo2": 2, "validate_flag": null, "demo1": 1, "reset_flag": false, "initialization_flag": false}},
{"pk": 6, "model": "management.resourcedata", "fields": {"reserved": "", "name": "fail_initialize_resource", "dirty": false, "owner": "", "group": 1}},
{"pk": 6, "model": "management.demoresourcedata", "fields": {"fails_on_initialize": true, "initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.2"}},
{"pk": 7, "model": "management.resourcedata", "fields": {"reserved": "", "name": "fail_finalize_resource", "dirty": false, "owner": "", "group": 1}},
{"pk": 7, "model": "management.demoresourcedata", "fields": {"fails_on_finalize": true, "initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.2"}},
{"pk": 8, "model": "management.resourcedata", "fields": {"reserved": "", "name": "other_group_resource", "dirty": false, "owner": "", "group": 2}},
{"pk": 8, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.3"}},
{"pk": 9, "model": "management.resourcedata", "fields": {"reserved": "", "name": "resource_with_no_group", "dirty": false, "owner": "", "group": null}},
{"pk": 9, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": null, "ip_address": "1.1.1.4"}}]
{"pk": 1, "model": "management.resourcedata", "fields": {"reserved": "", "name": "available_resource1", "owner": "", "group": 1}},
{"pk": 1, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.1"}},
{"pk": 2, "model": "management.resourcedata", "fields": {"reserved": "", "name": "available_resource2", "owner": "", "group": 1}},
{"pk": 2, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 2, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.1"}},
{"pk": 3, "model": "management.resourcedata", "fields": {"reserved": "", "name": "locked_resource1", "owner": "user1", "group": 1}},
{"pk": 3, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 3, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.1"}},
{"pk": 4, "model": "management.resourcedata", "fields": {"reserved": "", "name": "locked_resource2", "owner": "user2", "group": 1}},
{"pk": 4, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 4, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.1"}},
{"pk": 5, "model": "management.resourcedata", "fields": {"reserved": "", "name": "complex_resource1", "owner": "", "group": 1}},
{"pk": 5, "model": "management.democomplexresourcedata", "fields": {"demo2": 2, "validate_flag": false, "demo1": 1, "reset_flag": false, "initialization_flag": false}},
{"pk": 6, "model": "management.resourcedata", "fields": {"reserved": "", "name": "fail_initialize_resource", "owner": "", "group": 1}},
{"pk": 6, "model": "management.demoresourcedata", "fields": {"fails_on_initialize": true, "initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.2"}},
{"pk": 7, "model": "management.resourcedata", "fields": {"reserved": "", "name": "fail_finalize_resource", "owner": "", "group": 1}},
{"pk": 7, "model": "management.demoresourcedata", "fields": {"fails_on_finalize": true, "initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.2"}},
{"pk": 8, "model": "management.resourcedata", "fields": {"reserved": "", "name": "other_group_resource", "owner": "", "group": 2}},
{"pk": 8, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.3"}},
{"pk": 9, "model": "management.resourcedata", "fields": {"reserved": "", "name": "resource_with_no_group", "owner": "", "group": null}},
{"pk": 9, "model": "management.demoresourcedata", "fields": {"initialization_flag": false, "reset_flag": false, "version": 1, "mode": 0, "validate_flag": false, "ip_address": "1.1.1.4"}}]
2 changes: 0 additions & 2 deletions src/rotest/common/django_utils/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Django definitions for the administrator site urls."""
import django
from django.contrib import admin
from django.conf.urls import patterns, include, url


django.setup()
admin.autodiscover()
urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)))
4 changes: 2 additions & 2 deletions src/rotest/common/django_utils/ut_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@
win32file._setmaxstdio(2048)

except ImportError:
core_log.warning("Cannot find package 'win32file'. Install it using "
"'pip install pypiwin32'")
raise RuntimeError("Cannot find package 'win32file'. Install it using "
"'pip install pypiwin32'")
220 changes: 220 additions & 0 deletions src/rotest/core/abstract_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
"""Describe TestBlock class."""
# pylint: disable=attribute-defined-outside-init,unused-argument
# pylint: disable=too-many-arguments,too-many-locals,broad-except
# pylint: disable=dangerous-default-value,access-member-before-definition
# pylint: disable=bare-except,protected-access,too-many-instance-attributes
import unittest
from bdb import BdbQuit
from itertools import count

from ipdbugger import debug
from attrdict import AttrDict

from rotest.common.config import ROTEST_WORK_DIR
from rotest.management.client.manager import ResourceRequest
from rotest.management.client.manager import ClientResourceManager


request = ResourceRequest


class AbstractTest(unittest.TestCase):
"""Base class for all runnable Rotest tests.
Attributes:
resources (tuple): list of the required resources. each item is a
tuple of (resource_name, resource type, parameters dictionary),
you can use :func:`rotest.core..request` to create the tuple.
identifier (number): unique id of the test.
data (rotest.core.models._data.Data): contain information
about a test run.
logger (logging.Logger): test logger.
save_state (bool): a flag to determine if storing the states of
resources is required.
force_initialize (bool): a flag to determine if the resources will be
initialized even if their validation succeeds.
config (AttrDict): dictionary of configurations.
enable_debug (bool): whether to enable entering ipdb debugging mode
upon any exception in a test statement.
skip_init (bool): True to skip resources initialize and validation.
resource_manager (ClientResourceManager): client resource manager.
TAGS (list): list of tags by which the test may be filtered.
IS_COMPLEX (bool): if this test is complex (may contain sub-tests).
TIMEOUT (number): timeout for flow run, None means no timeout.
"""
SETUP_METHOD_NAME = 'setUp'
TEARDOWN_METHOD_NAME = 'tearDown'

TIMEOUT = 1800 # 30 minutes
SETUP_METHOD_NAME = 'setUp'
TEARDOWN_METHOD_NAME = 'tearDown'

resources = ()

TAGS = []
IS_COMPLEX = False

def __init__(self, indexer=count(), methodName='runTest',
base_work_dir=ROTEST_WORK_DIR, save_state=True,
force_initialize=False, config=None, parent=None,
run_data=None, enable_debug=True, resource_manager=None,
skip_init=False):

if enable_debug is True:
for method_name in (methodName, self.SETUP_METHOD_NAME,
self.TEARDOWN_METHOD_NAME):

debug(getattr(self, method_name),
ignore_exceptions=[KeyboardInterrupt,
unittest.SkipTest,
BdbQuit])

super(AbstractTest, self).__init__(methodName)

self._tags = None
self.result = None
self.config = config
self.parent = parent
self.skip_init = skip_init
self.save_state = save_state
self.identifier = indexer.next()
self.enable_debug = enable_debug
self.force_initialize = force_initialize
self.parents_count = self._get_parents_count()

self.all_resources = AttrDict()
self.locked_resources = AttrDict()

self._is_client_local = False
self.resource_manager = resource_manager

def create_resource_manager(self):
"""Create a new resource manager client instance.
Returns:
ClientResourceManager. new resource manager client.
"""
return ClientResourceManager(logger=self.logger)

def expect(self, expression, msg=None):
"""Check an expression and fail the test at the end if it's False.
This does not raise an AssertionError like assertTrue, but instead
updates the result of the test and appends the message to the saved
traceback without stopping its flow.
Args:
expression (bool): value to validate.
msg (str): failure message if the expression is False.
Returns:
bool. True if the validation passed, False otherwise.
"""
if expression is False:
failure = AssertionError(msg)
self.result.addFailure(self, (failure.__class__, failure, None))
return False

return True

def add_resources(self, resources):
"""Register the resources to the case and set them as its attributes.
Args:
resources (dict): dictionary of attributes name to resources
instance.
"""
self.all_resources.update(resources)
for name, resource in resources.iteritems():
setattr(self, name, resource)

def request_resources(self, resources_to_request, use_previous=False,
is_global=False):
"""Lock the requested resources and prepare them for the test.
Lock the required resources using the resource manager, then assign
each resource to its requested name, and update the result of the
chosen resources. This method can also be used to add resources to all
the sibling blocks under the test-flow.
Args:
resources_to_request (list): list of resource requests to lock.
use_previous (bool): whether to use previously locked resources and
release the unused ones.
is_global (bool): whether to inject the resources to the parent and
sibling components or not.
"""
if len(resources_to_request) == 0:
# No resources to requested
return

requested_resources = self.resource_manager.request_resources(
config=self.config,
skip_init=self.skip_init,
use_previous=use_previous,
save_state=self.save_state,
base_work_dir=self.work_dir,
requests=resources_to_request,
force_initialize=self.force_initialize)

self.add_resources(requested_resources)
self.locked_resources.update(requested_resources)

if self.result is not None:
self.result.updateResources(self)

def release_resources(self, resources=None, dirty=False,
force_release=True):
"""Release given resources using the client.
Args:
resources (list): resource names to release, leave None to release
all locked resources.
dirty (bool): True if the resource's integrity has been
compromised, and it should be re-validated.
force_release (bool): whether to always release to resources
or enable saving them for next tests.
"""
if resources is None:
resources = self.locked_resources.keys()

if len(resources) == 0:
# No resources to release locked
return

resources_dict = {name: resource
for name, resource in self.locked_resources.items()
if name in resources}

self.resource_manager.release_resources(resources_dict,
dirty=dirty,
force_release=force_release)

# Remove the resources from the test's resource to avoid double release
for key in resources:
self.locked_resources.pop(key, None)

def _get_parents_count(self):
"""Get the number of ancestors.
Returns:
number. number of ancestors.
"""
if self.parent is None:
return 0

return self.parent.parents_count + 1

def start(self):
"""Update the data that the test started."""
self.data.start()

def end(self, test_outcome, details=None):
"""Update the data that the test ended.
Args:
test_outcome (number): test outcome code (as defined in
rotest.core.models.case_data.TestOutcome).
details (str): details of the result (traceback/skip reason).
"""
self.data.update_result(test_outcome, details)

0 comments on commit f372ec6

Please sign in to comment.