Skip to content

Commit d5c61f5

Browse files
committed
test(edalizer): cover parse_args and parameters
1 parent f15e1c8 commit d5c61f5

1 file changed

Lines changed: 224 additions & 2 deletions

File tree

tests/test_edalizer.py

Lines changed: 224 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
# Licensed under the 2-Clause BSD License, see LICENSE for details.
33
# SPDX-License-Identifier: BSD-2-Clause
44

5+
from pathlib import Path
6+
7+
import pytest
58

6-
def test_apply_filters(caplog):
7-
import pytest
89

10+
def test_apply_filters(caplog):
911
from fusesoc.edalizer import Edalizer
1012

1113
input_edam = {
@@ -338,3 +340,223 @@ def test_hook_script_names_are_unique_per_core():
338340
assert len(set(names)) == 2, f"hook script names collided: {names}"
339341
assert "hookcollision-parent_0_myhook" in names
340342
assert "hookcollision-child_0_myhook" in names
343+
344+
345+
@pytest.mark.parametrize(
346+
"datatype,value",
347+
(
348+
("bool", None),
349+
("bool", "FalSE"),
350+
("bool", "f"),
351+
("bool", "No"),
352+
("bool", "n"),
353+
("bool", "0"),
354+
("bool", "tRuE"),
355+
("bool", "t"),
356+
("bool", "Yes"),
357+
("bool", "y"),
358+
("bool", "1"),
359+
("int", None),
360+
("int", -2137),
361+
("int", 0),
362+
("int", 2137),
363+
("real", None),
364+
("real", -0.25),
365+
("real", 0.0),
366+
("real", 0.25),
367+
("str", None),
368+
("str", ""),
369+
("str", "arg"),
370+
("str", "arg with spaces"),
371+
("list", None),
372+
("list", ""),
373+
("list", "-arg1"),
374+
("list", "-arg1 val1"),
375+
("list", "-arg1 val1 -arg2"),
376+
("list", "-arg1 val1 -arg2 val2"),
377+
("file", None),
378+
("file", "input.tcl"),
379+
),
380+
)
381+
def test_edalizer_parse_args_for_options(datatype: str, value: object) -> None:
382+
"""Test parsing arguments for options by the Edalizer class."""
383+
from edalize.flows.edaflow import Edaflow
384+
385+
from fusesoc.edalizer import Edalizer
386+
387+
name = f"my_{datatype}_option"
388+
389+
class MyFlow(Edaflow):
390+
argtypes = []
391+
392+
FLOW_OPTIONS = {
393+
name: {"type": datatype, "desc": "Description"},
394+
}
395+
396+
if datatype == "list":
397+
MyFlow.FLOW_OPTIONS[name]["type"] = "str"
398+
MyFlow.FLOW_OPTIONS[name]["list"] = True
399+
400+
edalizer = Edalizer(
401+
toplevel=None,
402+
flags=None,
403+
work_root=None,
404+
core_manager=None,
405+
)
406+
407+
edalizer.edam = {
408+
"name": "flow",
409+
"flow_options": {},
410+
"parameters": {},
411+
}
412+
413+
backendargs: list[str]
414+
415+
if value is None:
416+
backendargs = [f"--{name}"] if datatype == "bool" else []
417+
elif datatype == "list":
418+
# To pass arguments with leading dashes to backend
419+
backendargs = [f"--{name}={value}"]
420+
else:
421+
backendargs = [f"--{name}", str(value)]
422+
423+
edalizer.parse_args(MyFlow, backendargs)
424+
425+
expected: object = None
426+
427+
# Convert provided command line value to expected type for the Edalize
428+
if value is None and datatype != "bool":
429+
pass
430+
elif datatype == "bool":
431+
if value is None or str(value).lower() in ("yes", "true", "t", "y", "1"):
432+
expected = True
433+
else:
434+
expected = False
435+
elif datatype == "int":
436+
expected = int(value)
437+
elif datatype == "real":
438+
expected = float(value)
439+
elif datatype == "str":
440+
expected = str(value)
441+
elif datatype == "list":
442+
expected = str(value).split(" ")
443+
elif datatype == "file":
444+
expected = str(Path(value).resolve())
445+
446+
assert edalizer.edam["parameters"] == {}
447+
448+
if expected is None and datatype != "bool":
449+
# Option was defined but not used
450+
assert edalizer.activated_flow_options == {}
451+
assert name not in edalizer.edam["flow_options"]
452+
else:
453+
# Option was defined and used
454+
assert edalizer.activated_flow_options == {name: expected}
455+
assert edalizer.edam["flow_options"][name] == expected
456+
457+
458+
@pytest.mark.parametrize(
459+
"datatype,value,default",
460+
(
461+
("bool", None, None),
462+
("bool", "FalSE", True),
463+
("bool", "f", True),
464+
("bool", "No", True),
465+
("bool", "n", True),
466+
("bool", "0", True),
467+
("bool", "tRuE", False),
468+
("bool", "t", False),
469+
("bool", "Yes", False),
470+
("bool", "y", False),
471+
("bool", "1", False),
472+
("int", None, None),
473+
("int", -2137, 10),
474+
("int", 0, 2137),
475+
("int", 2137, -10),
476+
("real", None, None),
477+
("real", -0.25, 5),
478+
("real", 0.0, 5.0),
479+
("real", 0.25, -5),
480+
("str", None, None),
481+
("str", "", "default"),
482+
("str", "arg", "default"),
483+
("str", "arg with spaces", "default"),
484+
("file", None, None),
485+
("file", "input.tcl", "default.tcl"),
486+
),
487+
)
488+
@pytest.mark.parametrize(
489+
"paramtype",
490+
(
491+
"plusarg",
492+
"vlogparam",
493+
"vlogdefine",
494+
"generic",
495+
"cmdlinearg",
496+
),
497+
)
498+
def test_edalizer_parse_args_for_parameters(
499+
datatype: str, value: object, default: object, paramtype: str
500+
) -> None:
501+
"""Test parsing arguments for parameters by the Edalizer class."""
502+
from edalize.flows.edaflow import Edaflow
503+
504+
from fusesoc.edalizer import Edalizer
505+
506+
name = f"my_{datatype}_parameter"
507+
508+
class MyFlow(Edaflow):
509+
argtypes = [paramtype]
510+
511+
FLOW_OPTIONS = {}
512+
513+
edalizer = Edalizer(
514+
toplevel=None,
515+
flags=None,
516+
work_root=None,
517+
core_manager=None,
518+
)
519+
520+
edalizer.edam = {
521+
"name": "flow",
522+
"flow_options": {},
523+
"parameters": {
524+
name: {
525+
"datatype": datatype,
526+
"paramtype": paramtype,
527+
"default": default,
528+
},
529+
},
530+
}
531+
532+
backendargs: list[str]
533+
534+
if value is None:
535+
backendargs = [f"--{name}"] if datatype == "bool" else []
536+
else:
537+
backendargs = [f"--{name}", str(value)]
538+
539+
edalizer.parse_args(MyFlow, backendargs)
540+
541+
expected: object = None
542+
543+
# Convert provided command line value to expected type for the Edalize
544+
if value is None and datatype != "bool":
545+
pass
546+
elif datatype == "bool":
547+
if value is None or str(value).lower() in ("yes", "true", "t", "y", "1"):
548+
expected = True
549+
else:
550+
expected = False
551+
elif datatype == "int":
552+
expected = int(value)
553+
elif datatype == "real":
554+
expected = float(value)
555+
elif datatype == "str":
556+
expected = str(value)
557+
elif datatype == "file":
558+
expected = str(Path(value).resolve())
559+
560+
assert edalizer.activated_flow_options == {}
561+
assert edalizer.edam["flow_options"] == {}
562+
assert edalizer.edam["parameters"][name]["default"] == expected

0 commit comments

Comments
 (0)