Example #1
0
    def test_no_json_yaml_precedence(self) -> None:
        """
        Test that neither JSON nor YAML take precedence over each other.
        """
        yfp, ypath = tempfile.mkstemp(".yml")
        with open(ypath, 'w') as fy:
            fy.write("""
foo.bar: "i'm yaml"
""")
        jfp, jpath = tempfile.mkstemp(".json")
        with open(jpath, 'w') as fj:
            fj.write("""
{
    "foo.bar": "i'm json"
}
""")
        db1 = hammer_config.HammerDatabase()
        configs = hammer_config.load_config_from_paths([ypath, jpath])
        db1.update_core([hammer_config.combine_configs(configs)])
        self.assertEqual(db1.get_setting("foo.bar"), "i'm json")

        db2 = hammer_config.HammerDatabase()
        configs = hammer_config.load_config_from_paths([jpath, ypath])
        db2.update_core([hammer_config.combine_configs(configs)])
        self.assertEqual(db2.get_setting("foo.bar"), "i'm yaml")
Example #2
0
    def test_multiple_lazy_metas(self) -> None:
        """
        Test multiple lazy metas applied at once.
        Note that this is unsupported at the moment.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
hello1: "abc"
hello2: "def"
base: "hello1"
test: "${base}"
test_meta: ["lazysubst", "lazycrossref"]
    """,
                                                     is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
    "base": "hello2"
}
    """,
                                                     is_yaml=False)
        db.update_core([base, meta])
        with self.assertRaises(ValueError) as cm:
            self.assertEqual(db.get_setting("base"), "hello2")
            self.assertEqual(db.get_setting("test"), "def")
        msg = cm.exception.args[0]
        self.assertTrue(
            "Multiple lazy directives in a single directive array not supported yet"
            in msg)
Example #3
0
    def test_meta_prependlocal(self):
        """
        Test that the meta attribute "prependlocal" works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    bar:
        adc: "yes"
        dac: "no"
        dsl: ["scala"]
        base_test: "local_path"
        base_test_meta: prependlocal
""", is_yaml=True, path="base/config/path")
        meta = hammer_config.load_config_from_string("""
{
  "foo.bar.dsl": ["python"],
  "foo.bar.dsl_meta": "append",
  "foo.bar.dac": "current_weighted",
  "foo.bar.meta_test": "local_path",
  "foo.bar.meta_test_meta": "prependlocal"
}
""", is_yaml=False, path="meta/config/path")
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("foo.bar.dac"), "current_weighted")
        self.assertEqual(db.get_setting("foo.bar.dsl"), ["scala", "python"])
        self.assertEqual(db.get_setting("foo.bar.base_test"), "base/config/path/local_path")
        self.assertEqual(db.get_setting("foo.bar.meta_test"), "meta/config/path/local_path")
Example #4
0
    def test_meta_transclude_prependlocal(self):
        """
        Test that the meta attribute "transclude" works with "prependlocal".
        """
        # Put some text into the file.
        file_contents = "The quick brown fox jumps over the lazy dog"
        local_path = "meta/config/path"
        fd, path = tempfile.mkstemp(".txt")
        with open(path, "w") as f:
            f.write(file_contents)

        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
chips:
    potato: tuber
    bear: "yeah"
""", is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
  "chips.tree": "<path>",
  "chips.tree_meta": ["transclude", "prependlocal"]
}
""".replace("<path>", path), is_yaml=False, path=local_path)

        db.update_core([base, meta])

        # Trigger merge before cleanup
        self.assertEqual(db.get_setting("chips.potato"), "tuber")

        # Cleanup
        os.remove(path)

        self.assertEqual(db.get_setting("chips.bear"), "yeah")
        self.assertEqual(db.get_setting("chips.tree"), os.path.join(local_path, file_contents))
Example #5
0
    def test_meta_lazysubst_other_lazysubst(self) -> None:
        """
        Check that a lazysubst which references other lazysubst works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    flash: "yes"
    one: "1"
    two: "2"
    lolcat: ""
    twelve: "${lolcat}"
    twelve_meta: lazysubst
    """,
                                                     is_yaml=True)
        project = hammer_config.load_config_from_string("""
{
  "lolcat": "whatever",
  "later": "${foo.twelve}",
  "later_meta": "lazysubst"
}
    """,
                                                        is_yaml=False)
        db.update_core([base])
        db.update_project([project])
        self.assertEqual(db.get_setting("lolcat"), "whatever")
        self.assertEqual(db.get_setting("foo.twelve"), "whatever")
        self.assertEqual(db.get_setting("later"), "whatever")
Example #6
0
    def test_self_reference_lazycrossref(self) -> None:
        """
        Test that self-referencing lazy crossref works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
