Skip to content

Commit

Permalink
Issue #88. Adds pre_config.
Browse files Browse the repository at this point in the history
  • Loading branch information
kraigher committed Nov 28, 2015
1 parent c3e1271 commit d4310fe
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 91 deletions.
36 changes: 35 additions & 1 deletion vunit/test/unit/test_test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,24 @@ def test_no_post_check_when_elaborate_only(self):
self.cfg = TestConfiguration(elaborate_only=True)
scope = create_scope("lib", "entity")

def pre_config():
return True

def post_check():
return True

self.cfg.add_config(name="name",
generics=dict(),
pre_config=pre_config,
post_check=post_check,
scope=scope)

self.assertEqual(self.cfg.get_configurations(scope),
[cfg("name", pre_config=pre_config, elaborate_only=True)])

def test_config_with_post_check(self):
scope = create_scope("lib", "entity")

def post_check():
return True

Expand All @@ -148,7 +166,21 @@ def post_check():
scope=scope)

self.assertEqual(self.cfg.get_configurations(scope),
[cfg("name", elaborate_only=True)])
[cfg("name", post_check=post_check)])

def test_config_with_pre_config(self):
scope = create_scope("lib", "entity")

def pre_config():
return True

self.cfg.add_config(name="name",
generics=dict(),
pre_config=pre_config,
scope=scope)

self.assertEqual(self.cfg.get_configurations(scope),
[cfg("name", pre_config=pre_config)])

def test_sim_options(self):
scope = create_scope("lib", "entity")
Expand Down Expand Up @@ -187,6 +219,7 @@ def out(*args):

def cfg(name="", # pylint: disable=too-many-arguments
generics=None,
pre_config=None,
post_check=None,
pli=None,
disable_ieee_warnings=False,
Expand All @@ -201,4 +234,5 @@ def cfg(name="", # pylint: disable=too-many-arguments
disable_ieee_warnings=disable_ieee_warnings,
elaborate_only=elaborate_only,
options=sim_options),
pre_config=pre_config,
post_check=post_check)
224 changes: 156 additions & 68 deletions vunit/test/acceptance/test_ui.py → vunit/test/unit/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,7 @@
from re import MULTILINE
from vunit.ui import VUnit
from vunit.project import VHDL_EXTENSIONS, VERILOG_EXTENSIONS


class TestPreprocessor(object):
"""
A preprocessor that appends a check_relation call before the orginal code
"""
def __init__(self):
pass

@staticmethod
def run(code, file_name): # pylint: disable=unused-argument
return '-- check_relation(a = b);\n' + code


class VUnitfier(object):
"""
A preprocessor that replaces report statments with log calls
"""
def __init__(self):
self._report_pattern = re.compile(r'^(?P<indent>\s*)report\s*(?P<note>"[^"]*")\s*;', MULTILINE)

def run(self, code, file_name): # pylint: disable=unused-argument
return self._report_pattern.sub(
r'\g<indent>log(\g<note>); -- VUnitfier preprocessor: Report turned off, keeping original code.', code)


class ParentalControl(object):
"""
A preprocessor that replaces f..k with [BEEP]
"""
def __init__(self):
self._fword_pattern = re.compile(r'f..k')

def run(self, code, file_name): # pylint: disable=unused-argument
return self._fword_pattern.sub(r'[BEEP]', code)
from vunit.test.mock_2or3 import mock


class TestUi(unittest.TestCase):
Expand All @@ -62,20 +28,6 @@ class TestUi(unittest.TestCase):
def setUp(self):
self._output_path = join(dirname(__file__), 'ui_out')
self._preprocessed_path = join(self._output_path, "preprocessed")
self._source = Template("""
library vunit_lib;
context vunit_lib.vunit_context;
entity $entity is
end entity;
architecture arch of $entity is
begin
log("Hello World");
check_relation(1 /= 2);
report "Here I am!";
end architecture;
""")

def tearDown(self):
pass
Expand All @@ -85,6 +37,9 @@ def _create_ui(self):
ui = VUnit.from_argv(argv=["--output-path=%s" % self._output_path,
"--clean"])
ui.add_library('lib')

mocksim = MockSimulatorFactory(self._output_path)
ui._simulator_factory = mocksim # pylint: disable=protected-access
return ui

