1212from chipflow_lib import (
1313 ChipFlowError ,
1414 _get_cls_by_reference ,
15- _ensure_chipflow_root ,
16- _parse_config_file ,
17- _parse_config
15+ ensure_chipflow_root ,
16+ parse_config ,
17+ parse_config_file ,
1818)
1919
2020
21- class TestCoreUtilities (unittest .TestCase ):
22- def setUp (self ):
23- # Save original environment to restore later
24- self .original_chipflow_root = os .environ .get ("CHIPFLOW_ROOT" )
25- self .original_sys_path = sys .path .copy ()
26- < << << << HEAD
27-
28- == == == =
29-
30- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
31- # Create a temporary directory for tests
32- self .temp_dir = tempfile .TemporaryDirectory ()
33- self .temp_path = self .temp_dir .name
34-
35- def tearDown (self ):
36- # Restore original environment
37- if self .original_chipflow_root :
38- os .environ ["CHIPFLOW_ROOT" ] = self .original_chipflow_root
39- else :
40- os .environ .pop ("CHIPFLOW_ROOT" , None )
41- < << << << HEAD
42-
43- == == == =
21+ def fixture_path (filename ):
22+ """Helper to get path to test fixture file"""
23+ return os .path .join (os .path .dirname (__file__ ), "fixtures" , filename )
4424
45- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
46- sys .path = self .original_sys_path
47- self .temp_dir .cleanup ()
4825
26+ class TestCoreUtilities (unittest .TestCase ):
27+ """Test the core utilities in the chipflow_lib package"""
28+
4929 def test_chipflow_error (self ):
50- """Test that ChipFlowError can be raised and caught properly"""
51- with self .assertRaises (ChipFlowError ):
52- raise ChipFlowError ("Test error" )
53-
54- def test_get_cls_by_reference_valid (self ):
55- """Test retrieving a class by reference when the module and class exist"""
56- # unittest.TestCase is a valid class that should be importable
57- cls = _get_cls_by_reference ("unittest:TestCase" , "test context" )
58- self .assertEqual (cls , unittest .TestCase )
59-
60- def test_get_cls_by_reference_module_not_found (self ):
61- """Test _get_cls_by_reference when the module doesn't exist"""
62- with self .assertRaises (ChipFlowError ) as cm :
63- _get_cls_by_reference ("nonexistent_module:SomeClass" , "test context" )
64- < << << << HEAD
65-
66- == == == =
67-
68- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
69- self .assertIn ("Module `nonexistent_module` referenced by test context is not found" , str (cm .exception ))
70-
71- def test_get_cls_by_reference_class_not_found (self ):
72- """Test _get_cls_by_reference when the class doesn't exist in the module"""
73- with self .assertRaises (ChipFlowError ) as cm :
74- _get_cls_by_reference ("unittest:NonExistentClass" , "test context" )
75- < << << << HEAD
30+ """Test ChipFlowError exception creation"""
31+ # Create with message
32+ error = ChipFlowError ("Test error message" )
33+ self .assertEqual (str (error ), "Test error message" )
7634
77- == == == =
78-
79- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
80- self .assertIn ("Module `unittest` referenced by test context does not define `NonExistentClass`" , str (cm .exception ))
35+ # Create with formatted message
36+ error = ChipFlowError ("Error with {}" , "formatting" )
37+ self .assertEqual (str (error ), "Error with formatting" )
8138
8239 def test_ensure_chipflow_root_already_set (self ):
83- """Test _ensure_chipflow_root when CHIPFLOW_ROOT is already set"""
84- os .environ ["CHIPFLOW_ROOT" ] = "/test/path"
85- sys .path = ["/some/other/path" ]
86- < << << << HEAD
87-
88- result = _ensure_chipflow_root ()
89-
90- == == == =
91-
92- result = _ensure_chipflow_root ()
93-
94- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
95- self .assertEqual (result , "/test/path" )
96- self .assertIn ("/test/path" , sys .path )
40+ """Test ensure_chipflow_root when CHIPFLOW_ROOT is already set"""
41+ with mock .patch .dict (os .environ , {"CHIPFLOW_ROOT" : "/path/to/chipflow" }):
42+ # Should not modify the variable
43+ ensure_chipflow_root ()
44+ self .assertEqual (os .environ ["CHIPFLOW_ROOT" ], "/path/to/chipflow" )
9745
9846 def test_ensure_chipflow_root_not_set (self ):
99- """Test _ensure_chipflow_root when CHIPFLOW_ROOT is not set"""
100- if "CHIPFLOW_ROOT" in os .environ :
101- del os .environ ["CHIPFLOW_ROOT" ]
102- < << << << HEAD
47+ """Test ensure_chipflow_root when CHIPFLOW_ROOT is not set"""
48+ # Remove CHIPFLOW_ROOT if present
49+ os .environ .pop ("CHIPFLOW_ROOT" , None )
10350
104- with mock .patch ("os.getcwd" , return_value = "/mock/cwd" ):
105- result = _ensure_chipflow_root ()
51+ # Should set it to current directory
52+ with mock .patch ('os.getcwd' , return_value = "/current/dir" ):
53+ ensure_chipflow_root ()
54+ self .assertEqual (os .environ ["CHIPFLOW_ROOT" ], "/current/dir" )
10655
107- == == == =
56+ # Clean up
57+ os .environ .pop ("CHIPFLOW_ROOT" , None )
58+
59+ def test_get_cls_by_reference_valid (self ):
60+ """Test _get_cls_by_reference with valid reference"""
61+ # Test with actual class
62+ cls = _get_cls_by_reference ("chipflow_lib:ChipFlowError" )
63+ self .assertEqual (cls , ChipFlowError )
10864
109- with mock .patch ("os.getcwd" , return_value = "/mock/cwd" ):
110- result = _ensure_chipflow_root ()
65+ def test_get_cls_by_reference_module_not_found (self ):
66+ """Test _get_cls_by_reference with non-existent module"""
67+ with self .assertRaises (ChipFlowError ):
68+ _get_cls_by_reference ("nonexistent_module:SomeClass" )
11169
112- >> >> >> > bd941c3 ( Add comprehensive test suite for improved code coverage )
113- self . assertEqual ( result , "/mock/cwd" )
114- self .assertEqual ( os . environ [ "CHIPFLOW_ROOT" ], "/mock/cwd" )
115- self . assertIn ( "/mock/cwd" , sys . path )
70+ def test_get_cls_by_reference_class_not_found ( self ):
71+ """Test _get_cls_by_reference with non-existent class"""
72+ with self .assertRaises ( ChipFlowError ):
73+ _get_cls_by_reference ( "chipflow_lib:NonExistentClass" )
11674
117- def test_parse_config_file_valid (self ):
118- """Test _parse_config_file with a valid config file"""
119- # Create a temporary config file
120- config_content = """
75+ def test_parse_config (self ):
76+ """Test parse_config using a fixture file"""
77+ # Create temporary file for testing
78+ with tempfile .NamedTemporaryFile (suffix = ".toml" , delete = False ) as temp_file :
79+ temp_file .write (b'''
12180[chipflow]
12281project_name = "test_project"
123- steps = { silicon = "chipflow_lib.steps.silicon:SiliconStep" }
124- clocks = { default = "sys_clk" }
125- resets = { default = "sys_rst_n" }
126-
127- [chipflow.silicon]
128- process = "sky130"
129- package = "caravel"
130- """
131- config_path = os .path .join (self .temp_path , "chipflow.toml" )
132- with open (config_path , "w" ) as f :
133- f .write (config_content )
134- < << << << HEAD
82+ process = "sky130A"
83+ package = "cf20"
84+ silicon.debug.heartbeat = true
85+
86+ [chipflow.steps]
87+ silicon = "chipflow_lib.steps.silicon:SiliconStep"
88+ ''' )
89+ temp_file_path = temp_file .name
13590
136- config = _parse_config_file (config_path )
137-
138- == == == =
91+ try :
92+ # Test parsing
93+ with mock .patch ('os.path.isfile' , return_value = True ):
94+ config = parse_config (config_path = temp_file_path )
95+
96+ # Verify config contents
97+ self .assertEqual (config ["chipflow" ]["project_name" ], "test_project" )
98+ self .assertEqual (config ["chipflow" ]["process" ], "sky130A" )
99+ self .assertEqual (config ["chipflow" ]["silicon" ]["debug" ]["heartbeat" ], True )
100+ self .assertEqual (config ["chipflow" ]["steps" ]["silicon" ],
101+ "chipflow_lib.steps.silicon:SiliconStep" )
102+ finally :
103+ # Clean up temporary file
104+ os .unlink (temp_file_path )
139105
140- config = _parse_config_file (config_path )
106+ def test_parse_config_file_valid (self ):
107+ """Test parse_config_file with valid TOML"""
108+ valid_toml = '''
109+ [chipflow]
110+ project_name = "test_project"
111+ process = "sky130A"
112+ package = "cf20"
141113
142- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
143- self .assertIn ("chipflow" , config )
114+ [chipflow.steps]
115+ silicon = "chipflow_lib.steps.silicon:SiliconStep"
116+ '''
117+
118+ config = parse_config_file (valid_toml )
144119 self .assertEqual (config ["chipflow" ]["project_name" ], "test_project" )
145- self .assertEqual (config ["chipflow" ]["silicon" ]["process" ], "sky130" )
120+ self .assertEqual (config ["chipflow" ]["steps" ]["silicon" ],
121+ "chipflow_lib.steps.silicon:SiliconStep" )
146122
147123 def test_parse_config_file_invalid_schema (self ):
148- """Test _parse_config_file with an invalid config file (schema validation fails)"""
149- # Create a temporary config file with missing required fields
150- config_content = """
124+ """Test parse_config_file with TOML not matching schema"""
125+ invalid_toml = '''
151126[chipflow]
152- project_name = "test_project"
153- # Missing required fields: steps, silicon
154- """
155- config_path = os .path .join (self .temp_path , "chipflow.toml" )
156- with open (config_path , "w" ) as f :
157- f .write (config_content )
158- < << << << HEAD
159-
160- with self .assertRaises (ChipFlowError ) as cm :
161- _parse_config_file (config_path )
162-
163- == == == =
164-
165- with self .assertRaises (ChipFlowError ) as cm :
166- _parse_config_file (config_path )
167-
168- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
169- self .assertIn ("Syntax error in `chipflow.toml`" , str (cm .exception ))
170-
171- @mock .patch ("chipflow_lib._ensure_chipflow_root" )
172- @mock .patch ("chipflow_lib._parse_config_file" )
173- def test_parse_config (self , mock_parse_config_file , mock_ensure_chipflow_root ):
174- """Test _parse_config which uses _ensure_chipflow_root and _parse_config_file"""
175- mock_ensure_chipflow_root .return_value = "/mock/chipflow/root"
176- mock_parse_config_file .return_value = {"chipflow" : {"test" : "value" }}
177- < << << << HEAD
178-
179- config = _parse_config ()
127+ # Missing required fields: project_name, process, package
128+ steps = {} # Steps in wrong format
129+ '''
180130
181- mock_ensure_chipflow_root .assert_called_once ()
182- # We're expecting a string, not a Path
183- == == == =
184-
185- config = _parse_config ()
186-
187- mock_ensure_chipflow_root .assert_called_once ()
188- >> >> >> > bd941c3 (Add comprehensive test suite for improved code coverage )
189- mock_parse_config_file .assert_called_once_with ("/mock/chipflow/root/chipflow.toml" )
190- self .assertEqual (config , {"chipflow" : {"test" : "value" }})
131+ # Should raise error about missing required fields
132+ with self .assertRaises (ChipFlowError ) as ctx :
133+ parse_config_file (invalid_toml )
134+
135+ # Error message should mention the validation error
136+ self .assertIn ("validation error" , str (ctx .exception ))
0 commit comments