base: "hello"
derivative: "base"
derivative_meta: "lazycrossref"
        """,
                                                     is_yaml=True)
        config1 = hammer_config.load_config_from_string("""
{
    "derivative": "derivative",
    "derivative_meta": "lazycrossref"
}
        """,
                                                        is_yaml=True)
        config2 = hammer_config.load_config_from_string("""
{
    "base": "tower",
    "derivative": "derivative",
    "derivative_meta": "lazycrossref"
}
        """,
                                                        is_yaml=True)
        db.update_core([base, config1, config2])
        self.assertEqual(db.get_setting("base"), "tower")
Example #7
0
    def test_self_reference_lazyappend(self) -> None:
        """
        Test that lazy "append" works.
        Note that append is always self-referencing.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
global: ["hello", "world"]
""",
                                                     is_yaml=True)
        config1 = hammer_config.load_config_from_string("""
{
  "global": ["scala"],
  "global_meta": "lazyappend"
}
""",
                                                        is_yaml=False)
        config2 = hammer_config.load_config_from_string("""
{
  "global": ["python"],
  "global_meta": "lazyappend"
}
""",
                                                        is_yaml=False)
        db.update_core([base, config1])
        db.update_project([config2])
        self.assertEqual(db.get_setting("global"),
                         ["hello", "world", "scala", "python"])
Example #8
0
    def test_meta_lazycrossappendref_prepend_local(self) -> None:
        """
        Test that lazy crossappendref works to prepend the local path.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
# These lines are present to test that the dependency graph with
# crossappendref is correct.
# If crossappendref doesn't declare a dependency, aaa* might not be recognized
# as a dependency of test.
aaa0: "tmp.tmptmp"
aaa0_meta: lazycrossref
aaa1: "tmp.tmptmp"
aaa1_meta: lazycrossref
test: ["aaa0", "aaa1"]
test_meta: "lazycrossappendref"

base: ["bin", "usr_bin"]
tmp.tmptmp2: "myfolder"
tmp.tmptmp2_meta: "prependlocal"
tmp.tmptmp: ["tmp.tmptmp2"]
tmp.tmptmp_meta: "lazycrossref"
paths: ["base", "tmp.tmptmp"]
paths_meta: "lazycrossappendref"
""",
                                                     is_yaml=True,
                                                     path="opt")
        db.update_core([base])
        self.assertEqual(db.get_setting("base"), ["bin", "usr_bin"])
        self.assertEqual(db.get_setting("paths"),
                         ["bin", "usr_bin", "opt/myfolder"])
        self.assertEqual(db.get_setting("test"),
                         ["opt/myfolder", "opt/myfolder"])
Example #9
0
    def test_self_reference_lazysubst(self) -> None:
        """
        Test that self-referencing lazy subst works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