def _create_temp_files(self, num_files, file_suffix='.vhd'):
Expand All @@ -93,11 +48,33 @@ def _create_temp_files(self, num_files, file_suffix='.vhd'):
same source code but with different entity names depending on
the index
"""
files = [None] * num_files
for i in range(num_files):
with NamedTemporaryFile(mode='w', suffix=file_suffix, delete=False) as files[i]:
files[i].write(self._source.substitute(entity='foo%d' % i))
return files
return [self._create_temp_file(i, file_suffix) for i in xrange(num_files)]

@staticmethod
def _create_temp_file(idx, file_suffix='.vhd'):
"""
Create and a temporary file containing the same source code
but with different entity names depending on the index
"""
source = Template("""
library vunit_lib;
context vunit_lib.vunit_context;
entity $entity is
end entity;
architecture arch of $entity is
begin
log("Hello World");
check_relation(1 /= 2);
report "Here I am!";
end architecture;
""")

fptr = NamedTemporaryFile(mode='w', suffix=file_suffix, delete=False)
fptr.write(source.substitute(entity='foo%d' % idx))
fptr.close()
return fptr

@staticmethod
def _delete_temp_files(files):
Expand Down Expand Up @@ -205,10 +182,10 @@ def test_supported_source_file_suffixes(self):
allowable_extensions.extend([ext.upper() for ext in accepted_extensions])
allowable_extensions.append(VHDL_EXTENSIONS[0][0] + VHDL_EXTENSIONS[0][1].upper() +
VHDL_EXTENSIONS[0][2:]) # mixed case
for ext in allowable_extensions:
files = self._create_temp_files(1, ext)
ui.add_source_files(files[0].name, 'lib')
self._delete_temp_files(files)
for idx, ext in enumerate(allowable_extensions):
fptr = self._create_temp_file(idx, ext)
ui.add_source_files(fptr.name, 'lib')
self._delete_temp_files([fptr])

def test_unsupported_source_file_suffixes(self):
"""Test adding an unsupported filetype is rejected"""
Expand All @@ -218,17 +195,128 @@ def test_unsupported_source_file_suffixes(self):
self.assertRaises(RuntimeError, ui.add_source_files, files[0].name, 'lib')
self._delete_temp_files(files)

def test_can_add_non_ascii_encoded_files(self):
ui = self._create_ui()
lib = ui.library("lib")
lib.add_source_files(join(dirname(__file__), 'test_ui_encoding.vhd'))
lib.entity("encoding") # Fill raise exception of not found

class TestUiEncoding(unittest.TestCase):
def test_entity_has_pre_config(self):
for retval in (True, False, None):
ui = self._create_ui()
lib = ui.library("lib")
lib.add_source_files(join(dirname(__file__), 'test_ui_tb.vhd'))
entity = lib.entity("test_ui_tb")

pre_config = mock.Mock()
pre_config.return_value = retval

entity.add_config(name="", pre_config=pre_config)
try:
ui.main()
except SystemExit as exc:
if retval is True:
self.assertEqual(exc.code, 0)
else:
self.assertEqual(exc.code, 1)

pre_config.assert_has_calls([call(), call()])

def test_test_has_pre_config(self):
ui = self._create_ui()
lib = ui.library("lib")
lib.add_source_files(join(dirname(__file__), 'test_ui_tb.vhd'))
test = lib.entity("test_ui_tb").test("test_one")

pre_config = mock.Mock()
pre_config.return_value = True

test.add_config(name="", pre_config=pre_config)
try:
ui.main()
except SystemExit as exc:
self.assertEqual(exc.code, 0)

pre_config.assert_has_calls([call()])


def call(*args, **kwargs):
"""
Test reading non ASCII encoded file
To create call objects for checking calls on mock objects
"""
def setUp(self):
self._output_path = join(dirname(__file__), 'ui_out')
return (args, kwargs)

def test_can_add_non_ascii_encoded_files(self):
ui = VUnit.from_argv(argv=["--output-path=%s" % self._output_path,
"--clean"])
lib = ui.add_library('lib')
lib.add_source_files(join(dirname(__file__), 'encoding', 'encoding.vhd'))
lib.entity("encoding") # Fill raise exception of not found

class TestPreprocessor(object):
"""
A preprocessor that appends a check_relation call before the orginal code
"""
def __init__(self):
pass

@staticmethod
def run(code, file_name): # pylint: disable=unused-argument
return '-- check_relation(a = b);\n' + code


class VUnitfier(object):
"""
A preprocessor that replaces report statments with log calls
"""
def __init__(self):
self._report_pattern = re.compile(r'^(?P<indent>\s*)report\s*(?P<note>"[^"]*")\s*;', MULTILINE)

def run(self, code, file_name): # pylint: disable=unused-argument
return self._report_pattern.sub(
r'\g<indent>log(\g<note>); -- VUnitfier preprocessor: Report turned off, keeping original code.', code)


class ParentalControl(object):
"""
A preprocessor that replaces f..k with [BEEP]
"""
def __init__(self):
self._fword_pattern = re.compile(r'f..k')

def run(self, code, file_name): # pylint: disable=unused-argument
return self._fword_pattern.sub(r'[BEEP]', code)


class MockSimulatorFactory(object):
"""
Mock a simulator factory
"""
simulator_name = "mocksim"

def __init__(self, output_path):
self._output_path = output_path
self._mocksim = MockSimulator()

@property
def simulator_output_path(self):
return join(self._output_path, self.simulator_name)

@staticmethod
def package_users_depend_on_bodies():
return True

def create(self):
return self._mocksim


class MockSimulator(object):
"""
Mock a simulator
"""

@staticmethod
def compile_project(project, vhdl_standard): # pylint: disable=unused-argument
return True

def post_process(self, output_path): # pylint: disable=unused-argument
pass

# pylint: disable=too-many-arguments,unused-argument
@staticmethod
def simulate(output_path, library_name, entity_name, architecture_name, config):
return True
File renamed without changes.
29 changes: 29 additions & 0 deletions vunit/test/unit/test_ui_tb.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- Log package provides the primary functionality of the logging library.
--
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
-- You can obtain one at http://mozilla.org/MPL/2.0/.
--
-- Copyright (c) 2014-2015, Lars Asplund lars.anders.asplund@gmail.com

library vunit_lib;
context vunit_lib.vunit_context;

entity test_ui_tb is
generic (runner_cfg : runner_cfg_t);
end entity;

architecture tb of test_ui_tb is
begin

main : process
begin
test_runner_setup(runner, runner_cfg);
if run("test_one") then
report "one";
elsif run("test_two") then
report "two";
end if;
test_runner_cleanup(runner);
end process;
end architecture;
Loading

0 comments on commit d4310fe

Please sign in to comment.