Ejemplo n.º 1
0
 def testAddParam(self):
     root = pyhit.load('test.hit')
     self.assertEqual(len(root(1)), 2)
     self.assertIsNone(root(1).get('year'))
     root(1)['year'] = 1980
     self.assertEqual(len(root(1)), 2)
     self.assertEqual(root(1).get('year'), 1980)
Ejemplo n.º 2
0
    def test(self):

        # MOOSEDOCS:example-begin
        # Load the packages
        import pyhit
        import moosetree

        # Read the file
        root = pyhit.load('input.i')

        # Locate and modify "x_max" parameter for the mesh
        mesh = moosetree.find(root, func=lambda n: n.fullpath == '/Mesh/gen')
        mesh["x_max"] = 4

        # Set the comment on altered parameter
        mesh.setComment("x_max", "Changed from 3 to 4")

        # Write the modified file
        pyhit.write("input_modified.i", root)

        # MOOSEDOCS:example-end
        self.assertEqual(mesh["x_max"], 4)
        self.assertEqual(mesh.comment("x_max"), "Changed from 3 to 4")

        out = mesh.render()
        self.assertIn("x_max = 4", out)
        self.assertIn("Changed from 3 to 4", out)
Ejemplo n.º 3
0
def _add_requirements(out, location, filename):
    """
    Opens tests specification and extracts requirement items.
    """
    root = pyhit.load(filename)
    design = root.children[0].get('design', None)
    design_line = root.children[0].line('design', None)
    issues = root.children[0].get('issues', None)
    issues_line = root.children[0].line('issues', None)
    deprecated = root.children[0].get('deprecated', False)
    deprecated_line = root.children[0].line('deprecated', None)

    group = os.path.relpath(filename, location).split('/')[0]
    path = os.path.relpath(os.path.dirname(filename), location)

    for child in root.children[0]:
        req = _create_requirement(child, path, filename,
                                  design, design_line,
                                  issues, issues_line,
                                  deprecated, deprecated_line)
        out[group].append(req)

        # Get "detail" parameter from nested tests
        for grandchild in child.children:
            detail = _create_requirement(grandchild, path, filename, None, None, None, None, None, None)
            req.details.append(detail)
Ejemplo n.º 4
0
    def check(self, location):

        # List of errors
        messages = []

        # Load the test spec and create a list of PythonUnitTest files
        tested = set()
        spec = os.path.join(location, 'tests')
        if not os.path.exists(spec):
            if glob.glob(os.path.join(spec, '*.py')):
                messages.append("Missing a test spec file in '{}'".format(os.path.dirname(spec)))
        else:
            node = pyhit.load(os.path.join(location, 'tests'))
            for block in moosetree.find(node, lambda n: n.name=='Tests'):
                if block['type'] == 'PythonUnitTest':
                    tested.add(block['input'])

        # Loop through python files in this directory
        for filename in glob.glob(os.path.join(location, '*.py')):

            # Local filename
            base = os.path.basename(filename)

            # Load the module (tried this with os.chdir, but that didn't work)
            sys.path.append(location)
            mod = __import__(base[:-3])
            sys.path.remove(location)

            # Get a lit of unittest.TestCase objects, if they exist this file should be in spec
            tests = get_parent_objects(mod, unittest.TestCase)
            if tests and (base not in tested):
                msg = "The test script '{}' is not included in the tests spec '{}'."
                messages.append(msg.format(base, spec))

        return messages
Ejemplo n.º 5
0
def sqa_check_requirement_duplicates(
        working_dir=os.getcwd(), specs=['tests'], skip=[]):
    """Check that no duplicate requirements exist."""
    import pyhit

    requirements = collections.defaultdict(list)
    for root, dirs, files in os.walk(working_dir):
        for fname in files:
            filename = os.path.join(root, fname)
            if fname in specs and not any(s in filename for s in skip):
                node = pyhit.load(filename)
                for child in node.children[0]:
                    req = child.get('requirement', None)
                    if req is not None:
                        requirements[req.strip()].append(
                            (filename, child.fullpath,
                             child.line('requirement')))

    count = 0
    for key, value in requirements.items():
        if len(value) > 1:
            if count == 0:
                print(colorText('Duplicate Requirements Found:\n', 'YELLOW'))
            count += 1
            if len(key) > 80:
                print(colorText('{}...'.format(key[:80]), 'YELLOW'))
            for filename, path, line in value:
                print('    {}:{}'.format(filename, line))

    return count