base_str: "hello"
derivative_str: "${base_str}"
derivative_str_meta: "lazysubst"
        """,
                                                     is_yaml=True)
        config1 = hammer_config.load_config_from_string("""
{
    "derivative_str": "${derivative_str}_1",
    "derivative_str_meta": "lazysubst"
}
        """,
                                                        is_yaml=True)
        config2 = hammer_config.load_config_from_string("""
{
    "derivative_str": "${derivative_str}_2",
    "derivative_str_meta": "lazysubst"
}
        """,
                                                        is_yaml=True)
        db.update_core([base, config1, config2])
        self.assertEqual(db.get_setting("derivative_str"), "hello_1_2")
Example #10
0
    def test_tarballs_not_extracted(self) -> None:
        """
        Test that tarballs that are not pre-extracted work fine.
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir(
            "dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")

        # Add defaults to specify tarball_dir.
        with open(os.path.join(tech_dir, "defaults.json"), "w") as f:
            f.write(json.dumps({"technology.dummy28.tarball_dir": tech_dir}))

        HammerToolTestHelpers.write_tech_json(tech_json_filename,
                                              self.add_tarballs)
        tech = self.get_tech(
            hammer_tech.HammerTechnology.load_from_dir("dummy28", tech_dir))
        tech.cache_dir = tech_dir

        database = hammer_config.HammerDatabase()
        database.update_technology(tech.get_config())
        HammerVLSISettings.load_builtins_and_core(database)
        tech.set_database(database)
        outputs = tech.process_library_filter(
            pre_filts=[],
            filt=hammer_tech.filters.gds_filter,
            must_exist=False,
            output_func=lambda str, _: [str])

        self.assertEqual(
            outputs, ["{0}/extracted/foobar.tar.gz/test.gds".format(tech_dir)])

        # Cleanup
        shutil.rmtree(tech_dir_base)
Example #11
0
    def test_meta_dynamicsubst_other_dynamicsubst(self):
        """
        Check that a dynamicsubst which references other dynamicsubst errors for now.
        """
        """
        Test that the meta attribute "dynamicsubst" works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    flash: "yes"
    one: "1"
    two: "2"
    lolcat: ""
    twelve: "${lolcat}"
    twelve_meta: dynamicsubst
""", is_yaml=True)
        project = hammer_config.load_config_from_string("""
{
  "lolcat": "whatever",
  "later": "${foo.twelve}",
  "later_meta": "dynamicsubst"
}
""", is_yaml=False)
        db.update_core([base])
        db.update_project([project])
        with self.assertRaises(ValueError):
            print(db.get_config())
Example #12
0
    def test_meta_crossref(self) -> None:
        """
        Test that the meta attribute "crossref" works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
my:
    numbers: ["1", "2", "3"]
    dichotomy: false
    unity: true
    world: ["world"]
"target_key": "my.dichotomy"
""",
                                                     is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
  "just.numbers": "my.numbers",
  "just.numbers_meta": "crossref",
  "copies.numbers": ["my.numbers", "my.world"],
  "copies.numbers_meta": "crossref",
  "bools": ["my.dichotomy", "my.unity"],
  "bools_meta": "crossref",
  "indirect.numbers": "${target_key}",
  "indirect.numbers_meta": ["subst", "crossref"]
}
""",
                                                     is_yaml=False)
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("just.numbers"), ["1", "2", "3"])
        self.assertEqual(db.get_setting("copies.numbers"),
                         [["1", "2", "3"], ["world"]])
        self.assertEqual(db.get_setting("bools"), [False, True])
        self.assertEqual(db.get_setting("indirect.numbers"), False)
Example #13
0
    def test_meta_transclude_subst(self):
        """
        Test that the meta attribute "transclude" works with "subst".
        """
        # Put some text into the file.
        file_contents = "I like ${food.condiment} on my ${food.dish}."
        file_contents_sol = "I like monosodium monochloride on my chips."
        local_path = "meta/config/path"
        fd, path = tempfile.mkstemp(".txt")
        with open(path, "w") as f:
            f.write(file_contents)

        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
food:
    condiment: "monosodium monochloride"
    dish: "chips"
""", is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
  "food.announcement": "<path>",
  "food.announcement_meta": ["transclude", "subst"]
}
""".replace("<path>", path), is_yaml=False, path=local_path)

        db.update_core([base, meta])

        # Trigger merge before cleanup
        self.assertEqual(db.get_setting("food.dish"), "chips")

        # Cleanup
        os.remove(path)

        self.assertEqual(db.get_setting("food.announcement"), file_contents_sol)
Example #14
0
    def test_meta_subst(self) -> None:
        """
        Test that the meta attribute "subst" works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    flash: "yes"
    one: "1"
    two: "2"
""",
                                                     is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
  "foo.pipeline": "${foo.flash}man",
  "foo.pipeline_meta": "subst",
  "foo.uint": ["${foo.one}", "${foo.two}"],
  "foo.uint_meta": "subst"
}
""",
                                                     is_yaml=False)
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("foo.flash"), "yes")
        self.assertEqual(db.get_setting("foo.pipeline"), "yesman")
        self.assertEqual(db.get_setting("foo.uint"), ["1", "2"])
