Example #1
0
    def test_add_prerequisite(self):
        test_unit \
            = CInfo(CSymbolID('argle',
                              Path('bargle/wargle.gargle')))
        assert test_unit.depends_on == []

        test_unit.add_prerequisite('cheese')
        assert test_unit.depends_on == ['cheese']
Example #2
0
    def test_equality(self):
        test_unit \
            = CInfo(CSymbolID('argle',
                              Path('bargle/wargle.gargle')),
                    ['beef', 'cheese'])
        with pytest.raises(TypeError):
            _ = test_unit == 'not a CInfo'

        other = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle')),
                      ['beef', 'cheese'])
        assert test_unit == other
        assert other == test_unit

        other = CInfo(CSymbolID('argle', Path('bargle/wargle.gargle')))
        assert test_unit != other
        assert other != test_unit
Example #3
0
 def test_default_constructor(self):
     test_unit \
         = CInfo(CSymbolID('argle',
                           Path('bargle/wargle.gargle')))
     assert test_unit.symbol.name == 'argle'
     assert test_unit.symbol.found_in == Path('bargle/wargle.gargle')
     assert test_unit.depends_on == []
Example #4
0
 def test_prereq_constructor(self):
     test_unit \
         = CInfo(CSymbolID('argle',
                           Path('bargle/wargle.gargle')),
                 ['cheese'])
     assert test_unit.symbol.name == 'argle'
     assert test_unit.symbol.found_in == Path('bargle/wargle.gargle')
     assert test_unit.depends_on == ['cheese']
Example #5
0
    def test_analyser_symbols(self, caplog, tmp_path):
        """
        Tests that symbols are identified, and calls are
        picked up provided they come from internal headers.
        """
        caplog.set_level(logging.DEBUG)

        test_file: Path = tmp_path / 'test.c'
        test_file.write_text(
            dedent('''
                  #pragma FAB UsrIncludeStart
                  void foo();
                  #pragma FAB UsrIncludeEnd

                  #pragma FAB UsrIncludeStart
                  void bar();
                  #pragma FAB UsrIncludeEnd

                  #pragma FAB SysIncludeStart
                  void baz();
                  #pragma FAB SysIncludeEnd

                  void foo() {
                      bar();
                      baz();
                  }
                   '''))

        database: SqliteStateDatabase = SqliteStateDatabase(tmp_path)
        test_unit = CAnalyser(tmp_path)
        test_artifact = Artifact(test_file, CSource, Raw)
        output_artifacts = test_unit.run([test_artifact])

        # Confirm database is updated
        working_state = CWorkingState(database)
        assert list(working_state) \
            == [CInfo(CSymbolID('foo', test_file),
                      ['bar'])]

        # Confirm returned Artifact is updated
        assert len(output_artifacts) == 1
        assert output_artifacts[0].defines == ['foo']
        assert output_artifacts[0].depends_on == ['bar']
        assert output_artifacts[0].location == test_file
        assert output_artifacts[0].filetype is CSource
        assert output_artifacts[0].state is Analysed
Example #6
0
    def test_get_symbol(self, tmp_path: Path):
        database = SqliteStateDatabase(tmp_path)
        test_unit = CWorkingState(database)

        # Test on an empty list
        #
        with pytest.raises(WorkingStateException):
            _ = test_unit.get_symbol('tigger')

        # Test we can retrieve an item from a single element list
        test_unit.add_c_symbol(CSymbolID('tigger', Path('tigger.c')))
        assert test_unit.get_symbol('tigger') \
            == [CInfo(CSymbolID('tigger', Path('tigger.c')))]
        with pytest.raises(WorkingStateException):
            _ = test_unit.get_symbol('eeor')

        # Test retrieval from a multi-element list and with prerequisites.
        #
        test_unit.add_c_symbol(CSymbolID('eeor', Path('eeor.c')))
        test_unit.add_c_dependency(CSymbolID('eeor', Path('eeor.c')), 'pooh')
        test_unit.add_c_dependency(CSymbolID('eeor', Path('eeor.c')), 'piglet')
        assert test_unit.get_symbol('tigger') \
            == [CInfo(CSymbolID('tigger', Path('tigger.c')))]
        assert test_unit.get_symbol('eeor') \
            == [CInfo(CSymbolID('eeor', Path('eeor.c')),
                      ['piglet', 'pooh'])]
        with pytest.raises(WorkingStateException):
            _ = test_unit.get_symbol('pooh')

        # Test a multiply defined program unit.
        #
        test_unit.add_c_symbol(CSymbolID('tigger', Path('hundred.c')))
        assert test_unit.get_symbol('tigger') \
            == [CInfo(CSymbolID('tigger', Path('hundred.c'))),
                CInfo(CSymbolID('tigger', Path('tigger.c')))]
        assert test_unit.get_symbol('eeor') \
            == [CInfo(CSymbolID('eeor', Path('eeor.c')),
                      ['piglet', 'pooh'])]
        with pytest.raises(WorkingStateException):
            _ = test_unit.get_symbol('pooh')