Ejemplo n.º 6
0
 def testAddParam(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     self.assertEqual(len(root(1)), 2)
     self.assertIsNone(root(1).get('year'))
     root(1)['year'] = 1980
     self.assertEqual(len(root(1)), 2)
     self.assertEqual(root(1).get('year'), 1980)
Ejemplo n.º 7
0
 def testAppend(self):
     root = pyhit.load(os.path.join('test_files', 'test.hit'))
     self.assertEqual(len(root(1)), 2)
     sec = root(1).append('B-3')
     self.assertEqual(len(root(1)), 3)
     self.assertIs(root(1)(2), sec)
     self.assertIsNone(sec.get('year'))
     sec['year'] = 1980
     self.assertEqual(sec.get('year'), 1980)
Ejemplo n.º 8
0
 def testInsert(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     self.assertEqual(len(root(1)), 2)
     sec = root(1).insert(0, 'B-3')
     self.assertEqual(len(root(1)), 3)
     self.assertIs(root(1)(0), sec)
     self.assertIsNone(sec.get('year'))
     sec['year'] = 1980
     self.assertEqual(sec.get('year'), 1980)
Ejemplo n.º 9
0
    def testSetComment(self):
        root = pyhit.load('test.hit')
        root(1).setComment('update section comment')
        self.assertEqual(root(1).comment(), "update section comment")

        root(0, 0).setComment('update sub-section comment')
        self.assertEqual(root(0, 0).comment(), "update sub-section comment")

        root(1, 0, 0).setComment('type', 'update param comment')
        self.assertEqual(root(1, 0, 0).comment('type'), "update param comment")
Ejemplo n.º 10
0
    def testSetComment(self):
        root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
        root(1).setComment('update section comment')
        self.assertEqual(root(1).comment(), "update section comment")

        root(0, 0).setComment('update sub-section comment')
        self.assertEqual(root(0, 0).comment(), "update sub-section comment")

        root(1, 0, 0).setComment('type', 'update param comment')
        self.assertEqual(root(1, 0, 0).comment('type'), "update param comment")
Ejemplo n.º 11
0
def check_requirement(filename):
    """Check spec file for requirement documentation."""
    import pyhit

    messages = []
    root = pyhit.load(filename)
    design = root.children[0].get('design', '')
    issues = root.children[0].get('issues', '')
    deprecated = root.children[0].get('deprecated', False)

    for child in root.children[0]:
        if child.get('deprecated', deprecated):
            continue

        if 'requirement' not in child:
            messages.append(
                "    'requirement' parameter is missing or empty in '{}' block."
                .format(child.name))

        if not child.get('design', design).strip():
            messages.append(
                "    'design' parameter is missing or empty in '{}' block.".
                format(child.name))

        if not child.get('issues', issues).strip():
            messages.append(
                "    'issues' parameter is missing or empty in '{}' block.".
                format(child.name))

        for grandchild in child.children:
            if 'detail' not in grandchild:
                messages.append(
                    "    'detail' parameter is missing or empty in '{}' block."
                    .format(grandchild.name))

            if 'requirement' in grandchild:
                messages.append(
                    "    'requirement' parameter in block '{}' must not be used within a group, use 'detail' instead."
                    .format(grandchild.name))

            if 'design' in grandchild:
                messages.append(
                    "    'design' parameter in block '{}' must not be used within a group."
                    .format(grandchild.name))

            if 'issues' in grandchild:
                messages.append(
                    "    'issues' parameter in block '{}' must not be used within a group."
                    .format(grandchild.name))

    if messages:
        print('ERROR in {}'.format(filename))
        print('\n'.join(messages) + '\n')
        return 1
    return 0
Ejemplo n.º 12
0
 def extractInputBlocks(filename, blocks):
     """Read input file block(s)"""
     hit = pyhit.load(filename)
     out = []
     for block in blocks.split():
         node = moosetree.find(hit, lambda n: n.fullpath.endswith(block.strip('/')))
         if node is None:
             msg = "Unable to find block '{}' in {}."
             raise exceptions.MooseDocsException(msg, block, filename)
         out.append(str(node.render()))
     return pyhit.parse('\n'.join(out)) if out else hit
Ejemplo n.º 13
0
    def testAddComment(self):
        root = pyhit.load('test.hit')

        root(0).setComment('Section A')
        self.assertEqual(root(0).comment(), "Section A")

        root(1, 0).setComment('Section B-1')
        self.assertEqual(root(1, 0).comment(), "Section B-1")

        root(0, 0).setComment('param', "inline comment")
        self.assertEqual(root(0, 0).comment('param'), "inline comment")
Ejemplo n.º 14
0
    def testAddComment(self):
        root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))

        root(0).setComment('Section A')
        self.assertEqual(root(0).comment(), "Section A")

        root(1, 0).setComment('Section B-1')
        self.assertEqual(root(1, 0).comment(), "Section B-1")

        root(0, 0).setComment('param', "inline comment")
        self.assertEqual(root(0, 0).comment('param'), "inline comment")