Example #15
0
    def test_stackup(self) -> None:
        """
        Test that getting the stackup works as expected.
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir(
            "dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")

        test_stackup = StackupTestHelper.create_test_stackup_dict(10)

        def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]:
            out_dict = deepdict(in_dict)
            out_dict.update({"stackups": [test_stackup]})
            return out_dict

        HammerToolTestHelpers.write_tech_json(tech_json_filename, add_stackup)
        tech = self.get_tech(
            hammer_tech.HammerTechnology.load_from_dir("dummy28", tech_dir))
        tech.cache_dir = tech_dir

        tool = DummyTool()
        tool.technology = tech
        database = hammer_config.HammerDatabase()
        tool.set_database(database)

        self.assertEqual(
            tech.get_stackup_by_name(test_stackup["name"]),
            Stackup.from_setting(tech.get_grid_unit(), test_stackup))
Example #16
0
    def test_macro_sizes(self) -> None:
        """
        Test that getting macro sizes works as expected.
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir(
            "dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")

        def add_lib_with_lef(d: Dict[str, Any]) -> Dict[str, Any]:
            with open(os.path.join(tech_dir, 'my_vendor_lib.lef'), 'w') as f:
                f.write("""VERSION 5.8 ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;

MACRO my_awesome_macro
  CLASS BLOCK ;
  ORIGIN -0.435 607.525 ;
  FOREIGN my_awesome_macro 0.435 -607.525 ;
  SIZE 810.522 BY 607.525 ;
  SYMMETRY X Y R90 ;
END my_awesome_macro

END LIBRARY
                """)
            r = deepdict(d)
            r['libraries'].append({
                'name': 'my_vendor_lib',
                'lef file': 'test/my_vendor_lib.lef'
            })
            return r

        HammerToolTestHelpers.write_tech_json(tech_json_filename,
                                              add_lib_with_lef)
        tech_opt = hammer_tech.HammerTechnology.load_from_dir(
            "dummy28", tech_dir)
        if tech_opt is None:
            self.assertTrue(False, "Unable to load technology")
            return
        else:
            tech = tech_opt  # type: hammer_tech.HammerTechnology
        tech.cache_dir = tech_dir

        tech.logger = HammerVLSILogging.context("")

        database = hammer_config.HammerDatabase()
        tech.set_database(database)

        # Test that macro sizes can be read out of the LEF.
        self.assertEqual(tech.get_macro_sizes(), [
            hammer_tech.MacroSize(library='my_vendor_lib',
                                  name='my_awesome_macro',
                                  width=Decimal("810.522"),
                                  height=Decimal("607.525"))
        ])

        # Cleanup
        shutil.rmtree(tech_dir_base)
Example #17
0
 def test_no_config_junk(self):
     """Test that no _config_path junk variables get left behind."""
     db = hammer_config.HammerDatabase()
     db.update_core([hammer_config.load_config_from_string("key1: value1", is_yaml=True)])
     db.update_technology([hammer_config.load_config_from_string("key2: value2", is_yaml=True)])
     db.update_project([hammer_config.load_config_from_string("key3: value3", is_yaml=True)])
     for key in hammer_config.HammerDatabase.internal_keys():
         self.assertFalse(db.has_setting(key), "Should not have internal key " + key)
