@@ -3,6 +3,8 @@ package config
33import (
44 "context"
55 "errors"
6+ "os"
7+ "path/filepath"
68 "testing"
79
810 "github.com/BurntSushi/toml"
@@ -123,6 +125,210 @@ func (s *ToolsetConfigSuite) TestReadConfigUnregisteredToolsetConfig() {
123125 })
124126}
125127
128+ func (s * ToolsetConfigSuite ) TestConfigDirPathInContext () {
129+ var capturedDirPath string
130+ RegisterToolsetConfig ("test-toolset" , func (ctx context.Context , primitive toml.Primitive , md toml.MetaData ) (Extended , error ) {
131+ capturedDirPath = ConfigDirPathFromContext (ctx )
132+ var toolsetConfigForTest ToolsetConfigForTest
133+ if err := md .PrimitiveDecode (primitive , & toolsetConfigForTest ); err != nil {
134+ return nil , err
135+ }
136+ return & toolsetConfigForTest , nil
137+ })
138+ configPath := s .writeConfig (`
139+ [toolset_configs.test-toolset]
140+ enabled = true
141+ endpoint = "https://example.com"
142+ timeout = 30
143+ ` )
144+
145+ absConfigPath , err := filepath .Abs (configPath )
146+ s .Require ().NoError (err , "test error: getting the absConfigPath should not fail" )
147+
148+ _ , err = Read (configPath , "" )
149+ s .Run ("provides config directory path in context to parser" , func () {
150+ s .Require ().NoError (err , "Expected no error reading config" )
151+ s .NotEmpty (capturedDirPath , "Expected non-empty directory path in context" )
152+ s .Equal (filepath .Dir (absConfigPath ), capturedDirPath , "Expected directory path to match config file directory" )
153+ })
154+ }
155+
156+ func (s * ToolsetConfigSuite ) TestExtendedConfigMergingAcrossDropIns () {
157+ // Test that extended configs (toolset_configs) are properly merged
158+ // when scattered across multiple drop-in files
159+ RegisterToolsetConfig ("test-toolset" , toolsetConfigForTestParser )
160+
161+ tempDir := s .T ().TempDir ()
162+
163+ // Create main config with initial toolset config
164+ mainConfigPath := filepath .Join (tempDir , "config.toml" )
165+ err := os .WriteFile (mainConfigPath , []byte (`
166+ [toolset_configs.test-toolset]
167+ enabled = false
168+ endpoint = "from-main"
169+ timeout = 1
170+ ` ), 0644 )
171+ s .Require ().NoError (err )
172+
173+ // Create drop-in directory
174+ dropInDir := filepath .Join (tempDir , "conf.d" )
175+ s .Require ().NoError (os .Mkdir (dropInDir , 0755 ))
176+
177+ // First drop-in overrides some fields
178+ err = os .WriteFile (filepath .Join (dropInDir , "10-override.toml" ), []byte (`
179+ [toolset_configs.test-toolset]
180+ enabled = true
181+ timeout = 10
182+ ` ), 0644 )
183+ s .Require ().NoError (err )
184+
185+ // Second drop-in overrides other fields
186+ err = os .WriteFile (filepath .Join (dropInDir , "20-final.toml" ), []byte (`
187+ [toolset_configs.test-toolset]
188+ endpoint = "from-drop-in"
189+ timeout = 42
190+ ` ), 0644 )
191+ s .Require ().NoError (err )
192+
193+ config , err := Read (mainConfigPath , "" )
194+ s .Require ().NoError (err )
195+ s .Require ().NotNil (config )
196+
197+ toolsetConfig , ok := config .GetToolsetConfig ("test-toolset" )
198+ s .Require ().True (ok , "Expected to find toolset config" )
199+
200+ testConfig , ok := toolsetConfig .(* ToolsetConfigForTest )
201+ s .Require ().True (ok , "Expected toolset config to be *ToolsetConfigForTest" )
202+
203+ s .Run ("merges enabled from first drop-in" , func () {
204+ s .True (testConfig .Enabled , "enabled should be true from 10-override.toml" )
205+ })
206+
207+ s .Run ("merges endpoint from second drop-in" , func () {
208+ s .Equal ("from-drop-in" , testConfig .Endpoint , "endpoint should be from 20-final.toml" )
209+ })
210+
211+ s .Run ("last drop-in wins for timeout" , func () {
212+ s .Equal (42 , testConfig .Timeout , "timeout should be 42 from 20-final.toml" )
213+ })
214+ }
215+
216+ func (s * ToolsetConfigSuite ) TestExtendedConfigFromDropInOnly () {
217+ // Test that extended configs work when defined only in drop-in files (not in main config)
218+ RegisterToolsetConfig ("test-toolset" , toolsetConfigForTestParser )
219+
220+ tempDir := s .T ().TempDir ()
221+
222+ // Create main config WITHOUT toolset config
223+ mainConfigPath := filepath .Join (tempDir , "config.toml" )
224+ err := os .WriteFile (mainConfigPath , []byte (`
225+ log_level = 1
226+ ` ), 0644 )
227+ s .Require ().NoError (err )
228+
229+ // Create drop-in directory
230+ dropInDir := filepath .Join (tempDir , "conf.d" )
231+ s .Require ().NoError (os .Mkdir (dropInDir , 0755 ))
232+
233+ // Drop-in defines the toolset config
234+ err = os .WriteFile (filepath .Join (dropInDir , "10-toolset.toml" ), []byte (`
235+ [toolset_configs.test-toolset]
236+ enabled = true
237+ endpoint = "from-drop-in-only"
238+ timeout = 99
239+ ` ), 0644 )
240+ s .Require ().NoError (err )
241+
242+ config , err := Read (mainConfigPath , "" )
243+ s .Require ().NoError (err )
244+ s .Require ().NotNil (config )
245+
246+ toolsetConfig , ok := config .GetToolsetConfig ("test-toolset" )
247+ s .Require ().True (ok , "Expected to find toolset config from drop-in" )
248+
249+ testConfig , ok := toolsetConfig .(* ToolsetConfigForTest )
250+ s .Require ().True (ok )
251+
252+ s .Run ("loads extended config from drop-in only" , func () {
253+ s .True (testConfig .Enabled )
254+ s .Equal ("from-drop-in-only" , testConfig .Endpoint )
255+ s .Equal (99 , testConfig .Timeout )
256+ })
257+ }
258+
259+ func (s * ToolsetConfigSuite ) TestStandaloneConfigDirWithExtendedConfig () {
260+ // Test that extended configs work with standalone --config-dir (no main config)
261+ RegisterToolsetConfig ("test-toolset" , toolsetConfigForTestParser )
262+
263+ tempDir := s .T ().TempDir ()
264+
265+ // Create drop-in files only (no main config)
266+ err := os .WriteFile (filepath .Join (tempDir , "10-base.toml" ), []byte (`
267+ [toolset_configs.test-toolset]
268+ enabled = false
269+ endpoint = "base"
270+ timeout = 1
271+ ` ), 0644 )
272+ s .Require ().NoError (err )
273+
274+ err = os .WriteFile (filepath .Join (tempDir , "20-override.toml" ), []byte (`
275+ [toolset_configs.test-toolset]
276+ enabled = true
277+ timeout = 100
278+ ` ), 0644 )
279+ s .Require ().NoError (err )
280+
281+ // Read with standalone config-dir (empty config path)
282+ config , err := Read ("" , tempDir )
283+ s .Require ().NoError (err )
284+ s .Require ().NotNil (config )
285+
286+ toolsetConfig , ok := config .GetToolsetConfig ("test-toolset" )
287+ s .Require ().True (ok , "Expected to find toolset config in standalone mode" )
288+
289+ testConfig , ok := toolsetConfig .(* ToolsetConfigForTest )
290+ s .Require ().True (ok )
291+
292+ s .Run ("merges extended config in standalone mode" , func () {
293+ s .True (testConfig .Enabled , "enabled should be true from 20-override.toml" )
294+ s .Equal ("base" , testConfig .Endpoint , "endpoint should be 'base' from 10-base.toml" )
295+ s .Equal (100 , testConfig .Timeout , "timeout should be 100 from 20-override.toml" )
296+ })
297+ }
298+
299+ func (s * ToolsetConfigSuite ) TestConfigDirPathInContextStandalone () {
300+ // Test that configDirPath is correctly set in context for standalone --config-dir
301+ var capturedDirPath string
302+ RegisterToolsetConfig ("test-toolset" , func (ctx context.Context , primitive toml.Primitive , md toml.MetaData ) (Extended , error ) {
303+ capturedDirPath = ConfigDirPathFromContext (ctx )
304+ var toolsetConfigForTest ToolsetConfigForTest
305+ if err := md .PrimitiveDecode (primitive , & toolsetConfigForTest ); err != nil {
306+ return nil , err
307+ }
308+ return & toolsetConfigForTest , nil
309+ })
310+
311+ tempDir := s .T ().TempDir ()
312+
313+ err := os .WriteFile (filepath .Join (tempDir , "10-config.toml" ), []byte (`
314+ [toolset_configs.test-toolset]
315+ enabled = true
316+ endpoint = "test"
317+ timeout = 1
318+ ` ), 0644 )
319+ s .Require ().NoError (err )
320+
321+ absTempDir , err := filepath .Abs (tempDir )
322+ s .Require ().NoError (err )
323+
324+ _ , err = Read ("" , tempDir )
325+ s .Run ("provides config directory path in context for standalone mode" , func () {
326+ s .Require ().NoError (err )
327+ s .NotEmpty (capturedDirPath , "Expected non-empty directory path in context" )
328+ s .Equal (absTempDir , capturedDirPath , "Expected directory path to match config-dir" )
329+ })
330+ }
331+
126332func TestToolsetConfig (t * testing.T ) {
127333 suite .Run (t , new (ToolsetConfigSuite ))
128334}
0 commit comments