114141Snikos.nikoleris@arm.com# Copyright (c) 2019 ARM Limited
214141Snikos.nikoleris@arm.com# All rights reserved
314141Snikos.nikoleris@arm.com#
414141Snikos.nikoleris@arm.com# The license below extends only to copyright in the software and shall
514141Snikos.nikoleris@arm.com# not be construed as granting a license to any other intellectual
614141Snikos.nikoleris@arm.com# property including but not limited to intellectual property relating
714141Snikos.nikoleris@arm.com# to a hardware implementation of the functionality of the software
814141Snikos.nikoleris@arm.com# licensed hereunder.  You may use the software subject to the license
914141Snikos.nikoleris@arm.com# terms below provided that you ensure that this notice is replicated
1014141Snikos.nikoleris@arm.com# unmodified and in its entirety in all distributions of the software,
1114141Snikos.nikoleris@arm.com# modified or unmodified, in source code or in binary form.
1214141Snikos.nikoleris@arm.com#
1312882Sspwilson2@wisc.edu# Copyright (c) 2017 Mark D. Hill and David A. Wood
1412882Sspwilson2@wisc.edu# All rights reserved.
1512882Sspwilson2@wisc.edu#
1612882Sspwilson2@wisc.edu# Redistribution and use in source and binary forms, with or without
1712882Sspwilson2@wisc.edu# modification, are permitted provided that the following conditions are
1812882Sspwilson2@wisc.edu# met: redistributions of source code must retain the above copyright
1912882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer;
2012882Sspwilson2@wisc.edu# redistributions in binary form must reproduce the above copyright
2112882Sspwilson2@wisc.edu# notice, this list of conditions and the following disclaimer in the
2212882Sspwilson2@wisc.edu# documentation and/or other materials provided with the distribution;
2312882Sspwilson2@wisc.edu# neither the name of the copyright holders nor the names of its
2412882Sspwilson2@wisc.edu# contributors may be used to endorse or promote products derived from
2512882Sspwilson2@wisc.edu# this software without specific prior written permission.
2612882Sspwilson2@wisc.edu#
2712882Sspwilson2@wisc.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2812882Sspwilson2@wisc.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2912882Sspwilson2@wisc.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3012882Sspwilson2@wisc.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3112882Sspwilson2@wisc.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3212882Sspwilson2@wisc.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3312882Sspwilson2@wisc.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3412882Sspwilson2@wisc.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3512882Sspwilson2@wisc.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3612882Sspwilson2@wisc.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3712882Sspwilson2@wisc.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3812882Sspwilson2@wisc.edu#
3912882Sspwilson2@wisc.edu# Authors: Sean Wilson
4012882Sspwilson2@wisc.edu
4112882Sspwilson2@wisc.edu'''
4212882Sspwilson2@wisc.eduModule contains wrappers for test items that have been
4312882Sspwilson2@wisc.eduloaded by the testlib :class:`testlib.loader.Loader`.
4412882Sspwilson2@wisc.edu'''
4512882Sspwilson2@wisc.eduimport itertools
4612882Sspwilson2@wisc.edu
4712882Sspwilson2@wisc.eduimport log
4812882Sspwilson2@wisc.eduimport uid
4912882Sspwilson2@wisc.edufrom state import Status, Result
5012882Sspwilson2@wisc.edu
5112882Sspwilson2@wisc.educlass TestCaseMetadata():
5212882Sspwilson2@wisc.edu    def __init__(self, name, uid, path, result, status, suite_uid):
5312882Sspwilson2@wisc.edu        self.name = name
5412882Sspwilson2@wisc.edu        self.uid = uid
5512882Sspwilson2@wisc.edu        self.path = path
5612882Sspwilson2@wisc.edu        self.status = status
5712882Sspwilson2@wisc.edu        self.result = result
5812882Sspwilson2@wisc.edu        self.suite_uid = suite_uid
5912882Sspwilson2@wisc.edu
6012882Sspwilson2@wisc.edu
6112882Sspwilson2@wisc.educlass TestSuiteMetadata():
6212882Sspwilson2@wisc.edu    def __init__(self, name, uid, tags, path, status, result):
6312882Sspwilson2@wisc.edu        self.name = name
6412882Sspwilson2@wisc.edu        self.uid = uid
6512882Sspwilson2@wisc.edu        self.tags = tags
6612882Sspwilson2@wisc.edu        self.path = path
6712882Sspwilson2@wisc.edu        self.status = status
6812882Sspwilson2@wisc.edu        self.result = result
6912882Sspwilson2@wisc.edu
7012882Sspwilson2@wisc.edu
7112882Sspwilson2@wisc.educlass LibraryMetadata():
7212882Sspwilson2@wisc.edu    def __init__(self, name, result, status):
7312882Sspwilson2@wisc.edu        self.name = name
7412882Sspwilson2@wisc.edu        self.result = result
7512882Sspwilson2@wisc.edu        self.status = status
7612882Sspwilson2@wisc.edu
7712882Sspwilson2@wisc.edu
7812882Sspwilson2@wisc.educlass LoadedTestable(object):
7912882Sspwilson2@wisc.edu    '''
8012882Sspwilson2@wisc.edu    Base class for loaded test items.
8112882Sspwilson2@wisc.edu
8212882Sspwilson2@wisc.edu    :property:`result` and :property:`status` setters
8312882Sspwilson2@wisc.edu    notify testlib via the :func:`log_result` and :func:`log_status`
8412882Sspwilson2@wisc.edu    of the updated status.
8512882Sspwilson2@wisc.edu    '''
8612882Sspwilson2@wisc.edu    def __init__(self, obj):
8712882Sspwilson2@wisc.edu        self.obj = obj
8812882Sspwilson2@wisc.edu        self.metadata = self._generate_metadata()
8912882Sspwilson2@wisc.edu
9012882Sspwilson2@wisc.edu    @property
9112882Sspwilson2@wisc.edu    def status(self):
9212882Sspwilson2@wisc.edu        return self.metadata.status
9312882Sspwilson2@wisc.edu
9412882Sspwilson2@wisc.edu    @status.setter
9512882Sspwilson2@wisc.edu    def status(self, status):
9612882Sspwilson2@wisc.edu        self.log_status(status)
9712882Sspwilson2@wisc.edu        self.metadata.status = status
9812882Sspwilson2@wisc.edu
9912882Sspwilson2@wisc.edu    @property
10012882Sspwilson2@wisc.edu    def result(self):
10112882Sspwilson2@wisc.edu        return self.metadata.result
10212882Sspwilson2@wisc.edu
10312882Sspwilson2@wisc.edu    @result.setter
10412882Sspwilson2@wisc.edu    def result(self, result):
10512882Sspwilson2@wisc.edu        self.log_result(result)
10612882Sspwilson2@wisc.edu        self.metadata.result = result
10712882Sspwilson2@wisc.edu
10812882Sspwilson2@wisc.edu    @property
10912882Sspwilson2@wisc.edu    def uid(self):
11012882Sspwilson2@wisc.edu        return self.metadata.uid
11112882Sspwilson2@wisc.edu
11212882Sspwilson2@wisc.edu    @property
11312882Sspwilson2@wisc.edu    def name(self):
11412882Sspwilson2@wisc.edu        return self.metadata.name
11512882Sspwilson2@wisc.edu
11612882Sspwilson2@wisc.edu    @property
11712882Sspwilson2@wisc.edu    def fixtures(self):
11812882Sspwilson2@wisc.edu        return self.obj.fixtures
11912882Sspwilson2@wisc.edu
12012882Sspwilson2@wisc.edu    @fixtures.setter
12112882Sspwilson2@wisc.edu    def fixtures(self, fixtures):
12212882Sspwilson2@wisc.edu        self.obj.fixtures = fixtures
12312882Sspwilson2@wisc.edu
12412882Sspwilson2@wisc.edu    @property
12512882Sspwilson2@wisc.edu    def runner(self):
12612882Sspwilson2@wisc.edu        return self.obj.runner
12712882Sspwilson2@wisc.edu
12812882Sspwilson2@wisc.edu    # TODO Change log to provide status_update, result_update for all types.
12912882Sspwilson2@wisc.edu    def log_status(self, status):
13012882Sspwilson2@wisc.edu        log.test_log.status_update(self, status)
13112882Sspwilson2@wisc.edu
13212882Sspwilson2@wisc.edu    def log_result(self, result):
13312882Sspwilson2@wisc.edu        log.test_log.result_update(self, result)
13412882Sspwilson2@wisc.edu
13512882Sspwilson2@wisc.edu    def __iter__(self):
13612882Sspwilson2@wisc.edu        return iter(())
13712882Sspwilson2@wisc.edu
13812882Sspwilson2@wisc.edu
13912882Sspwilson2@wisc.educlass LoadedTest(LoadedTestable):
14012882Sspwilson2@wisc.edu    def __init__(self, test_obj, loaded_suite, path):
14112882Sspwilson2@wisc.edu        self.parent_suite = loaded_suite
14212882Sspwilson2@wisc.edu        self._path = path
14312882Sspwilson2@wisc.edu        LoadedTestable.__init__(self, test_obj)
14412882Sspwilson2@wisc.edu
14512882Sspwilson2@wisc.edu    def test(self, *args, **kwargs):
14612882Sspwilson2@wisc.edu        self.obj.test(*args, **kwargs)
14712882Sspwilson2@wisc.edu
14812882Sspwilson2@wisc.edu    def _generate_metadata(self):
14912882Sspwilson2@wisc.edu        return TestCaseMetadata( **{
15012882Sspwilson2@wisc.edu            'name':self.obj.name,
15112882Sspwilson2@wisc.edu            'path': self._path,
15212882Sspwilson2@wisc.edu            'uid': uid.TestUID(self._path,
15312882Sspwilson2@wisc.edu                               self.obj.name,
15412882Sspwilson2@wisc.edu                               self.parent_suite.name),
15512882Sspwilson2@wisc.edu            'status': Status.Unscheduled,
15612882Sspwilson2@wisc.edu            'result': Result(Result.NotRun),
15712882Sspwilson2@wisc.edu            'suite_uid': self.parent_suite.metadata.uid
15812882Sspwilson2@wisc.edu        })
15912882Sspwilson2@wisc.edu
16012882Sspwilson2@wisc.edu
16112882Sspwilson2@wisc.educlass LoadedSuite(LoadedTestable):
16212882Sspwilson2@wisc.edu    def __init__(self, suite_obj, path):
16312882Sspwilson2@wisc.edu        self._path = path
16412882Sspwilson2@wisc.edu        LoadedTestable.__init__(self, suite_obj)
16512882Sspwilson2@wisc.edu        self.tests = self._wrap_children(suite_obj)
16612882Sspwilson2@wisc.edu
16712882Sspwilson2@wisc.edu    def _wrap_children(self, suite_obj):
16812882Sspwilson2@wisc.edu        return [LoadedTest(test, self, self.metadata.path)
16912882Sspwilson2@wisc.edu                for test in suite_obj]
17012882Sspwilson2@wisc.edu
17112882Sspwilson2@wisc.edu    def _generate_metadata(self):
17212882Sspwilson2@wisc.edu        return TestSuiteMetadata( **{
17312882Sspwilson2@wisc.edu            'name': self.obj.name,
17412882Sspwilson2@wisc.edu            'tags':self.obj.tags,
17512882Sspwilson2@wisc.edu            'path': self._path,
17612882Sspwilson2@wisc.edu            'uid': uid.SuiteUID(self._path, self.obj.name),
17712882Sspwilson2@wisc.edu            'status': Status.Unscheduled,
17812882Sspwilson2@wisc.edu            'result': Result(Result.NotRun)
17912882Sspwilson2@wisc.edu        })
18012882Sspwilson2@wisc.edu
18112882Sspwilson2@wisc.edu    def __iter__(self):
18212882Sspwilson2@wisc.edu        return iter(self.tests)
18312882Sspwilson2@wisc.edu
18412882Sspwilson2@wisc.edu    @property
18512882Sspwilson2@wisc.edu    def tags(self):
18612882Sspwilson2@wisc.edu        return self.metadata.tags
18712882Sspwilson2@wisc.edu
18812882Sspwilson2@wisc.edu
18912882Sspwilson2@wisc.educlass LoadedLibrary(LoadedTestable):
19012882Sspwilson2@wisc.edu    '''
19112882Sspwilson2@wisc.edu    Wraps a collection of all loaded test suites and
19212882Sspwilson2@wisc.edu    provides utility functions for accessing fixtures.
19312882Sspwilson2@wisc.edu    '''
19414141Snikos.nikoleris@arm.com    def __init__(self, suites):
19512882Sspwilson2@wisc.edu        LoadedTestable.__init__(self, suites)
19612882Sspwilson2@wisc.edu
19712882Sspwilson2@wisc.edu    def _generate_metadata(self):
19812882Sspwilson2@wisc.edu        return LibraryMetadata( **{
19912882Sspwilson2@wisc.edu            'name': 'Test Library',
20012882Sspwilson2@wisc.edu            'status': Status.Unscheduled,
20112882Sspwilson2@wisc.edu            'result': Result(Result.NotRun)
20212882Sspwilson2@wisc.edu        })
20312882Sspwilson2@wisc.edu
20412882Sspwilson2@wisc.edu    def __iter__(self):
20512882Sspwilson2@wisc.edu        '''
20612882Sspwilson2@wisc.edu        :returns: an iterator over contained :class:`TestSuite` objects.
20712882Sspwilson2@wisc.edu        '''
20812882Sspwilson2@wisc.edu        return iter(self.obj)
20912882Sspwilson2@wisc.edu
21012882Sspwilson2@wisc.edu    def all_fixtures(self):
21112882Sspwilson2@wisc.edu        '''
21212882Sspwilson2@wisc.edu        :returns: an interator overall all global, suite,
21312882Sspwilson2@wisc.edu          and test fixtures
21412882Sspwilson2@wisc.edu        '''
21512882Sspwilson2@wisc.edu        return itertools.chain(itertools.chain(
21614141Snikos.nikoleris@arm.com            *(suite.fixtures for suite in self.obj)),
21712882Sspwilson2@wisc.edu            *(self.test_fixtures(suite) for suite in self.obj)
21812882Sspwilson2@wisc.edu        )
21912882Sspwilson2@wisc.edu
22012882Sspwilson2@wisc.edu    def test_fixtures(self, suite):
22112882Sspwilson2@wisc.edu        '''
22212882Sspwilson2@wisc.edu        :returns: an interator over all fixtures of each
22312882Sspwilson2@wisc.edu          test contained in the given suite
22412882Sspwilson2@wisc.edu        '''
22512882Sspwilson2@wisc.edu        return itertools.chain(*(test.fixtures for test in suite))
22612882Sspwilson2@wisc.edu
22712882Sspwilson2@wisc.edu    @property
22812882Sspwilson2@wisc.edu    def fixtures(self):
22914141Snikos.nikoleris@arm.com        global_fixtures = []
23014141Snikos.nikoleris@arm.com        for fixture in self.all_fixtures():
23114141Snikos.nikoleris@arm.com            if fixture.is_global():
23214141Snikos.nikoleris@arm.com                global_fixtures.append(fixture)
23314141Snikos.nikoleris@arm.com        return global_fixtures
23412882Sspwilson2@wisc.edu
23512882Sspwilson2@wisc.edu    @property
23612882Sspwilson2@wisc.edu    def uid(self):
23712882Sspwilson2@wisc.edu        return self.name
23812882Sspwilson2@wisc.edu
23912882Sspwilson2@wisc.edu    @property
24012882Sspwilson2@wisc.edu    def suites(self):
24112882Sspwilson2@wisc.edu        return self.obj
24212882Sspwilson2@wisc.edu
24312882Sspwilson2@wisc.edu    @suites.setter
24412882Sspwilson2@wisc.edu    def suites(self, suites):
24512882Sspwilson2@wisc.edu        self.obj = suites
246