Example #18
0
    def test_read_libs(self) -> None:
        """
        Test that HammerTool can read technology IP libraries and filter/process them.
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir(
            "dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")
        HammerToolTestHelpers.write_tech_json(tech_json_filename)
        tech_opt = hammer_tech.HammerTechnology.load_from_dir(
            "dummy28", tech_dir)
        if tech_opt is None:
            self.assertTrue(False, "Unable to load technology")
        else:
            tech = tech_opt  # type: hammer_tech.HammerTechnology
        tech.cache_dir = tech_dir

        class Tool(SingleStepTool):
            def step(self) -> bool:
                def test_tool_format(lib, filt) -> List[str]:
                    return ["drink {0}".format(lib)]

                self._read_lib_output = self.read_libs(
                    [self.milkyway_techfile_filter],
                    test_tool_format,
                    must_exist=False)

                self._test_filter_output = self.read_libs(
                    [HammerToolTestHelpers.make_test_filter()],
                    test_tool_format,
                    must_exist=False)
                return True

        test = Tool()
        test.logger = HammerVLSILogging.context("")
        test.run_dir = tempfile.mkdtemp()
        test.technology = tech
        test.set_database(hammer_config.HammerDatabase())
        test.run()

        # Don't care about ordering here.
        self.assertEqual(set(test._read_lib_output), {
            "drink {0}/soy".format(tech_dir),
            "drink {0}/coconut".format(tech_dir)
        })

        # We do care about ordering here.
        self.assertEqual(test._test_filter_output, [
            "drink {0}/tea".format(tech_dir),
            "drink {0}/grapefruit".format(tech_dir),
            "drink {0}/juice".format(tech_dir),
            "drink {0}/orange".format(tech_dir)
        ])

        # Cleanup
        shutil.rmtree(tech_dir_base)
        shutil.rmtree(test.run_dir)
Example #19
0
 def test_overriding(self):
     """
     Test that we can add a project first and technology after and still have it override.
     """
     db = hammer_config.HammerDatabase()
     db.update_project([{"tech.x": "foo"}])
     self.assertEqual(db.get_setting("tech.x"), "foo")
     db.update_technology([{"tech.x": "bar"}])
     self.assertEqual(db.get_setting("tech.x"), "foo")
Example #20
0
 def test_meta_lazysubst_array(self) -> None:
     """
     Check that lazysubst works correctly with an array.
     """
     db = hammer_config.HammerDatabase()
     d = hammer_config.load_config_from_string("""
     target: "foo"
     array: ["${target}bar"]
     array_meta: lazysubst
     """,
                                               is_yaml=True)
     db.update_core([d])
     self.assertEqual(db.get_setting("array"), ["foobar"])
Example #21
0
    def test_unpacking(self):
        """
        Test that input configs get unpacked.
        """
        db = hammer_config.HammerDatabase()
        config = hammer_config.load_config_from_string("""
foo:
    bar:
        adc: "yes"
        dac: "no"
""", is_yaml=True)
        db.update_core([config])
        self.assertEqual(db.get_setting("foo.bar.adc"), "yes")
        self.assertEqual(db.get_setting("foo.bar.dac"), "no")
Example #22
0
    def test_drc_lvs_decks(self) -> None:
        """
        Test that getting the DRC & LVS decks works as expected.
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir("dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")

        def add_drc_lvs_decks(in_dict: Dict[str, Any]) -> Dict[str, Any]:
            out_dict = deepdict(in_dict)
            out_dict.update({"drc decks": [
                    {"tool name": "hammer", "deck name": "a_nail", "path": "/path/to/hammer/a_nail.drc.rules"},
                    {"tool name": "chisel", "deck name": "some_wood", "path": "/path/to/chisel/some_wood.drc.rules"},
                    {"tool name": "hammer", "deck name": "head_shark", "path": "/path/to/hammer/head_shark.drc.rules"}
                ]})
            out_dict.update({"lvs decks": [
                    {"tool name": "hammer", "deck name": "a_nail", "path": "/path/to/hammer/a_nail.lvs.rules"},
                    {"tool name": "chisel", "deck name": "some_wood", "path": "/path/to/chisel/some_wood.lvs.rules"},
                    {"tool name": "hammer", "deck name": "head_shark", "path": "/path/to/hammer/head_shark.lvs.rules"}
                ]})
            return out_dict

        HammerToolTestHelpers.write_tech_json(tech_json_filename, add_drc_lvs_decks)
        sys.path.append(tech_dir_base)
        tech = self.get_tech(hammer_tech.HammerTechnology.load_from_dir("dummy28", tech_dir))
        tech.cache_dir = tech_dir

        tool = DummyTool()
        tool.technology = tech
        database = hammer_config.HammerDatabase()
        tool.set_database(database)

        self.maxDiff = None
        self.assertEqual(tech.get_drc_decks_for_tool("hammer"),
                [DRCDeck(tool_name="hammer", name="a_nail", path="/path/to/hammer/a_nail.drc.rules"),
                 DRCDeck(tool_name="hammer", name="head_shark", path="/path/to/hammer/head_shark.drc.rules")
                ])

        self.assertEqual(tech.get_lvs_decks_for_tool("hammer"),
                [LVSDeck(tool_name="hammer", name="a_nail", path="/path/to/hammer/a_nail.lvs.rules"),
                 LVSDeck(tool_name="hammer", name="head_shark", path="/path/to/hammer/head_shark.lvs.rules")
                ])

        self.assertEqual(tech.get_drc_decks_for_tool("chisel"),
                [DRCDeck(tool_name="chisel", name="some_wood", path="/path/to/chisel/some_wood.drc.rules")])

        self.assertEqual(tech.get_lvs_decks_for_tool("chisel"),
                [LVSDeck(tool_name="chisel", name="some_wood", path="/path/to/chisel/some_wood.lvs.rules")])
