Skip to content

Instantly share code, notes, and snippets.

@michaelmontgomery19
Last active June 9, 2016 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save michaelmontgomery19/34efaf45172aeb9cbd8f67afee28870f to your computer and use it in GitHub Desktop.
Save michaelmontgomery19/34efaf45172aeb9cbd8f67afee28870f to your computer and use it in GitHub Desktop.
Executable Test Plan
#!/usr/bin/env python
""" Holds logic for TestReporter objects """
__author__ = "Mike 'Monty' Montgomery"
__copyright__ = "Copyright 2015, ArcherDX"
__credits__ = ["Mike 'Monty' Montgomery, Jody 'JodyStephens' Stephens"]
__license__ = "To Scribe"
__version__ = "0.1"
__maintainer__ = "Mike 'Monty' Montgomery"
__email__ = "mmontgomery@archerd.com"
__status__ = "Development"
import logging
from server_management.test_report.test_object import TestObject
logger = logging.getLogger(__name__)
class TestReporter(object):
"""
Logic for TestReporter
Must:
- instantiate from $TEST_PLAN_TEMPLATE.tpt
- acquire list of test names from .tpt
- accept list of tags by which tests may be filtered
"""
def __init__(self, tests=None, tags=None):
"""
:param [str] tests: Iterable of tests TestReporter may filter or otherwise act on
:param {str} tags: test tags such as "SMOKE", "VARIANT", "IN_SILICO" used to subset tests
"""
self.tags = tags
self.tests = tests
# instantiate and collect test_objects which have knowledge of their own tags
self.test_objects = []
for test in tests:
self.test_objects.append(TestObject(test))
@classmethod
def fromTemplate(cls, template):
"""
Instantiate TestReporter from Test Plan Template (.mdt) file
:param str template: Test Plan Template file name
"""
with open(template, 'r') as fh:
cls._fromTemplate(fh)
@classmethod
def _fromTemplate(cls, file_handle):
"""
Instantiate TestReporter from str iterable, such as open file handle
:param iter file_handle: string iterable from which TestReporter will glean list of test references
"""
tests = cls._getTests(file_handle)
return TestReporter(tests=tests)
@classmethod
def _getTests(cls, file_handle):
"""
Parse string iterable and return list of tests. Tests are recognized by surrounding brackets
:param file_handle:
:return [str]:
"""
tests = []
for line in file_handle:
tests.append(cls._getTest(line))
return tests
@classmethod
def _getTest(cls, line):
"""
Parse a single line. If line starts and ends with brackets, assume what's inside is a test and return that
:param str line:
:return str or None:
"""
line = line.strip() # ignore leading / trailing whitespace
if line.startswith('[') and line.endswith(']'):
return line[1:-1]
else:
return None
def testsToRun(self):
"""
Wrapper-method
:return: multi-line string of tests to be run by arcus
"""
test_list = self._testsToRun()
return '\n'.join(test_list)
def _testsToRun(self):
"""
Utilize self.tags (if any) to return only those tests
:return [str]: list of tests to be run by arcus
"""
if self.tags:
return self.filterByTag()
else:
return self.tests
def filterByTag(self):
"""
Query TestObjects tags
:return:
"""
filtered_tests = []
for test_object in self.test_objects:
shared_tags = self.tags & test_object.tags
if shared_tags:
filtered_tests.append(test_object.name)
return filtered_tests
#!/usr/bin/env python
""" Holds logic for TestObject objects """
__author__ = "Mike 'Monty' Montgomery"
__copyright__ = "Copyright 2015, ArcherDX"
__credits__ = ["Mike 'Monty' Montgomery, Jody 'JodyStephens' Stephens"]
__license__ = "To Thrive"
__version__ = "0.1"
__maintainer__ = "Mike 'Monty' Montgomery"
__email__ = "mmontgomery@archerd.com"
__status__ = "Development"
import os
import logging
from nose.tools import nottest
LOCAL_TESTS = '/var/www/archer/system_test/analysis'
ARCUS_HOARD = '/45drives'
ARCUS_CONFIG = 'config.py'
logger = logging.getLogger(__name__)
@nottest
class TestObject(object):
"""
Abstract of a test
Must:
- instantiate from name of test or raise Exception if name of test cannot be found in arcus hoard
- collect list of tags from arcus config.py in test directory
"""
def __str__(self):
"""
Returns name of test as it would appear as an argument to an 'arcus runpanel' command
"""
return self.name
def __repr__(self):
"""
Returns python code to instantiate this TestObject
"""
return 'server_management.test_report.test_object.TestObject({})'.format(self.name)
def __init__(self, name, config=None):
"""
:param str name: Name of test as it would appear in an `arcus runpanel $NAME` command
"""
self.name = name
if not config:
self.config = self.getConfig()
# look within self.arcus_config for tags attr of CONFIG.metadata
self.tags = self.getTags(self.config)
def getConfig(self):
"""
Returns arcus `config.py` file if it can be found. Otherwise raises IOError
:return str: valid file path to arcus `config.py` file
"""
local_config = os.path.join(LOCAL_TESTS, self.name, ARCUS_CONFIG)
hoard_config = os.path.join(ARCUS_HOARD, self.name, ARCUS_CONFIG)
if os.path.isfile(local_config):
return local_config
elif os.path.isfile(hoard_config):
return hoard_config
else:
message = "Could not find arcus config for test: {} in either {}, or {}".format(
self.name, LOCAL_TESTS, ARCUS_HOARD,)
raise IOError(message)
def getTags(self, config_file):
"""
Collects tags from CONFIG.metadata.tags, if they are present. If not, returns empty list
:return [str] or []:
"""
tags = set()
arcus_objects = {} # will acquire CONFIG, an arcus Orders object
exec(open(config_file).read(), arcus_objects) # read in python from self.config & populate arcus_objects
config = arcus_objects['CONFIG']
try:
tags = config.metadata.tags
if not tags:
tags = set()
except AttributeError as e:
message = 'Did not find any tags for test {}. Tags go in config.metadata.tags'.format(self.name)
logger.warning(message)
if isinstance(tags, list): # protect in case tags were given as list instead of set
tags = set(tags)
return tags
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment