Пример #1
0
def find_includes(filepath, filelist=set()):
    """
    Recursively searches a .cpp file for #include directives and returns
    a set of all of them.
    :return: a list of all includes found
    """
    filedir = os.path.dirname(filepath)
    try:
        log.debug_indent()
        for include_line in file.grep(r'^\s*#\s*include\s+("(.*)"|<(.*)>)\s*$',
                                      filepath):
            m = include_line['match']
            index = include_line['index']
            include = find_include(
                m.group(2), filedir) or find_include_in_dirs(
                    m.group(2)) or find_include_in_dirs(m.group(3))
            if include:
                if include in filelist:
                    log.d(m.group(0), '->', include, '(already processed)')
                else:
                    log.d(m.group(0), '->', include)
                    filelist.add(include)
                    filelist = find_includes(include, filelist)
            else:
                log.d('not found:', m.group(0))
    finally:
        log.debug_unindent()
    return filelist
Пример #2
0
def get_tests():
    global regex, target, pyrs, current_dir, linux
    if regex:
        pattern = re.compile(regex)
    if target:
        # In Linux, the build targets are located elsewhere than on Windows
        # Go over all the tests from a "manifest" we take from the result of the last CMake
        # run (rather than, for example, looking for test-* in the build-directory):
        if linux:
            manifestfile = target + '/CMakeFiles/TargetDirectories.txt'
        else:
            manifestfile = target + '/../CMakeFiles/TargetDirectories.txt'
        # log.d( manifestfile )
        for manifest_ctx in file.grep(
                r'(?<=unit-tests/build/)\S+(?=/CMakeFiles/test-\S+.dir$)',
                manifestfile):
            # We need to first create the test name so we can see if it fits the regex
            testdir = manifest_ctx['match'].group(0)  # "log/internal/test-all"
            # log.d( testdir )
            testparent = os.path.dirname(testdir)  # "log/internal"
            if testparent:
                testname = 'test-' + testparent.replace(
                    '/', '-') + '-' + os.path.basename(testdir)[
                        5:]  # "test-log-internal-all"
            else:
                testname = testdir  # no parent folder so we get "test-all"

            if regex and not pattern.search(testname):
                continue

            if linux:
                exe = target + '/unit-tests/build/' + testdir + '/' + testname
            else:
                exe = target + '/' + testname + '.exe'

            yield libci.ExeTest(testname, exe, context)

    # Python unit-test scripts are in the same directory as us... we want to consider running them
    # (we may not if they're live and we have no pyrealsense2.pyd):
    for py_test in file.find(current_dir, '(^|/)test-.*\.py'):
        testparent = os.path.dirname(
            py_test)  # "log/internal" <-  "log/internal/test-all.py"
        if testparent:
            testname = 'test-' + testparent.replace(
                '/', '-') + '-' + os.path.basename(py_test)[5:-3]  # remove .py
        else:
            testname = os.path.basename(py_test)[:-3]

        if regex and not pattern.search(testname):
            continue

        yield libci.PyTest(testname, py_test, context)
Пример #3
0
def check_log_for_fails(path_to_log,
                        testname,
                        configuration=None,
                        repetition=1):
    # Normal logs are expected to have in last line:
    #     "All tests passed (11 assertions in 1 test case)"
    # Tests that have failures, however, will show:
    #     "test cases: 1 | 1 failed
    #      assertions: 9 | 6 passed | 3 failed"
    # We make sure we look at the log written by the last run of the test by ignoring anything before the last
    # line with "----...---" that separate between 2 separate runs of he test
    if path_to_log is None:
        return False
    results = None
    for ctx in file.grep(
            r'^test cases:\s*(\d+) \|\s*(\d+) (passed|failed)|^----------TEST-SEPARATOR----------$',
            path_to_log):
        m = ctx['match']
        if m.string == "----------TEST-SEPARATOR----------":
            results = None
        else:
            results = m

    if not results:
        return False

    total = int(results.group(1))
    passed = int(results.group(2))
    if results.group(3) == 'failed':
        # "test cases: 1 | 1 failed"
        passed = total - passed
    if passed < total:
        if total == 1 or passed == 0:
            desc = 'failed'
        else:
            desc = str(total - passed) + ' of ' + str(total) + ' failed'

        if log.is_verbose_on():
            log.e(log.red + testname + log.reset + ': ' +
                  configuration_str(configuration, repetition, suffix=' ') +
                  desc)
            log.i('Log: >>>')
            log.out()
            file.cat(path_to_log)
            log.out('<<<')
        else:
            log.e(log.red + testname + log.reset + ': ' +
                  configuration_str(configuration, repetition, suffix=' ') +
                  desc + '; see ' + path_to_log)
        return True
    return False