Example #23
0
 def check_src(self, yaml_src: str, ref_port: ClockPort) -> None:
     """
     Helper method to check if the given source parses to the given port.
     :param yaml_src: YAML config source
     :param ref_port: Reference port
     """
     database = hammer_config.HammerDatabase()
     database.update_project(
         [hammer_config.load_config_from_string(yaml_src, is_yaml=True)])
     tool = DummyHammerTool()
     tool.set_database(database)
     ports = tool.get_clock_ports()
     self.assertEqual(len(ports), 1)
     port = ports[0]
     self.assertEqual(port, ref_port)
Example #24
0
    def test_installs_in_cache_dir(self) -> None:
        """
        Test that we can access files in the tech cache dir.
        Use case: A PDK file needs to be hacked by post_install_script
        """
        import hammer_config

        tech_dir, tech_dir_base = HammerToolTestHelpers.create_tech_dir(
            "dummy28")
        tech_json_filename = os.path.join(tech_dir, "dummy28.tech.json")

        tech_json = {
            "name":
            "dummy",
            "installs": [{
                "path": "tech-dummy28-cache",
                "base var": ""  # means relative to tech dir
            }],
            "libraries": [{
                "lef file": "tech-dummy28-cache/tech.lef",
                "provides": [{
                    "lib_type": "technology"
                }]
            }]
        }  # type: Dict[str, Any]

        with open(tech_json_filename,
                  "w") as f:  # pyline: disable=invalid-name
            f.write(json.dumps(tech_json, cls=HammerJSONEncoder, indent=4))

        tech = self.get_tech(
            hammer_tech.HammerTechnology.load_from_dir("dummy28", tech_dir))
        tech.cache_dir = tech_dir

        database = hammer_config.HammerDatabase()
        database.update_technology(tech.get_config())
        HammerVLSISettings.load_builtins_and_core(database)
        tech.set_database(database)
        outputs = tech.process_library_filter(
            pre_filts=[],
            filt=hammer_tech.filters.lef_filter,
            must_exist=False,
            output_func=lambda str, _: [str])

        self.assertEqual(outputs, ["{0}/tech.lef".format(tech.cache_dir)])

        # Cleanup
        shutil.rmtree(tech_dir_base)
Example #25
0
    def test_meta_lazycrossappend_with_lazycrossref(self) -> None:
        """
        Test that lazy crossappend works with lazy crossref in one file.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
global: ["hello", "world", "scala"]
tool_1: "global"
tool_1_meta: "lazycrossref"
tool: ["tool_1", ["python"]]
tool_meta: "lazycrossappend"
""",
                                                     is_yaml=True)
        db.update_core([base])
        self.assertEqual(db.get_setting("global"), ["hello", "world", "scala"])
        self.assertEqual(db.get_setting("tool"),
                         ["hello", "world", "scala", "python"])
