diff options
author | tgingold <tgingold@users.noreply.github.com> | 2020-12-29 17:19:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-29 17:19:09 +0100 |
commit | 7ca54117b8f757396ba5ef04c83ff1228ca94384 (patch) | |
tree | cc5f7f4166cc0570bda5cf2047d3ef7abbc36e37 /testsuite | |
parent | 340fc792bba2ffdb4f930bc427a39ea3a1b659b2 (diff) | |
parent | 50adcf884c3cfa4e33ca45769295f163baa63a3e (diff) | |
download | ghdl-7ca54117b8f757396ba5ef04c83ff1228ca94384.tar.gz ghdl-7ca54117b8f757396ba5ef04c83ff1228ca94384.tar.bz2 ghdl-7ca54117b8f757396ba5ef04c83ff1228ca94384.zip |
Merge pull request #1556 from Paebbels/paebbels/pyGHDL
Cleanup and Restructuring of pyGHDL
Diffstat (limited to 'testsuite')
-rwxr-xr-x | testsuite/python/testsuite.sh | 53 | ||||
-rw-r--r-- | testsuite/python/units01/demo.vhdl | 12 | ||||
-rw-r--r-- | testsuite/python/units01/show_ports.py | 111 | ||||
-rwxr-xr-x | testsuite/python/units01/show_units.py | 55 | ||||
-rwxr-xr-x | testsuite/python/units01/testsuite.sh | 11 | ||||
-rw-r--r-- | testsuite/pyunit/SimpleEntity.vhdl | 27 | ||||
-rw-r--r-- | testsuite/pyunit/SimplePackage.vhdl | 21 | ||||
-rw-r--r-- | testsuite/pyunit/__init__.py | 14 | ||||
-rw-r--r-- | testsuite/pyunit/dom/SimpleEntity.py | 46 | ||||
-rw-r--r-- | testsuite/pyunit/dom/__init__.py | 13 | ||||
-rw-r--r-- | testsuite/pyunit/libghdl/Initialize.py | 62 | ||||
-rw-r--r-- | testsuite/pyunit/libghdl/__init__.py | 13 | ||||
-rw-r--r-- | testsuite/requirements.txt | 4 | ||||
-rwxr-xr-x | testsuite/testsuite.sh | 16 |
14 files changed, 213 insertions, 245 deletions
diff --git a/testsuite/python/testsuite.sh b/testsuite/python/testsuite.sh deleted file mode 100755 index 12b367f2c..000000000 --- a/testsuite/python/testsuite.sh +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/sh - -# Driver for a testsuite. - -set -e - -# This is the only place where test dirs are specified. Do not duplicate this -# line -dirs="*[0-9]" - -failures="" -full=n - -for opt; do - case "$opt" in - -k | --keep-going) full=y ;; - --dir=*) dirs=`echo $opt | sed -e 's/--dir=//'` ;; - --skip=*) d=`echo $opt | sed -e 's/--skip=//'` - dirs=`echo "" $dirs | sed -e "s/ $d//"` ;; - --start-at=*) d=`echo $opt | sed -e 's/--start-at=//'` - dirs=`echo "" $dirs | sed -e "s/^.* $d//"` - dirs="$d $dirs" ;; - --list-tests) echo $dirs; exit 0;; - *) echo "Unknown option $opt" - exit 2 - ;; - esac -done - -singlerun() { - echo "" - echo "dir $1:" - cd $1 - if ! ./testsuite.sh; then - echo "#################################################################" - echo "######### FAILURE: $1" - echo "#################################################################" - if [ $2 = "y" ]; then - failures="$failures $1" - else - exit 1; - fi - fi - cd .. -} - -for i in $dirs; do singlerun $i $full; done - -if [ x"$failures" = x"" ]; then - echo "tests are successful" && exit 0 -else - echo "test failed ($failures)" && exit 1 -fi diff --git a/testsuite/python/units01/demo.vhdl b/testsuite/python/units01/demo.vhdl deleted file mode 100644 index ed98c936a..000000000 --- a/testsuite/python/units01/demo.vhdl +++ /dev/null @@ -1,12 +0,0 @@ -entity e1 is -port ( - CLK: in std_logic; - RST: in std_logic; - Q: out std_logic_vector(7 downto 0) -); -end e1; - -architecture behav of e1 is -begin - assert false report "arch" severity note; -end behav; diff --git a/testsuite/python/units01/show_ports.py b/testsuite/python/units01/show_ports.py deleted file mode 100644 index a11f2acbd..000000000 --- a/testsuite/python/units01/show_ports.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -from sys import argv -from pathlib import Path - -import libghdl -from libghdl.thin import name_table -from libghdl.thin import files_map -from libghdl.thin.vhdl import nodes -from libghdl.thin.vhdl import sem_lib -from libghdl.thin.vhdl import pyutils -from libghdl.thin import errorout_console - - -def get_identifier_ptr(n): - """Return the python string from node :param n: identifier""" - return name_table.Get_Name_Ptr(nodes.Get_Identifier(n)).decode("utf-8") - - -def get_port_mode(port) -> str: - """Return the Mode of a port, as a string""" - mode = nodes.Get_Mode(port) - return ( - "in" - if mode == nodes.Iir_Mode.In_Mode - else "out" - if mode == nodes.Iir_Mode.Out_Mode - else "inout" - if mode == nodes.Iir_Mode.Inout_Mode - else "buffer" - if mode == nodes.Iir_Mode.Buffer_Mode - else "linkage" - if mode == nodes.Iir_Mode.Linkage_Mode - else "unknown" - ) - - -def get_port_type(port) -> str: - "Return the Type of a port, as a string" - subtype = nodes.Get_Subtype_Indication(port) - skind = nodes.Get_Kind(subtype) - - if skind == nodes.Iir_Kind.Simple_Name: - return get_identifier_ptr(subtype) - - if skind == nodes.Iir_Kind.Array_Subtype_Definition: - mark = get_identifier_ptr(nodes.Get_Subtype_Type_Mark(subtype)) - - for rng in pyutils.flist_iter(nodes.Get_Index_Constraint_List(subtype)): - if nodes.Get_Kind(rng) == nodes.Iir_Kind.Range_Expression: - return "%s(%d %s %d)" % ( - mark, - nodes.Get_Value(nodes.Get_Left_Limit_Expr(rng)), - "downto" if nodes.Get_Direction(rng) else "to", - nodes.Get_Value(nodes.Get_Right_Limit_Expr(rng)), - ) - return "UNSUPPORTED array_subtype_definition" - - return "UNSUPPORTED" - - -def list_units(filename): - # Load the file - file_id = name_table.Get_Identifier(filename.encode("utf_8")) - sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id) - if sfe == files_map.No_Source_File_Entry: - print("cannot open file '%s'" % filename) - return - - # Parse - file = sem_lib.Load_File(sfe) - - # Display all design units - unit = nodes.Get_First_Design_Unit(file) - while unit != nodes.Null_Iir: - lib_unit = nodes.Get_Library_Unit(unit) - if nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Entity_Declaration: - print(" - entity %s" % get_identifier_ptr(lib_unit)) - for port in pyutils.chain_iter(nodes.Get_Port_Chain(lib_unit)): - print( - " * %s %s %s" - % ( - get_identifier_ptr(port), - get_port_mode(port), - get_port_type(port), - ) - ) - elif nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Architecture_Body: - print( - " - architecture %s of %s" - % ( - get_identifier_ptr(lib_unit), - get_identifier_ptr(nodes.Get_Entity_Name(lib_unit)), - ) - ) - else: - print("unknown unit!") - unit = nodes.Get_Chain(unit) - - -if __name__ == "__main__": - # Initialization: set options and then load libaries - errorout_console.Install_Handler() - libghdl.set_option(b"--std=08") - if libghdl.analyze_init_status() != 0: - raise Exception("libghdl initialization error") - - # Recursively find and parse all the files with extension *.vhdl - if len(argv) > 1: - for file in Path(argv[1]).glob("**/*.vhdl"): - print("ยท %s" % file) - list_units(str(file)) diff --git a/testsuite/python/units01/show_units.py b/testsuite/python/units01/show_units.py deleted file mode 100755 index 43baf9aed..000000000 --- a/testsuite/python/units01/show_units.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -import libghdl -from libghdl.thin import name_table -from libghdl.thin import files_map -from libghdl.thin.vhdl import nodes -from libghdl.thin.vhdl import sem_lib -from libghdl.thin import errorout_console - - -def init(): - """Initialization: set options and then load libaries""" - # Print error messages on the console - errorout_console.Install_Handler() - # Set options. This must be done before analyze_init() - libghdl.set_option(b"--std=08") - # Finish initialization. This will load the standard package - if libghdl.analyze_init_status() != 0: - raise Exception("libghdl initialization error") - -def get_identifier_ptr(n): - """Return the python string from node :param n: identifier""" - return name_table.Get_Name_Ptr(nodes.Get_Identifier(n)).decode("utf-8") - - -def list_units(filename): - # Load the file - file_id = name_table.Get_Identifier(filename.encode("utf_8")) - sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id) - if sfe == files_map.No_Source_File_Entry: - print("cannot open file '%s'" % filename) - return - - # Parse - file = sem_lib.Load_File(sfe) - - # Display all design units - unit = nodes.Get_First_Design_Unit(file) - while unit != nodes.Null_Iir: - lib_unit = nodes.Get_Library_Unit(unit) - if nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Entity_Declaration: - print("entity %s" % get_identifier_ptr(lib_unit)) - elif nodes.Get_Kind(lib_unit) == nodes.Iir_Kind.Architecture_Body: - print("architecture %s" % get_identifier_ptr(lib_unit)) - else: - print("unknown unit!") - unit = nodes.Get_Chain(unit) - - -def main(): - init() - list_units("demo.vhdl") - - -if __name__ == "__main__": - main() diff --git a/testsuite/python/units01/testsuite.sh b/testsuite/python/units01/testsuite.sh deleted file mode 100755 index f45d12ac3..000000000 --- a/testsuite/python/units01/testsuite.sh +++ /dev/null @@ -1,11 +0,0 @@ -#! /bin/sh - -. ../../testenv.sh - -$PYTHON show_units.py - -echo "" - -$PYTHON show_ports.py ./ - -echo "Test successful" diff --git a/testsuite/pyunit/SimpleEntity.vhdl b/testsuite/pyunit/SimpleEntity.vhdl new file mode 100644 index 000000000..a26a6357c --- /dev/null +++ b/testsuite/pyunit/SimpleEntity.vhdl @@ -0,0 +1,27 @@ +library ieee; +use ieee.numeric_std.all; + +entity e1 is + generic ( + BITS : positive := 8 + ); + port ( + Clock: in std_logic; + Reset: in std_logic; + Q: out std_logic_vector(BITS - 1 downto 0) + ); +end entity e1; + +architecture behav of e1 is +begin + process(Clock) + begin + if rising_edge(Clock) then + if Reset = '1' then + Q <= (others => '0'); + else + Q <= std_logic_vector(unsigned(Q) + 1); + end if; + end if; + end process; +end architecture behav; diff --git a/testsuite/pyunit/SimplePackage.vhdl b/testsuite/pyunit/SimplePackage.vhdl new file mode 100644 index 000000000..f06cc32fa --- /dev/null +++ b/testsuite/pyunit/SimplePackage.vhdl @@ -0,0 +1,21 @@ +library ieee; +use ieee.numeric_std.all + +package pack_1 is + constant const_1 : boolean; + + type matrix is array(natural range <>, natural range <>) of std_logic; + + subtype matrix8x8 is matrix(7 downto 0, 7 downto 0); + + function func1(value : unsigned) return natural; +end package; + +package body pack_1 is + constant const_1 : boolean := true; + + function func1(value : unsigned) return natural is + begin + return to_integer(value); + end function; +end package body; diff --git a/testsuite/pyunit/__init__.py b/testsuite/pyunit/__init__.py new file mode 100644 index 000000000..eff53eb2f --- /dev/null +++ b/testsuite/pyunit/__init__.py @@ -0,0 +1,14 @@ +from unittest import TestSuite + +try: + from testsuite.pyunit import libghdl, dom +except ModuleNotFoundError: + from pyunit import libghdl, dom + +def load_tests(loader, testCases, pattern): + suite = TestSuite() + + suite.addTests(loader.loadTestsFromModule(libghdl)) + suite.addTests(loader.loadTestsFromModule(dom)) + + return suite diff --git a/testsuite/pyunit/dom/SimpleEntity.py b/testsuite/pyunit/dom/SimpleEntity.py new file mode 100644 index 000000000..2f65c9813 --- /dev/null +++ b/testsuite/pyunit/dom/SimpleEntity.py @@ -0,0 +1,46 @@ +from pathlib import Path +from unittest import TestCase + +from pyGHDL.dom.Misc import Design, Library, Document + + +if __name__ == "__main__": + print("ERROR: you called a testcase declaration file as an executable module.") + print("Use: 'python -m unitest <testcase module>'") + exit(1) + + +class SimpleEntity(TestCase): + _root = Path(__file__).resolve().parent.parent + _filename : Path = _root / "SimpleEntity.vhdl" + + def test_Design(self): + design = Design() + + self.assertIsNotNone(design) + + # def test_Library(self): + # library = Library() + + def test_Document(self): + design = Design() + document = Document(self._filename) + design.Documents.append(document) + + self.assertTrue(len(design.Documents) == 1) + + def test_Entity(self): + design = Design() + document = Document(self._filename) + design.Documents.append(document) + + self.assertEqual(len(design.Documents[0].Entities), 1) + self.assertTrue(design.Documents[0].Entities[0].Name == "e1") + + def test_Architecture(self): + design = Design() + document = Document(self._filename) + design.Documents.append(document) + + self.assertEqual(len(design.Documents[0].Architectures), 1) + self.assertTrue(design.Documents[0].Architectures[0].Name == "behav") diff --git a/testsuite/pyunit/dom/__init__.py b/testsuite/pyunit/dom/__init__.py new file mode 100644 index 000000000..9c103eb6a --- /dev/null +++ b/testsuite/pyunit/dom/__init__.py @@ -0,0 +1,13 @@ +from unittest import TestSuite + +try: + from testsuite.pyunit.dom import SimpleEntity +except ModuleNotFoundError: + from pyunit.dom import SimpleEntity + +def load_tests(loader, testCases, pattern): + suite = TestSuite() + + suite.addTests(loader.loadTestsFromModule(SimpleEntity)) + + return suite diff --git a/testsuite/pyunit/libghdl/Initialize.py b/testsuite/pyunit/libghdl/Initialize.py new file mode 100644 index 000000000..0a46fe8b4 --- /dev/null +++ b/testsuite/pyunit/libghdl/Initialize.py @@ -0,0 +1,62 @@ +from pathlib import Path +from unittest import TestCase + +import pyGHDL.libghdl as libghdl +from pyGHDL.libghdl import name_table, files_map, errorout_console +from pyGHDL.libghdl.vhdl import nodes, sem_lib + + +if __name__ == "__main__": + print("ERROR: you called a testcase declaration file as an executable module.") + print("Use: 'python -m unitest <testcase module>'") + exit(1) + + +class Instantiate(TestCase): + _root = Path(__file__).resolve().parent.parent + _filename : Path = _root / "SimpleEntity.vhdl" + + @staticmethod + def getIdentifier(node): + """Return the Python string from node :param:`node` identifier""" + return name_table.Get_Name_Ptr(nodes.Get_Identifier(node)).decode("utf-8") + + def test_InitializeGHDL(self) -> None: + """Initialization: set options and then load libaries""" + + # Print error messages on the console. + errorout_console.Install_Handler() + + # Set options. This must be done before analyze_init() + libghdl.set_option(b"--std=08") + + # Finish initialization. This will load the standard package. + if libghdl.analyze_init_status() != 0: + self.fail("libghdl initialization error") + + # Load the file + file_id = name_table.Get_Identifier(str(self._filename).encode("utf_8")) + sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id) + if sfe == files_map.No_Source_File_Entry: + self.fail("Cannot read file '{!s}'".format(self._filename)) + + # Parse + file = sem_lib.Load_File(sfe) + + # Display all design units + designUnit = nodes.Get_First_Design_Unit(file) + while designUnit != nodes.Null_Iir: + libraryUnit = nodes.Get_Library_Unit(designUnit) + + if nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Entity_Declaration: + entityName = self.getIdentifier(libraryUnit) + self.assertEqual(entityName, "e1", "expected entity name 'e1', got '{}'".format(entityName)) + + elif nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Architecture_Body: + architectureName = self.getIdentifier(libraryUnit) + self.assertEqual(architectureName, "behav", "expected architecture name 'behav', got '{}'".format(architectureName)) + + else: + self.fail("Unknown unit.") + + designUnit = nodes.Get_Chain(designUnit) diff --git a/testsuite/pyunit/libghdl/__init__.py b/testsuite/pyunit/libghdl/__init__.py new file mode 100644 index 000000000..4aeab3ec3 --- /dev/null +++ b/testsuite/pyunit/libghdl/__init__.py @@ -0,0 +1,13 @@ +from unittest import TestSuite + +try: + from testsuite.pyunit.libghdl import Initialize +except ModuleNotFoundError: + from pyunit.libghdl import Initialize + +def load_tests(loader, testCases, pattern): + suite = TestSuite() + + suite.addTests(loader.loadTestsFromModule(Initialize)) + + return suite diff --git a/testsuite/requirements.txt b/testsuite/requirements.txt new file mode 100644 index 000000000..ce54b669b --- /dev/null +++ b/testsuite/requirements.txt @@ -0,0 +1,4 @@ +-r ../pyGHDL/requirements.txt + +# Coverage collection +Coverage>=5.3 diff --git a/testsuite/testsuite.sh b/testsuite/testsuite.sh index fd686ccd0..55c2ff9fb 100755 --- a/testsuite/testsuite.sh +++ b/testsuite/testsuite.sh @@ -112,7 +112,7 @@ do_sanity () { [ "$failures" = "" ] || exit 1 } -# The GNA testsuite: regression testsuite using reports/issues from gna.org +# The GNA testsuite: regression testsuite using reports/issues from gna.org and from GitHub do_gna () { gstart "[GHDL - test] gna" cd gna @@ -138,6 +138,15 @@ do_gna () { [ "$failures" = "" ] || exit 1 } +# The Python Unit testsuite: regression testsuite for Python bindings to libghdl +do_pyunit () { + gstart "[GHDL - test] pyunit" + cd .. + PYTHONPATH=$(pwd) python3 -m unittest testsuite.pyunit.libghdl.Initialize + cd testsuite + gend +} + # The VESTS testsuite: compliance testsuite, from: https://github.com/nickg/vests.git 388250486a do_vests () { gstart "[GHDL - test] vests" @@ -226,7 +235,7 @@ for opt; do esac done -if [ "x$tests" = "x" ]; then tests="sanity gna vests synth vpi"; fi +if [ "x$tests" = "x" ]; then tests="sanity pyunit gna vests synth vpi"; fi echo "tests: $tests" @@ -234,10 +243,11 @@ echo "tests: $tests" do_test() { case $1 in sanity) do_sanity;; + pyunit) do_pyunit;; gna) do_gna;; vests) do_vests;; synth) do_synth;; - vpi) do_vpi;; + vpi) do_vpi;; *) printf "${ANSI_RED}$0: test name '$1' is unknown${ANSI_NOCOLOR}\n" exit 1;; |