Пример #4
0
def find_includes(filepath):
    filelist = set()
    filedir = os.path.dirname(filepath)
    for context in file.grep('^\s*#\s*include\s+"(.*)"\s*$', filepath):
        m = context['match']
        index = context['index']
        include = m.group(1)
        if not os.path.isabs(include):
            include = os.path.normpath(filedir + '/' + include)
        include = include.replace('\\', '/')
        if os.path.exists(include):
            filelist.add(include)
            filelist |= find_includes(include)
    return filelist
Пример #5
0
    def __init__( self, source, line_prefix ):
        """
        :param source: The path to the text file
        :param line_prefix: A regex to denote a directive (must be first thing in a line), which will
            be immediately followed by the directive itself and optional arguments
        """
        TestConfig.__init__(self)

        # Parse the python
        regex = r'^' + line_prefix + r'(\S+)((?:\s+\S+)*?)\s*(?:#\s*(.*))?$'
        for context in file.grep( regex, source ):
            match = context['match']
            directive = match.group(1)
            text_params = match.group(2).strip()
            params = [s for s in text_params.split()]
            comment = match.group(3)
            if directive == 'device':
                #log.d( '    configuration:', params )
                if not params:
                    log.e( source + '+' + str(context['index']) + ': device directive with no devices listed' )
                elif 'each' in text_params.lower() and len(params) > 1:
                    log.e( source + '+' + str(context['index']) + ': each() cannot be used in combination with other specs', params )
                elif 'each' in text_params.lower() and not re.fullmatch( r'each\(.+\)', text_params, re.IGNORECASE ):
                    log.e( source + '+' + str(context['index']) + ': invalid \'each\' syntax:', params )
                else:
                    self._configurations.append( params )
            elif directive == 'priority':
                if len(params) == 1 and params[0].isdigit():
                    self._priority = int( params[0] )
                else:
                    log.e( source + '+' + str(context['index']) + ': priority directive with invalid parameters:', params )
            elif directive == 'timeout':
                if len(params) == 1 and params[0].isdigit():
                    self._timeout = int( params[0] )
                else:
                    log.e( source + '+' + str(context['index']) + ': timeout directive with invalid parameters:', params )
            elif directive == 'tag':
                self._tags.update(params)
            elif directive == 'flag':
                self._flags.update( params )
            else:
                log.e( source + '+' + str(context['index']) + ': invalid directive "' + directive + '"; ignoring' )
Пример #6
0
def process_cpp(dir, builddir):
    global regex, required_tags, list_only, available_tags, tests_and_tags
    found = []
    shareds = []
    statics = []
    if regex:
        pattern = re.compile(regex)
    for f in file.find(dir, '(^|/)test-.*\.cpp$'):
        testdir = os.path.splitext(f)[
            0]  # "log/internal/test-all"  <-  "log/internal/test-all.cpp"
        testparent = os.path.dirname(testdir)  # "log/internal"
        # We need the project name unique: keep the path but make it nicer:
        testname = 'test-' + testparent.replace(
            '/', '-') + '-' + os.path.basename(testdir)[
                5:]  # "test-log-internal-all"

        if regex and not pattern.search(testname):
            continue

        if required_tags or list_tags:
            config = libci.TestConfigFromCpp(dir + os.sep + f)
            if not all(tag in config.tags for tag in required_tags):
                continue
            available_tags.update(config.tags)
            if list_tests:
                tests_and_tags[testname] = config.tags

        if testname not in tests_and_tags:
            tests_and_tags[testname] = None

        if list_only:
            continue

        # Each CMakeLists.txt sits in its own directory
        os.makedirs(builddir + '/' + testdir,
                    exist_ok=True)  # "build/log/internal/test-all"
        # Build the list of files we want in the project:
        # At a minimum, we have the original file, plus any common files
        filelist = [dir + '/' + f, '${ELPP_FILES}', '${CATCH_FILES}']
        # Add any "" includes specified in the .cpp that we can find
        includes = find_includes(dir + '/' + f)
        # Add any files explicitly listed in the .cpp itself, like this:
        #         //#cmake:add-file <filename>
        # Any files listed are relative to $dir
        shared = False
        static = False
        for context in file.grep('^//#cmake:\s*', dir + '/' + f):
            m = context['match']
            index = context['index']
            cmd, *rest = context['line'][m.end():].split()
            if cmd == 'add-file':
                for additional_file in rest:
                    files = additional_file
                    if not os.path.isabs(additional_file):
                        files = dir + '/' + testparent + '/' + additional_file
                    files = glob(files)
                    if not files:
                        log.e(f + '+' + str(index) + ': no files match "' +
                              additional_file + '"')
                    for abs_file in files:
                        abs_file = os.path.normpath(abs_file)
                        abs_file = abs_file.replace('\\', '/')
                        if not os.path.exists(abs_file):
                            log.e(f + '+' + str(index) + ': file not found "' +
                                  additional_file + '"')
                        log.d('   add file:', abs_file)
                        filelist.append(abs_file)
                        if (os.path.splitext(abs_file)[0] == 'cpp'):
                            # Add any "" includes specified in the .cpp that we can find
                            includes |= find_includes(abs_file)
            elif cmd == 'static!':
                if len(rest):
                    log.e(f + '+' + str(index) +
                          ': unexpected arguments past \'' + cmd + '\'')
                elif shared:
                    log.e(f + '+' + str(index) + ': \'' + cmd +
                          '\' mutually exclusive with \'shared!\'')
                else:
                    static = True
            elif cmd == 'shared!':
                if len(rest):
                    log.e(f + '+' + str(index) +
                          ': unexpected arguments past \'' + cmd + '\'')
                elif static:
                    log.e(f + '+' + str(index) + ': \'' + cmd +
                          '\' mutually exclusive with \'static!\'')
                else:
                    shared = True
            else:
                log.e(
                    f + '+' + str(index) + ': unknown cmd \'' + cmd +
                    '\' (should be \'add-file\', \'static!\', or \'shared!\')')
        for include in includes:
            filelist.append(include)
        generate_cmake(builddir, testdir, testname, filelist)
        if static:
            statics.append(testdir)
        elif shared:
            shareds.append(testdir)
        else:
            found.append(testdir)
    return found, shareds, statics