Ejemplo n.º 15
0
    def testRemoveComment(self):
        root = pyhit.load('test.hit')
        self.assertIn("type = test # param comment", root.render())
        self.assertIn("# section comment", root.render())

        root(1, 0, 0).setComment("type", None)
        self.assertIsNone(root(1, 0, 0).comment())
        self.assertNotIn("type = test # param comment", root.render())

        root(1).setComment(None)
        self.assertIsNone(root(1).comment())
        self.assertNotIn("# section comment", root.render())
Ejemplo n.º 16
0
def get_requirements_from_file(filename,
                               prefix=None,
                               include_non_testable=False):
    """
    Opens hit file and extracts requirement items.

    Input:
        filename[str]: The HIT file to open and extract Requirements

    Returns:
         A list of Requirement objects.
    """
    if not os.path.isfile(filename):
        raise FileNotFoundError(
            "The supplied filename does not exist: {}".format(filename))
    requirements = list()
    root = pyhit.load(filename)

    # Options available at the top-level
    #   [Tests]
    #      design = 'foo.md bar.md'
    #      issues = '#12345 ab23bd34'
    design = root.children[0].get('design', None)
    design_line = root.children[0].line('design', None)
    issues = root.children[0].get('issues', None)
    issues_line = root.children[0].line('issues', None)
    deprecated = root.children[0].get('deprecated', False)
    deprecated_line = root.children[0].line('deprecated', None)
    collections = root.children[0].get('collections', None)
    collections_line = root.children[0].line('collections', None)

    for child in root.children[0]:
        req = _create_requirement(child, filename, design, design_line, issues,
                                  issues_line, collections, collections_line,
                                  deprecated, deprecated_line)
        req.prefix = prefix

        # Get "detail" parameter from nested tests
        for grandchild in child.children:
            detail = _create_detail(grandchild, filename)
            detail.specification = _create_specification(
                grandchild, '{}/{}'.format(child.name, grandchild.name),
                filename)
            req.details.append(detail)

        if not req.details:
            req.specification = _create_specification(child, child.name,
                                                      filename)

        if req.testable or include_non_testable:
            requirements.append(req)

    return requirements
Ejemplo n.º 17
0
    def parse(self, filename, default_values=None):

        self.fname = os.path.abspath(filename)

        try:
            root = pyhit.load(self.fname)
        except Exception as err:
            self.error(err)
            return
        self.root = root(0)  # make the [Tests] block the root

        self.check()
        self._parseNode(filename, self.root, default_values)
