1- """Tests for LLMConfigManager."""
1+ # --------------------------------------------------------------------------------------------
2+ # Copyright (c) Microsoft Corporation. All rights reserved.
3+ # Licensed under the MIT License. See License.txt in the project root for license information.
4+ # --------------------------------------------------------------------------------------------
25
36import os
47import tempfile
@@ -18,7 +21,7 @@ def setUp(self):
1821 self .temp_dir = tempfile .mkdtemp ()
1922 self .config_file = os .path .join (self .temp_dir , "test_config.yaml" )
2023 self .manager = LLMConfigManager ()
21- self .manager .config_file = self .config_file
24+ self .manager .config_path = self .config_file
2225
2326 def tearDown (self ):
2427 """Clean up test fixtures."""
@@ -344,41 +347,119 @@ def test_validate_config_valid_structure(self):
344347 ]
345348 }
346349
350+ # Write valid config to file
351+ with open (self .config_file , 'w' ) as f :
352+ yaml .safe_dump (valid_config , f )
353+
347354 # Should not raise any exception
348- self .manager .validate_config (valid_config )
355+ self .manager .validate_config ()
349356
350357 def test_validate_config_missing_llms_key (self ):
351358 """Test validate_config raises error when 'llms' key is missing."""
352359 invalid_config = {
353360 "other_key" : "value"
354361 }
355362
356- with self .assertRaises (AzCLIError ) as cm :
357- self .manager .validate_config (invalid_config )
363+ # Write invalid config to file
364+ with open (self .config_file , 'w' ) as f :
365+ yaml .safe_dump (invalid_config , f )
366+
367+ with self .assertRaises (ValueError ) as cm :
368+ self .manager .validate_config ()
358369
359- self .assertIn ("Configuration file is invalid" , str (cm .exception ))
360- self .assertIn ("missing 'llms' key" , str (cm .exception ))
370+ self .assertIn ("must contain an 'llms' key" , str (cm .exception ))
361371
362372 def test_validate_config_llms_not_list (self ):
363373 """Test validate_config raises error when 'llms' is not a list."""
364374 invalid_config = {
365375 "llms" : "not a list"
366376 }
367377
368- with self .assertRaises (AzCLIError ) as cm :
369- self .manager .validate_config (invalid_config )
378+ # Write invalid config to file
379+ with open (self .config_file , 'w' ) as f :
380+ yaml .safe_dump (invalid_config , f )
381+
382+ with self .assertRaises (ValueError ) as cm :
383+ self .manager .validate_config ()
370384
371- self .assertIn ("Configuration file is invalid" , str (cm .exception ))
372385 self .assertIn ("'llms' must be a list" , str (cm .exception ))
373386
374387 def test_validate_config_empty_llms_list (self ):
375- """Test validate_config with empty llms list (should be valid) ."""
376- valid_config = {
388+ """Test validate_config raises error when llms list is empty ."""
389+ invalid_config = {
377390 "llms" : []
378391 }
379392
393+ # Write config with empty llms list to file
394+ with open (self .config_file , 'w' ) as f :
395+ yaml .safe_dump (invalid_config , f )
396+
397+ with self .assertRaises (ValueError ) as cm :
398+ self .manager .validate_config ()
399+
400+ self .assertIn ("'llms' list cannot be empty" , str (cm .exception ))
401+
402+ def test_validate_config_file_not_found (self ):
403+ """Test validate_config raises error when config file doesn't exist."""
404+ # Don't create the config file, so it doesn't exist
405+ with self .assertRaises (ValueError ) as cm :
406+ self .manager .validate_config ()
407+
408+ self .assertIn ("Configuration file" , str (cm .exception ))
409+ self .assertIn ("not found" , str (cm .exception ))
410+
411+ def test_validate_config_invalid_yaml (self ):
412+ """Test validate_config raises error for invalid YAML syntax."""
413+ # Write invalid YAML to file
414+ with open (self .config_file , 'w' ) as f :
415+ f .write ("invalid: yaml: content: {\n " )
416+
417+ with self .assertRaises (ValueError ) as cm :
418+ self .manager .validate_config ()
419+
420+ self .assertIn ("Invalid YAML syntax" , str (cm .exception ))
421+
422+ def test_validate_config_not_dict (self ):
423+ """Test validate_config raises error when config is not a dictionary."""
424+ # Write a list instead of dict to file
425+ with open (self .config_file , 'w' ) as f :
426+ yaml .safe_dump (["not" , "a" , "dict" ], f )
427+
428+ with self .assertRaises (ValueError ) as cm :
429+ self .manager .validate_config ()
430+
431+ self .assertIn ("must contain a YAML dictionary/mapping" , str (cm .exception ))
432+
433+ def test_validate_config_llm_not_dict (self ):
434+ """Test validate_config raises error when LLM config is not a dictionary."""
435+ invalid_config = {
436+ "llms" : ["not a dict" ]
437+ }
438+
439+ # Write config with non-dict LLM config to file
440+ with open (self .config_file , 'w' ) as f :
441+ yaml .safe_dump (invalid_config , f )
442+
443+ with self .assertRaises (ValueError ) as cm :
444+ self .manager .validate_config ()
445+
446+ self .assertIn ("each LLM configuration must be a dictionary/mapping" , str (cm .exception ))
447+
448+ @patch ("azext_aks_agent.agent.llm_config_manager.get_config_dir" )
449+ def test_validate_config_skips_default_config_path (self , mock_get_config_dir ):
450+ """Test validate_config skips validation for default config path."""
451+ from azext_aks_agent ._consts import CONST_AGENT_CONFIG_FILE_NAME
452+
453+ # Mock the config directory to match our test setup
454+ mock_get_config_dir .return_value = self .temp_dir
455+
456+ # Set the manager to use the default config path
457+ default_config_path = os .path .join (self .temp_dir , CONST_AGENT_CONFIG_FILE_NAME )
458+ self .manager .config_path = default_config_path
459+
460+ # Don't create the file - validation should be skipped for default path
380461 # Should not raise any exception
381- self .manager .validate_config (valid_config )
462+ self .manager .validate_config ()
382463
383464
384465if __name__ == '__main__' :
0 commit comments