@@ -479,3 +479,289 @@ def test_var_from_env(tmp_path):
479479 os .environ ["RELEASE_SHA" ] = '12345'
480480 ret = envars .process (args )
481481 assert ret == ['TEST=12345' ]
482+
483+
484+ def test_validate_success (tmp_path ):
485+ """test valid configuration is successful"""
486+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
487+ run_cmd (tmp_path , 'add TEST_VAR=test' )
488+ run_cmd (tmp_path , 'add -e prod PROD_VAR=prod-value' )
489+ run_cmd (tmp_path , 'add -e staging -a master STAGING_VAR=staging-master' )
490+
491+ ret = run_cmd (tmp_path , 'validate' )
492+ assert ret .returncode == 0
493+
494+
495+ def test_validate_lowercase_var_fails (tmp_path ):
496+ """test lowercase variable names"""
497+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
498+
499+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
500+ f .write ("""configuration:
501+ APP: testapp
502+ ENVIRONMENTS:
503+ - prod
504+ - staging
505+ KMS_KEY_ARN: abc
506+
507+ environment_variables:
508+ test_var:
509+ default: value
510+ """ )
511+
512+ ret = subprocess .run (
513+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
514+ shell = True ,
515+ capture_output = True ,
516+ text = True
517+ )
518+ assert ret .returncode == 1
519+ assert 'var name "test_var" is not uppercase' in ret .stdout
520+
521+
522+ def test_validate_mixed_case_var_fails (tmp_path ):
523+ """test mixed case variable names"""
524+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
525+
526+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
527+ f .write ("""configuration:
528+ APP: testapp
529+ ENVIRONMENTS:
530+ - prod
531+ - staging
532+ KMS_KEY_ARN: abc
533+
534+ environment_variables:
535+ TestVar:
536+ default: value
537+ """ )
538+
539+ ret = subprocess .run (
540+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
541+ shell = True ,
542+ capture_output = True ,
543+ text = True
544+ )
545+ assert ret .returncode == 1
546+ assert 'var name "TestVar" is not uppercase' in ret .stdout
547+
548+
549+ def test_validate_unknown_env_fails (tmp_path ):
550+ """test unkown environment fails validation"""
551+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
552+
553+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
554+ f .write ("""configuration:
555+ APP: testapp
556+ ENVIRONMENTS:
557+ - prod
558+ - staging
559+ KMS_KEY_ARN: abc
560+
561+ environment_variables:
562+ TEST_VAR:
563+ default: value
564+ development: dev-value
565+ """ )
566+
567+ ret = subprocess .run (
568+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
569+ shell = True ,
570+ capture_output = True ,
571+ text = True
572+ )
573+ assert ret .returncode == 1
574+ assert '"TEST_VAR" has unknown env "development"' in ret .stdout
575+
576+
577+ def test_validate_empty_string_fails (tmp_path ):
578+ """test empty string validation failure"""
579+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
580+
581+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
582+ f .write ("""configuration:
583+ APP: testapp
584+ ENVIRONMENTS:
585+ - prod
586+ - staging
587+ KMS_KEY_ARN: abc
588+
589+ environment_variables:
590+ TEST_VAR:
591+ default: ""
592+ """ )
593+
594+ ret = subprocess .run (
595+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
596+ shell = True ,
597+ capture_output = True ,
598+ text = True
599+ )
600+ assert ret .returncode == 1
601+ assert '"TEST_VAR" "default" has unsupported empty string' in ret .stdout
602+
603+
604+ def test_validate_empty_string_in_account_fails (tmp_path ):
605+ """test account specific configs with empty strings"""
606+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
607+
608+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
609+ f .write ("""configuration:
610+ APP: testapp
611+ ENVIRONMENTS:
612+ - prod
613+ - staging
614+ KMS_KEY_ARN: abc
615+
616+ environment_variables:
617+ TEST_VAR:
618+ prod:
619+ master: ""
620+ """ )
621+
622+ ret = subprocess .run (
623+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
624+ shell = True ,
625+ capture_output = True ,
626+ text = True
627+ )
628+ assert ret .returncode == 1
629+ assert '"TEST_VAR" "prod" "master" has unsupported empty string' in ret .stdout
630+
631+
632+ def test_validate_invalid_account_fails (tmp_path ):
633+ """test invalid account names"""
634+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
635+
636+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
637+ f .write ("""configuration:
638+ APP: testapp
639+ ENVIRONMENTS:
640+ - prod
641+ - staging
642+ KMS_KEY_ARN: abc
643+
644+ environment_variables:
645+ TEST_VAR:
646+ prod:
647+ production: prod-value
648+ """ )
649+
650+ ret = subprocess .run (
651+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
652+ shell = True ,
653+ capture_output = True ,
654+ text = True
655+ )
656+ assert ret .returncode == 1
657+ assert '"TEST_VAR" "prod" has invalid account "production"' in ret .stdout
658+
659+
660+ def test_validate_multiple_errors (tmp_path ):
661+ """Test if we get multiple validation reports"""
662+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
663+
664+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
665+ f .write ("""configuration:
666+ APP: testapp
667+ ENVIRONMENTS:
668+ - prod
669+ - staging
670+ KMS_KEY_ARN: abc
671+
672+ environment_variables:
673+ test_var:
674+ default: value
675+ VALID_VAR:
676+ default: valid
677+ invalid_env: value
678+ ANOTHER_VAR:
679+ prod:
680+ invalid_account: value
681+ """ )
682+
683+ ret = subprocess .run (
684+ f'{ CMD } -f { tmp_path } /envars.yml validate' ,
685+ shell = True ,
686+ capture_output = True ,
687+ text = True
688+ )
689+ assert ret .returncode == 1
690+ assert 'var name "test_var" is not uppercase' in ret .stdout
691+ assert '"VALID_VAR" has unknown env "invalid_env"' in ret .stdout
692+ assert '"ANOTHER_VAR" "prod" has invalid account "invalid_account"' in ret .stdout
693+
694+
695+ def test_validate_with_description (tmp_path ):
696+ """test valid description field"""
697+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging --kms-key-arn abc' )
698+
699+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
700+ f .write ("""configuration:
701+ APP: testapp
702+ ENVIRONMENTS:
703+ - prod
704+ - staging
705+ KMS_KEY_ARN: abc
706+
707+ environment_variables:
708+ TEST_VAR:
709+ default: value
710+ description: This is a test variable
711+ """ )
712+
713+ ret = run_cmd (tmp_path , 'validate' )
714+ assert ret .returncode == 0
715+
716+
717+ def test_validate_complex_valid_config (tmp_path ):
718+ """test validation with a more complex file"""
719+ run_cmd (tmp_path , 'init --app testapp --environments prod,staging,dev --kms-key-arn abc' )
720+
721+ with open (f'{ tmp_path } /envars.yml' , 'w' ) as f :
722+ f .write ("""configuration:
723+ APP: testapp
724+ ENVIRONMENTS:
725+ - prod
726+ - staging
727+ - dev
728+ KMS_KEY_ARN: abc
729+
730+ environment_variables:
731+ API_KEY:
732+ default: default-key
733+ description: API key for external service
734+
735+ DATABASE_URL:
736+ dev: dev-db-url
737+ staging: staging-db-url
738+ prod:
739+ master: prod-master-db-url
740+ sandbox: prod-sandbox-db-url
741+
742+ FEATURE_FLAG_1:
743+ default: "false"
744+ prod: "true"
745+
746+ MULTI_ACCOUNT_VAR:
747+ default:
748+ master: default-master
749+ sandbox: default-sandbox
750+ staging:
751+ master: staging-master
752+ sandbox: staging-sandbox
753+ """ )
754+
755+ ret = run_cmd (tmp_path , 'validate' )
756+ assert ret .returncode == 0
757+
758+
759+ def test_validate_nonexistent_file (tmp_path ):
760+ """Test validation fails gracefully when file doesn't exist"""
761+ ret = subprocess .run (
762+ f'{ CMD } -f { tmp_path } /nonexistent.yml validate' ,
763+ shell = True ,
764+ capture_output = True ,
765+ text = True
766+ )
767+ assert ret .returncode == 1
0 commit comments