Example #26
0
    def test_meta_crossref_errors(self) -> None:
        """
        Test that the meta attribute "crossref" raises errors appropriately.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
my:
    numbers: ["1", "2", "3"]
    dichotomy: false
    unity: true
    world: ["world"]
"target_key": "my.dichotomy"
""",
                                                     is_yaml=True)
        with self.assertRaises(ValueError):
            meta = hammer_config.load_config_from_string("""
{
  "no_crossrefing_using_int": 123,
  "no_crossrefing_using_int_meta": "crossref"
}
""",
                                                         is_yaml=False)
            db.update_core([base, meta])
            db.get_setting("no_crossrefing_using_int")
        with self.assertRaises(ValueError):
            meta = hammer_config.load_config_from_string("""
{
  "no_crossrefing_using_bool": false,
  "no_crossrefing_using_bool_meta": "crossref"
}
""",
                                                         is_yaml=False)
            db.update_core([base, meta])
            db.get_setting("no_crossrefing_using_bool")
        with self.assertRaises(ValueError):
            meta = hammer_config.load_config_from_string("""
{
  "bad_list": [1, 2],
  "bad_list_meta": "crossref"
}
""",
                                                         is_yaml=False)
            db.update_core([base, meta])
            db.get_setting("bad_list")
Example #27
0
    def test_meta_deepsubst_cwd(self) -> None:
        """
        Test that the deepsubst special meta "cwd" correctly prepends the CWD.
        """
        cwd = os.getcwd()
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    bar_meta: deepsubst
    bar:
    - adc: "yes"
      dac: "no"
      dsl: ["scala"]
      base_test: "some_relative_path"
      base_test_deepsubst_meta: "cwd"
""",
                                                     is_yaml=True,
                                                     path="base/config/path")
        meta = hammer_config.load_config_from_string("""
{
  "foo.bar_meta": ["append", "deepsubst"],
  "foo.bar": [{
      "dsl": ["python"],
      "dsl_meta": "append",
      "dac": "current_weighted",
      "meta_test": "some/relative/path",
      "meta_test_deepsubst_meta": "cwd",
      "abs_test": "/this/is/an/abs/path",
      "abs_test_deepsubst_meta": "cwd"
  }]
}
""",
                                                     is_yaml=False,
                                                     path="meta/config/path")
        db.update_core([base, meta])
        self.assertEqual(
            db.get_setting("foo.bar")[0]["base_test"],
            os.path.join(cwd, "some_relative_path"))
        self.assertEqual(
            db.get_setting("foo.bar")[1]["meta_test"],
            os.path.join(cwd, "some/relative/path"))
        # leading / should override the meta
        self.assertEqual(
            db.get_setting("foo.bar")[1]["abs_test"], "/this/is/an/abs/path")
Example #28
0
    def test_meta_lazycrossref(self) -> None:
        """
        Test that lazy crossref works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
my:
    numbers: ["1", "2", "3"]
    """,
                                                     is_yaml=True)
        meta = hammer_config.load_config_from_string("""
numbers: "my.numbers"
numbers_meta: crossref
lazy.numbers: "numbers"
lazy.numbers_meta: lazycrossref
    """,
                                                     is_yaml=True)
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("lazy.numbers"), ["1", "2", "3"])
Example #29
0
    def test_meta_subst_and_prependlocal(self):
        """
        Test that meta attributes that are an array.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    bar:
        base_test: "local_path"
""", is_yaml=True, path="base/config/path")
        meta = hammer_config.load_config_from_string("""
{
  "foo.bar.meta_test": "${foo.bar.base_test}",
  "foo.bar.meta_test_meta": ["subst", "prependlocal"]
}
""", is_yaml=False, path="meta/config/path")
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("foo.bar.base_test"), "local_path")
        self.assertEqual(db.get_setting("foo.bar.meta_test"), "meta/config/path/local_path")
Example #30
0
    def test_meta_json2list(self):
        """
        Test that the meta attribute "json2list" works.
        """
        db = hammer_config.HammerDatabase()
        base = hammer_config.load_config_from_string("""
foo:
    flash: "yes"
    max: "min"
""", is_yaml=True)
        meta = hammer_config.load_config_from_string("""
{
    "foo.pipeline": "[\\"1\\", \\"2\\"]",
    "foo.pipeline_meta": "json2list"
}
    """, is_yaml=False)
        db.update_core([base, meta])
        self.assertEqual(db.get_setting("foo.flash"), "yes")
        self.assertEqual(db.get_setting("foo.max"), "min")
        self.assertEqual(db.get_setting("foo.pipeline"), ["1", "2"])