Example #7
0
    def test_add_remove_sequence(self, tmp_path: Path):
        database = SqliteStateDatabase(tmp_path)
        test_unit = CWorkingState(database)
        assert list(iter(test_unit)) == []

        # Add a file containing a program unit and an unsatisfied dependency.
        #
        test_unit.add_c_symbol(CSymbolID('foo', Path('foo.c')))
        test_unit.add_c_dependency(CSymbolID('foo', Path('foo.c')), 'bar')
        assert list(iter(test_unit)) \
            == [CInfo(CSymbolID('foo', Path('foo.c')),
                      ['bar'])]
        assert list(test_unit.depends_on(CSymbolID('foo',
                                                   Path('foo.c')))) \
            == [CSymbolUnresolvedID('bar')]

        # Add a second file containing a second program unit.
        #
        # This satisfies the previously dangling dependency and adds a new
        # one.
        #
        test_unit.add_c_symbol(CSymbolID('bar', Path('bar.c')))
        test_unit.add_c_dependency(CSymbolID('bar', Path('bar.c')), 'baz')
        assert list(iter(test_unit)) \
            == [CInfo(CSymbolID('bar', Path('bar.c')),
                      ['baz']),
                CInfo(CSymbolID('foo', Path('foo.c')),
                      ['bar'])]
        assert list(test_unit.depends_on(CSymbolID('foo',
                                                   Path('foo.c')))) \
            == [CSymbolID('bar', Path('bar.c'))]
        assert list(test_unit.depends_on(CSymbolID('bar',
                                                   Path('bar.c')))) \
            == [CSymbolUnresolvedID('baz')]

        # Add a third file also containing a third program unit and another
        # copy of the first.
        #
        # The new unit depends on two other units.
        #
        test_unit.add_c_symbol(CSymbolID('baz', Path('baz.c')))
        test_unit.add_c_symbol(CSymbolID('foo', Path('baz.c')))
        test_unit.add_c_dependency(CSymbolID('baz', Path('baz.c')), 'qux')
        test_unit.add_c_dependency(CSymbolID('baz', Path('baz.c')), 'cheese')
        assert list(iter(test_unit)) \
            == [CInfo(CSymbolID('bar', Path('bar.c')),
                      ['baz']),
                CInfo(CSymbolID('baz', Path('baz.c')),
                      ['cheese', 'qux']),
                CInfo(CSymbolID('foo', Path('baz.c'))),
                CInfo(CSymbolID('foo', Path('foo.c')),
                      ['bar'])]
        assert list(test_unit.depends_on(CSymbolID('foo',
                                                   Path('foo.c')))) \
            == [CSymbolID('bar', Path('bar.c'))]
        assert list(test_unit.depends_on(CSymbolID('foo',
                                                   Path('baz.c')))) \
            == []
        assert list(test_unit.depends_on(CSymbolID('bar',
                                                   Path('bar.c')))) \
            == [CSymbolID('baz', Path('baz.c'))]
        assert list(test_unit.depends_on(CSymbolID('baz',
                                                   Path('baz.c')))) \
            == [CSymbolUnresolvedID('qux'),
                CSymbolUnresolvedID('cheese')]

        # Remove a previously added file
        #
        test_unit.remove_c_file(Path('baz.c'))
        assert list(iter(test_unit)) \
            == [CInfo(CSymbolID('bar', Path('bar.c')),
                      ['baz']),
                CInfo(CSymbolID('foo', Path('foo.c')),
                      ['bar'])]
        assert list(test_unit.depends_on(CSymbolID('foo',
                                                   Path('foo.c')))) \
            == [CSymbolID('bar', Path('bar.c'))]
        assert list(test_unit.depends_on(CSymbolID('bar',
                                                   Path('bar.c')))) \
            == [CSymbolUnresolvedID('baz')]
Example #8
0
    def test_analyser_cbinding(self, caplog, tmp_path):
        """
        Tests that C bind procedures are correctly detected.
        """
        caplog.set_level(logging.DEBUG)

        test_file: Path = tmp_path / 'test.f90'
        test_file.write_text(
            dedent('''
                module foo

                   integer, bind(c), target, save :: quuz
                   real, bind(c, name="corge"), target, save :: varname

                   function bar() bind(c, name="bar_c")
                     implicit none
                   end function bar

                   subroutine baz(), bind(c)
                     implicit none
                   end subroutine baz

                   interface
                     function qux() bind(c, name="qux_c")
                       implicit none
                     end function qux

                     subroutine quux() bind(c)
                       implicit none
                     end subroutine quux
                   end interface
                end module foo

                   '''))

        database: SqliteStateDatabase = SqliteStateDatabase(tmp_path)
        test_unit = FortranAnalyser(tmp_path)
        test_artifact = Artifact(test_file, FortranSource, Raw)
        output_artifacts = test_unit.run([test_artifact])

        # Confirm database is updated
        # Fortran part
        working_state = FortranWorkingState(database)
        assert list(working_state) \
            == [FortranInfo(FortranUnitID('foo', tmp_path/'test.f90'),
                            ['quux', 'qux_c'])]

        # C part
        cworking_state = CWorkingState(database)
        assert list(cworking_state) \
            == [CInfo(CSymbolID('bar_c', tmp_path/'test.f90'), []),
                CInfo(CSymbolID('baz', tmp_path/'test.f90'), []),
                CInfo(CSymbolID('corge', tmp_path/'test.f90'), []),
                CInfo(CSymbolID('quuz', tmp_path/'test.f90'), [])]

        # Confirm returned Artifact is updated
        assert len(output_artifacts) == 1
        assert output_artifacts[0].defines \
            == ['foo', 'quuz', 'corge', 'bar_c', 'baz']
        assert output_artifacts[0].depends_on == ['qux_c', 'quux']
        assert output_artifacts[0].location == test_file
        assert output_artifacts[0].filetype is FortranSource
        assert output_artifacts[0].state is Analysed