Ejemplo n.º 18
0
    def _setParallel(self):
        """ Read the test spec file and determine if parallel_scheduling is set. """
        if self.__parallel_scheduling is not None:
            return self.__parallel_scheduling
        self.__parallel_scheduling = False

        job = self.getJob()
        if job:
            # We only need a single tester so we know what spec file to load.
            # TODO: would be nice to have access to this without needing tester.specs
            tester = job[0].getTester()
            root = pyhit.load(
                os.path.join(tester.specs['test_dir'],
                             tester.specs['spec_file']))
            self.__parallel_scheduling = root.children[0].get(
                'parallel_scheduling', False)

        return self.__parallel_scheduling
Ejemplo n.º 19
0
    def testBasic(self):
        root = pyhit.load(os.path.join('test_files', 'test.hit'))

        self.assertEqual(root.children[0].name, 'A')
        self.assertEqual(root.children[0]['param'], 'foo')
        self.assertEqual(root.children[0].children[0].name, 'A-1')
        self.assertIn('param', root.children[0].children[0])
        self.assertEqual(root.children[0].children[0]['param'], 'bar')

        self.assertEqual(root.children[1].name, 'B')
        self.assertEqual(root.children[1].children[0].name, 'B-1')
        self.assertEqual(root.children[1].children[0].children[0].name, 'B-1-1')
        self.assertIn('type', root.children[1].children[0].children[0])
        self.assertEqual(root.children[1].children[0].children[0]['type'], 'test')
        self.assertEqual(root.children[1].children[1].name, 'B-2')

        gold = ['A', 'B']
        for i, child in enumerate(root):
            self.assertEqual(child.name, gold[i])
Ejemplo n.º 20
0
def get_test_specification(filename, block):
    """
    Create a TestSpecification object from the HIT file and block name.

    Input:
        filename[str]: Complete filename of a HIT file containing test specification(s)
        block[str]: The name of the block to use for creating the TestSpecification object

    This function exists to allow for requirements to be defined outside of the test specifications,
    but still reference tests for the purpose of SQA traceability. Support for this was added to
    allow for non-functional requirements to be defined outside of the test specifications.
    """
    root = pyhit.load(filename)

    # Locate the desired block
    node = moosetree.find(root, lambda n: n.fullpath.endswith(block))
    if node is None:
        raise KeyError("Unable to locate '{}' in {}".format(block, filename))

    # Build/return TestSpecification object
    name = node.name if node.parent.parent.is_root else '{}/{}'.format(node.parent.name, node.name)
    return _create_specification(node, name, filename, mooseutils.git_root_dir(os.path.dirname(filename)))
Ejemplo n.º 21
0
def _add_requirements(out, location, filename):
    """
    Opens tests specification and extracts requirement items.
    """
    root = pyhit.load(filename)

    # Options available at the top-level
    #   [Tests]
    #      design = 'foo.md bar.md'
    #      issues = '#12345 ab23bd34'
    design = root.children[0].get('design', None)
    design_line = root.children[0].line('design', None)
    issues = root.children[0].get('issues', None)
    issues_line = root.children[0].line('issues', None)
    deprecated = root.children[0].get('deprecated', False)
    deprecated_line = root.children[0].line('deprecated', None)
    collections = root.children[0].get('collections', None)
    collections_line = root.children[0].line('collections', None)

    group = os.path.relpath(filename, location).split('/')[0]
    path = os.path.relpath(os.path.dirname(filename), location)
    for child in root.children[0]:
        req = _create_requirement(child, path, filename,
                                  design, design_line,
                                  issues, issues_line,
                                  collections, collections_line,
                                  deprecated, deprecated_line)
        out[group].append(req)

        # Get "detail" parameter from nested tests
        for grandchild in child.children:
            detail = _create_detail(grandchild, path, filename)
            detail.specification = _create_specification(grandchild, '{}/{}'.format(child.name, grandchild.name), path, filename)
            req.details.append(detail)

        if not req.details:
            req.specification = _create_specification(child, child.name, path, filename)