Пример #7
0
 def derive_config_from_text(self, source, line_prefix):
     # Configuration is made up of directives:
     #     #test:<directive>[:[!]<context>] <param>*
     # If a context is not specified, the directive always applies. Any directive with a context
     # will only get applied if we're running under the context it specifies (! means not, so
     # !nightly means when not under nightly).
     regex = r'^' + line_prefix
     regex += r'([^\s:]+)'  # 1: directive
     regex += r'(?::(\S+))?'  # 2: optional context
     regex += r'((?:\s+\S+)*?)'  # 3: params
     regex += r'\s*(?:#\s*(.*))?$'  # 4: optional comment
     for line in file.grep(regex, source):
         match = line['match']
         directive = match.group(1)
         directive_context = match.group(2)
         text_params = match.group(3).strip()
         params = [s for s in text_params.split()]
         comment = match.group(4)
         if directive_context:
             not_context = directive_context.startswith('!')
             if not_context:
                 directive_context = directive_context[1:]
             # not_context | directive_ctx==context | RESULT
             # ----------- | ---------------------- | ------
             #      0      |           0            | IGNORE
             #      0      |           1            | USE
             #      1      |           0            | USE
             #      1      |           1            | IGNORE
             if not_context == (directive_context == self.context):
                 # log.d( "directive", line['line'], "ignored because of context mismatch with running context",
                 #       self.context)
                 continue
         if directive == 'device':
             # log.d( '    configuration:', params )
             if not params:
                 log.e(source + '+' + str(line['index']) +
                       ': device directive with no devices listed')
             elif 'each' in text_params.lower() and len(params) > 1:
                 log.e(
                     source + '+' + str(line['index']) +
                     ': each() cannot be used in combination with other specs',
                     params)
             elif 'each' in text_params.lower() and not re.fullmatch(
                     r'each\(.+\)', text_params, re.IGNORECASE):
                 log.e(
                     source + '+' + str(line['index']) +
                     ': invalid \'each\' syntax:', params)
             else:
                 self._configurations.append(params)
         elif directive == 'priority':
             if len(params) == 1 and params[0].isdigit():
                 self._priority = int(params[0])
             else:
                 log.e(
                     source + '+' + str(line['index']) +
                     ': priority directive with invalid parameters:',
                     params)
         elif directive == 'timeout':
             if len(params) == 1 and params[0].isdigit():
                 self._timeout = int(params[0])
             else:
                 log.e(
                     source + '+' + str(line['index']) +
                     ': timeout directive with invalid parameters:', params)
         elif directive == 'tag':
             self._tags.update(map(str.lower,
                                   params))  # tags are case-insensitive
         elif directive == 'flag':
             self._flags.update(params)
         elif directive == 'donotrun':
             if params:
                 log.e(
                     source + '+' + str(line['index']) +
                     ': donotrun directive should not have parameters:',
                     params)
             self._donotrun = True
         else:
             log.e(source + '+' + str(line['index']) +
                   ': invalid directive "' + directive + '"; ignoring')