wrappers.py revision 12882
11761SN/A# Copyright (c) 2017 Mark D. Hill and David A. Wood
22SN/A# All rights reserved.
32SN/A#
42SN/A# Redistribution and use in source and binary forms, with or without
52SN/A# modification, are permitted provided that the following conditions are
62SN/A# met: redistributions of source code must retain the above copyright
72SN/A# notice, this list of conditions and the following disclaimer;
82SN/A# redistributions in binary form must reproduce the above copyright
92SN/A# notice, this list of conditions and the following disclaimer in the
102SN/A# documentation and/or other materials provided with the distribution;
112SN/A# neither the name of the copyright holders nor the names of its
122SN/A# contributors may be used to endorse or promote products derived from
132SN/A# this software without specific prior written permission.
142SN/A#
152SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262665Ssaidi@eecs.umich.edu#
272665Ssaidi@eecs.umich.edu# Authors: Sean Wilson
282SN/A
292SN/A'''
302SN/AModule contains wrappers for test items that have been
312SN/Aloaded by the testlib :class:`testlib.loader.Loader`.
322SN/A'''
33705SN/Aimport itertools
342SN/A
352SN/Aimport log
362SN/Aimport uid
376661Snate@binkert.orgfrom state import Status, Result
382SN/A
396661Snate@binkert.orgclass TestCaseMetadata():
406661Snate@binkert.org    def __init__(self, name, uid, path, result, status, suite_uid):
416661Snate@binkert.org        self.name = name
426661Snate@binkert.org        self.uid = uid
432SN/A        self.path = path
446661Snate@binkert.org        self.status = status
456661Snate@binkert.org        self.result = result
466661Snate@binkert.org        self.suite_uid = suite_uid
476661Snate@binkert.org
486661Snate@binkert.org
496661Snate@binkert.orgclass TestSuiteMetadata():
506661Snate@binkert.org    def __init__(self, name, uid, tags, path, status, result):
516661Snate@binkert.org        self.name = name
526661Snate@binkert.org        self.uid = uid
536661Snate@binkert.org        self.tags = tags
546661Snate@binkert.org        self.path = path
556661Snate@binkert.org        self.status = status
566661Snate@binkert.org        self.result = result
576661Snate@binkert.org
586661Snate@binkert.org
596661Snate@binkert.orgclass LibraryMetadata():
606661Snate@binkert.org    def __init__(self, name, result, status):
616661Snate@binkert.org        self.name = name
626661Snate@binkert.org        self.result = result
636661Snate@binkert.org        self.status = status
646661Snate@binkert.org
656661Snate@binkert.org
666661Snate@binkert.orgclass LoadedTestable(object):
676661Snate@binkert.org    '''
686661Snate@binkert.org    Base class for loaded test items.
696661Snate@binkert.org
706661Snate@binkert.org    :property:`result` and :property:`status` setters
716661Snate@binkert.org    notify testlib via the :func:`log_result` and :func:`log_status`
726661Snate@binkert.org    of the updated status.
736661Snate@binkert.org    '''
746661Snate@binkert.org    def __init__(self, obj):
756661Snate@binkert.org        self.obj = obj
766661Snate@binkert.org        self.metadata = self._generate_metadata()
776661Snate@binkert.org
786661Snate@binkert.org    @property
796661Snate@binkert.org    def status(self):
806661Snate@binkert.org        return self.metadata.status
816661Snate@binkert.org
826661Snate@binkert.org    @status.setter
836661Snate@binkert.org    def status(self, status):
846661Snate@binkert.org        self.log_status(status)
856661Snate@binkert.org        self.metadata.status = status
866661Snate@binkert.org
876661Snate@binkert.org    @property
886661Snate@binkert.org    def result(self):
896661Snate@binkert.org        return self.metadata.result
906661Snate@binkert.org
916661Snate@binkert.org    @result.setter
926661Snate@binkert.org    def result(self, result):
936661Snate@binkert.org        self.log_result(result)
946661Snate@binkert.org        self.metadata.result = result
956661Snate@binkert.org
966661Snate@binkert.org    @property
976661Snate@binkert.org    def uid(self):
986661Snate@binkert.org        return self.metadata.uid
996661Snate@binkert.org
1002SN/A    @property
1012SN/A    def name(self):
1026661Snate@binkert.org        return self.metadata.name
1036661Snate@binkert.org
1046661Snate@binkert.org    @property
1056661Snate@binkert.org    def fixtures(self):
1066661Snate@binkert.org        return self.obj.fixtures
1076661Snate@binkert.org
1086661Snate@binkert.org    @fixtures.setter
1096661Snate@binkert.org    def fixtures(self, fixtures):
1106661Snate@binkert.org        self.obj.fixtures = fixtures
1116661Snate@binkert.org
1126661Snate@binkert.org    @property
1136661Snate@binkert.org    def runner(self):
1146661Snate@binkert.org        return self.obj.runner
1156661Snate@binkert.org
1166661Snate@binkert.org    # TODO Change log to provide status_update, result_update for all types.
1176661Snate@binkert.org    def log_status(self, status):
1182SN/A        log.test_log.status_update(self, status)
1196661Snate@binkert.org
1206661Snate@binkert.org    def log_result(self, result):
1216661Snate@binkert.org        log.test_log.result_update(self, result)
1226661Snate@binkert.org
1232SN/A    def __iter__(self):
1246661Snate@binkert.org        return iter(())
1256661Snate@binkert.org
1266661Snate@binkert.org
1276661Snate@binkert.orgclass LoadedTest(LoadedTestable):
1282SN/A    def __init__(self, test_obj, loaded_suite, path):
1296661Snate@binkert.org        self.parent_suite = loaded_suite
1306661Snate@binkert.org        self._path = path
1316866Snate@binkert.org        LoadedTestable.__init__(self, test_obj)
1326661Snate@binkert.org
1336661Snate@binkert.org    def test(self, *args, **kwargs):
1346661Snate@binkert.org        self.obj.test(*args, **kwargs)
1356661Snate@binkert.org
1366661Snate@binkert.org    def _generate_metadata(self):
1376661Snate@binkert.org        return TestCaseMetadata( **{
1382SN/A            'name':self.obj.name,
1396661Snate@binkert.org            'path': self._path,
1406661Snate@binkert.org            'uid': uid.TestUID(self._path,
1416661Snate@binkert.org                               self.obj.name,
1426661Snate@binkert.org                               self.parent_suite.name),
1436661Snate@binkert.org            'status': Status.Unscheduled,
1446661Snate@binkert.org            'result': Result(Result.NotRun),
1456661Snate@binkert.org            'suite_uid': self.parent_suite.metadata.uid
1466661Snate@binkert.org        })
1472SN/A
1482023SN/A
1496661Snate@binkert.orgclass LoadedSuite(LoadedTestable):
1506661Snate@binkert.org    def __init__(self, suite_obj, path):
1516661Snate@binkert.org        self._path = path
1526661Snate@binkert.org        LoadedTestable.__init__(self, suite_obj)
1536661Snate@binkert.org        self.tests = self._wrap_children(suite_obj)
1546661Snate@binkert.org
1556661Snate@binkert.org    def _wrap_children(self, suite_obj):
1566661Snate@binkert.org        return [LoadedTest(test, self, self.metadata.path)
1572023SN/A                for test in suite_obj]
1586661Snate@binkert.org
1596661Snate@binkert.org    def _generate_metadata(self):
1606661Snate@binkert.org        return TestSuiteMetadata( **{
1616661Snate@binkert.org            'name': self.obj.name,
1622SN/A            'tags':self.obj.tags,
1636661Snate@binkert.org            'path': self._path,
1646661Snate@binkert.org            'uid': uid.SuiteUID(self._path, self.obj.name),
1656661Snate@binkert.org            'status': Status.Unscheduled,
1666661Snate@binkert.org            'result': Result(Result.NotRun)
1672SN/A        })
1686661Snate@binkert.org
1696661Snate@binkert.org    def __iter__(self):
1706661Snate@binkert.org        return iter(self.tests)
1712SN/A
1726661Snate@binkert.org    @property
1736661Snate@binkert.org    def tags(self):
1746661Snate@binkert.org        return self.metadata.tags
1756661Snate@binkert.org
1762SN/A
1776661Snate@binkert.orgclass LoadedLibrary(LoadedTestable):
1786661Snate@binkert.org    '''
1796661Snate@binkert.org    Wraps a collection of all loaded test suites and
1806661Snate@binkert.org    provides utility functions for accessing fixtures.
1812SN/A    '''
1826661Snate@binkert.org    def __init__(self, suites, global_fixtures):
1836661Snate@binkert.org        LoadedTestable.__init__(self, suites)
1846661Snate@binkert.org        self.global_fixtures = global_fixtures
1852SN/A
1866661Snate@binkert.org    def _generate_metadata(self):
1876661Snate@binkert.org        return LibraryMetadata( **{
1882SN/A            'name': 'Test Library',
1896661Snate@binkert.org            'status': Status.Unscheduled,
1906661Snate@binkert.org            'result': Result(Result.NotRun)
1916661Snate@binkert.org        })
1926661Snate@binkert.org
1932SN/A    def __iter__(self):
1946661Snate@binkert.org        '''
1956661Snate@binkert.org        :returns: an iterator over contained :class:`TestSuite` objects.
1966661Snate@binkert.org        '''
1976661Snate@binkert.org        return iter(self.obj)
1986661Snate@binkert.org
1996661Snate@binkert.org    def all_fixture_tuples(self):
2006661Snate@binkert.org        return itertools.chain(
2016661Snate@binkert.org                self.global_fixtures,
2026661Snate@binkert.org                *(suite.fixtures for suite in self.obj))
2036661Snate@binkert.org
2046661Snate@binkert.org    def all_fixtures(self):
2056661Snate@binkert.org        '''
2066661Snate@binkert.org        :returns: an interator overall all global, suite,
2076661Snate@binkert.org          and test fixtures
2086661Snate@binkert.org        '''
2092SN/A        return itertools.chain(itertools.chain(
2106661Snate@binkert.org                self.global_fixtures,
2116661Snate@binkert.org                *(suite.fixtures for suite in self.obj)),
2126661Snate@binkert.org            *(self.test_fixtures(suite) for suite in self.obj)
2136661Snate@binkert.org        )
2146661Snate@binkert.org
2156661Snate@binkert.org    def test_fixtures(self, suite):
2166661Snate@binkert.org        '''
2176661Snate@binkert.org        :returns: an interator over all fixtures of each
2186661Snate@binkert.org          test contained in the given suite
2196661Snate@binkert.org        '''
2206661Snate@binkert.org        return itertools.chain(*(test.fixtures for test in suite))
2216661Snate@binkert.org
2226661Snate@binkert.org    @property
2236661Snate@binkert.org    def fixtures(self):
2242107SN/A        return self.global_fixtures
2252227SN/A
2262SN/A    @property
2272SN/A    def uid(self):
228715SN/A        return self.name
2296661Snate@binkert.org
2306661Snate@binkert.org    @property
2316661Snate@binkert.org    def suites(self):
2326661Snate@binkert.org        return self.obj
2336661Snate@binkert.org
2342SN/A    @suites.setter
2356661Snate@binkert.org    def suites(self, suites):
2366661Snate@binkert.org        self.obj = suites
2376661Snate@binkert.org