Ejemplo n.º 22
0
 def testTestRoot(self):
     root = pyhit.load(os.path.join('..', '..', 'testroot'))
     self.assertIn('app_name', root)
     self.assertEqual(root['app_name'], 'moose_python')
Ejemplo n.º 23
0
 def testAddSectionWithParameters(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     self.assertEqual(len(root(1)), 2)
     sec = root(1).append('B-3', year=1980)
     self.assertEqual(len(root(1)), 3)
     self.assertEqual(sec.get('year'), 1980)
Ejemplo n.º 24
0
 def testComment(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     self.assertEqual(root(1).comment(), "section comment")
     self.assertEqual(root(0, 0).comment(), "sub-section comment")
     self.assertEqual(root(1, 0, 0).comment('type'), "param comment")
Ejemplo n.º 25
0
 def testIterParam(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     for k, v in root.children[0].params():
         self.assertEqual(k, 'param')
         self.assertEqual(v, 'foo')
Ejemplo n.º 26
0
 def testGetParam(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     p = root.get('nope', 'default')
     self.assertEqual(p, 'default')
Ejemplo n.º 27
0
    def _addRequirement(self, parent, info, page, req, requirements, category):
        reqname = "{}:{}".format(req.path, req.name) if req.path != '.' else req.name
        item = SQARequirementMatrixItem(parent, label=req.label, reqname=reqname,
                                        satisfied=req.satisfied)
        text = SQARequirementText(item)

        self.reader.tokenize(text, req.text, page, MarkdownReader.INLINE, info.line, report=False)
        for token in moosetree.iterate(item):
            if token.name == 'ErrorToken':
                msg = common.report_error("Failed to tokenize SQA requirement.",
                                          req.filename,
                                          req.text_line,
                                          req.text,
                                          token['traceback'],
                                          'SQA TOKENIZE ERROR')
                LOG.critical(msg)

        if req.details:
            details = SQARequirementDetails(item)
            for detail in req.details:
                ditem = SQARequirementDetailItem(details)
                text = SQARequirementText(ditem)
                self.reader.tokenize(text, detail.text, page, MarkdownReader.INLINE, info.line, \
                                     report=False)

        if self.settings['link']:
            if self.settings['link-spec']:
                p = SQARequirementSpecification(item, spec_path=req.path, spec_name=req.name)

                hit_root = pyhit.load(req.filename)
                h = moosetree.find(hit_root, lambda n: n.name==req.name)
                content = h.render()

                floats.create_modal_link(p,
                                         title=reqname, string=reqname,
                                         content=core.Code(None, language='text', content=content))

            if self.settings['link-design'] and req.design:
                p = SQARequirementDesign(item, filename=req.filename, design=req.design,
                                         line=req.design_line)

            if self.settings['link-issues'] and req.issues:
                p = SQARequirementIssues(item, filename=req.filename, issues=req.issues,
                                         line=req.issues_line, url=self.extension.remote(category))

            if self.settings.get('link-prerequisites', False) and req.prerequisites:
                labels = []
                for prereq in req.prerequisites:
                    for other in requirements:
                        if (other.name == prereq) and (other.path == req.path):
                            labels.append((other.path, other.name, other.label))
                        for detail in other.details:
                            if (detail.name == prereq) and (detail.path == req.path):
                                labels.append((other.path, other.name, other.label))

                SQARequirementPrequisites(item, specs=labels)

            if self.settings.get('link-results', False):
                keys = list()

                for detail in req.details:
                    keys.append('{}.{}/{}'.format(req.path, req.name, detail.name))

                if not keys:
                    keys.append('{}.{}'.format(req.path, req.name))

                if self.extension.hasCivetExtension():
                    civet.CivetTestBadges(item, tests=keys)
Ejemplo n.º 28
0
 def testRemoveParam(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     self.assertEqual(root(0)['param'], 'foo')
     root(0).removeParam('param')
     self.assertIsNone(root(0).get('param'))
Ejemplo n.º 29
0
def _add_requirements(out, location, filename):
    """Opens tests specification and extracts requirement items."""
    root = pyhit.load(filename)
    design = root.children[0].get('design', None)
    design_line = root.children[0].line('design', None)
    issues = root.children[0].get('issues', None)
    issues_line = root.children[0].line('issues', None)
    deprecated = root.children[0].get('deprecated', False)
    deprecated_line = root.children[0].line('deprecated', None)

    for child in root.children[0]:
        if 'requirement' in child:
            requirement_line = child.line('requirement')

            # Deprecation
            local_deprecated = child.get('deprecated', deprecated)
            local_deprecated_line = child.line('deprecated', deprecated_line)
            if local_deprecated:
                msg = "%s:%s\nThe 'requirement' parameter is specified for %s, but the test is " \
                      "marked as deprecated on line %s."
                LOG.error(msg, filename, requirement_line, child.name,
                          local_deprecated_line)
                continue

            # Deprecation
            local_deprecated = child.get('deprecated', deprecated)
            local_deprecated_line = child.line('deprecated', deprecated_line)
            if local_deprecated:
                msg = "The 'requirment' parameter is specified for %s, but the test is marked as " \
                      "deprecated on line %s."
                LOG.error(msg, child.name, local_deprecated_line)
                continue

            local_design = child.get('design', design)
            local_design_line = child.line('design', design_line)
            if local_design is None:
                msg = "The 'design' parameter is missing from '%s' in %s. It must be defined at " \
                      "the top level and/or within the individual test specification. It " \
                      "should contain a space separated list of filenames."
                LOG.error(msg, child.name, filename)
                local_design = ''

            local_issues = child.get('issues', issues)
            local_issues_line = child.line('issues', issues_line)
            if local_issues is None:
                msg = "The 'issues' parameter is missing from '%s' in %s. It must be defined at " \
                      "the top level and/or within the individual test specification. It " \
                      "should contain a space separated list of issue numbers (include the #) or " \
                      "a git commit SHA."
                LOG.error(msg, child.name, filename)
                local_issues = ''

            text = child['requirement']
            if 'MOOSE_TEST_NAME' in text:
                idx = filename.index('/tests/')
                name = os.path.join(os.path.dirname(filename[idx + 7:]),
                                    child.name)
                text = text.replace('MOOSE_TEST_NAME', name)

            satisfied = False if (child['skip'] or child['deleted']) else True
            req = Requirement(name=child.name,
                              path=os.path.relpath(os.path.dirname(filename),
                                                   location),
                              filename=filename,
                              text=str(text),
                              text_line=child.line('requirement', None),
                              design=local_design.split(),
                              design_line=local_design_line,
                              issues=local_issues.split(),
                              issues_line=local_issues_line,
                              satisfied=satisfied)

            req.verification = child.get('verification', None)
            req.validation = child.get('validation', None)

            group = os.path.relpath(filename, location).split('/')[0]

            prereq = child.get('prereq', None)
            if prereq is not None:
                req.prerequisites = set(prereq.split(' '))

            for grandchild in child.children:
                detail = grandchild.get('detail', None)
                if detail is None:
                    msg = "The 'detail' parameters is missing from '%s' in %s. It must be defined "\
                          "for all sub-blocks within a test group."
                    LOG.error(msg, grandchild.name, filename)

                _check_extra_param(grandchild, 'requirement', filename)
                _check_extra_param(grandchild, 'issues', filename)
                _check_extra_param(grandchild, 'design', filename)

                req.details.append(
                    Detail(name=grandchild.name,
                           path=req.path,
                           filename=filename,
                           text=str(detail),
                           text_line=grandchild.line('detail')))

            out[group].append(req)
Ejemplo n.º 30
0
 def testRender(self):
     root = pyhit.load(os.path.join('..', '..', 'test_files', 'test.hit'))
     out = root.render()
     self.assertIn('[A]', out)
     self.assertIn('param = bar', out)
     self.assertIn('comment', out)