@@ -3,6 +3,8 @@ package config_test
33import (
44 "os"
55 "path/filepath"
6+ "runtime"
7+ "strings"
68 "testing"
79
810 "github.com/kubernetes-sigs/headlamp/backend/pkg/config"
@@ -386,3 +388,251 @@ func TestOIDCTLSEnvironmentVariables(t *testing.T) {
386388 })
387389 }
388390}
391+
392+ var applyMeDefaultsTests = []struct {
393+ name string
394+ usernamePath string
395+ emailPath string
396+ groupsPath string
397+ userInfoURL string
398+ wantUsernamePath string
399+ wantEmailPath string
400+ wantGroupsPath string
401+ wantUserInfoURL string
402+ }{
403+ {
404+ name : "all_empty_uses_defaults" ,
405+ usernamePath : "" ,
406+ emailPath : "" ,
407+ groupsPath : "" ,
408+ userInfoURL : "" ,
409+ wantUsernamePath : config .DefaultMeUsernamePath ,
410+ wantEmailPath : config .DefaultMeEmailPath ,
411+ wantGroupsPath : config .DefaultMeGroupsPath ,
412+ wantUserInfoURL : config .DefaultMeUserInfoURL ,
413+ },
414+ {
415+ name : "whitespace_only_uses_defaults" ,
416+ usernamePath : " " ,
417+ emailPath : " " ,
418+ groupsPath : "\t " ,
419+ userInfoURL : " " ,
420+ wantUsernamePath : config .DefaultMeUsernamePath ,
421+ wantEmailPath : config .DefaultMeEmailPath ,
422+ wantGroupsPath : config .DefaultMeGroupsPath ,
423+ wantUserInfoURL : config .DefaultMeUserInfoURL ,
424+ },
425+ {
426+ name : "all_custom_values_preserved" ,
427+ usernamePath : "custom.username" ,
428+ emailPath : "custom.email" ,
429+ groupsPath : "custom.groups" ,
430+ userInfoURL : "/oauth2/userinfo" ,
431+ wantUsernamePath : "custom.username" ,
432+ wantEmailPath : "custom.email" ,
433+ wantGroupsPath : "custom.groups" ,
434+ wantUserInfoURL : "/oauth2/userinfo" ,
435+ },
436+ {
437+ name : "partial_empty_uses_defaults_for_empty" ,
438+ usernamePath : "my.user" ,
439+ emailPath : "" ,
440+ groupsPath : "my.groups" ,
441+ userInfoURL : "" ,
442+ wantUsernamePath : "my.user" ,
443+ wantEmailPath : config .DefaultMeEmailPath ,
444+ wantGroupsPath : "my.groups" ,
445+ wantUserInfoURL : config .DefaultMeUserInfoURL ,
446+ },
447+ {
448+ name : "values_with_surrounding_whitespace_are_trimmed" ,
449+ usernamePath : " trimmed.user " ,
450+ emailPath : " trimmed.email " ,
451+ groupsPath : " trimmed.groups " ,
452+ userInfoURL : " /some/url " ,
453+ wantUsernamePath : "trimmed.user" ,
454+ wantEmailPath : "trimmed.email" ,
455+ wantGroupsPath : "trimmed.groups" ,
456+ wantUserInfoURL : "/some/url" ,
457+ },
458+ }
459+
460+ func TestApplyMeDefaults (t * testing.T ) {
461+ for _ , tt := range applyMeDefaultsTests {
462+ t .Run (tt .name , func (t * testing.T ) {
463+ gotUsername , gotEmail , gotGroups , gotUserInfo := config .ApplyMeDefaults (
464+ tt .usernamePath , tt .emailPath , tt .groupsPath , tt .userInfoURL ,
465+ )
466+ assert .Equal (t , tt .wantUsernamePath , gotUsername )
467+ assert .Equal (t , tt .wantEmailPath , gotEmail )
468+ assert .Equal (t , tt .wantGroupsPath , gotGroups )
469+ assert .Equal (t , tt .wantUserInfoURL , gotUserInfo )
470+ })
471+ }
472+ }
473+
474+ func TestValidateSessionTTL (t * testing.T ) {
475+ tests := []struct {
476+ name string
477+ args []string
478+ expectError bool
479+ errorContains string
480+ }{
481+ {
482+ name : "session_ttl_zero" ,
483+ args : []string {"go run ./cmd" , "--session-ttl=0" },
484+ expectError : true ,
485+ errorContains : "session-ttl cannot be negative or equal to zero" ,
486+ },
487+ {
488+ name : "session_ttl_negative" ,
489+ args : []string {"go run ./cmd" , "--session-ttl=-1" },
490+ expectError : true ,
491+ errorContains : "session-ttl cannot be negative or equal to zero" ,
492+ },
493+ {
494+ name : "session_ttl_exceeds_one_year" ,
495+ args : []string {"go run ./cmd" , "--session-ttl=31536001" },
496+ expectError : true ,
497+ errorContains : "session-ttl cannot be greater than 1 year" ,
498+ },
499+ {
500+ name : "session_ttl_exactly_one_year" ,
501+ args : []string {"go run ./cmd" , "--session-ttl=31536000" },
502+ expectError : false ,
503+ },
504+ {
505+ name : "session_ttl_minimum_valid" ,
506+ args : []string {"go run ./cmd" , "--session-ttl=1" },
507+ expectError : false ,
508+ },
509+ {
510+ name : "session_ttl_default" ,
511+ args : []string {"go run ./cmd" },
512+ expectError : false ,
513+ },
514+ }
515+
516+ for _ , tt := range tests {
517+ t .Run (tt .name , func (t * testing.T ) {
518+ conf , err := config .Parse (tt .args )
519+ if tt .expectError {
520+ require .Error (t , err )
521+ require .Nil (t , conf )
522+ assert .Contains (t , err .Error (), tt .errorContains )
523+ } else {
524+ require .NoError (t , err )
525+ require .NotNil (t , conf )
526+ }
527+ })
528+ }
529+ }
530+
531+ var validateTracingTests = []struct {
532+ name string
533+ args []string
534+ expectError bool
535+ errorContains string
536+ }{
537+ {
538+ name : "tracing_enabled_without_service_name" ,
539+ args : []string {
540+ "go run ./cmd" ,
541+ "--tracing-enabled=true" ,
542+ "--service-name=" ,
543+ },
544+ expectError : true ,
545+ errorContains : "service-name is required when tracing is enabled" ,
546+ },
547+ {
548+ name : "tracing_enabled_with_service_name" ,
549+ args : []string {
550+ "go run ./cmd" ,
551+ "--tracing-enabled=true" ,
552+ "--service-name=myapp" ,
553+ "--otlp-endpoint=localhost:4317" ,
554+ },
555+ expectError : false ,
556+ },
557+ {
558+ name : "otlp_http_without_endpoint" ,
559+ args : []string {
560+ "go run ./cmd" ,
561+ "--tracing-enabled=true" ,
562+ "--service-name=myapp" ,
563+ "--use-otlp-http=true" ,
564+ "--otlp-endpoint=" ,
565+ },
566+ expectError : true ,
567+ errorContains : "otlp-endpoint must be configured when use-otlp-http is enabled" ,
568+ },
569+ {
570+ name : "tracing_disabled_no_validation" ,
571+ args : []string {
572+ "go run ./cmd" ,
573+ "--tracing-enabled=false" ,
574+ },
575+ expectError : false ,
576+ },
577+ }
578+
579+ func TestValidateTracing (t * testing.T ) {
580+ for _ , tt := range validateTracingTests {
581+ t .Run (tt .name , func (t * testing.T ) {
582+ conf , err := config .Parse (tt .args )
583+ if tt .expectError {
584+ require .Error (t , err )
585+ require .Nil (t , conf )
586+ assert .Contains (t , err .Error (), tt .errorContains )
587+ } else {
588+ require .NoError (t , err )
589+ require .NotNil (t , conf )
590+ }
591+ })
592+ }
593+ }
594+
595+ func TestMakeHeadlampKubeConfigsDir (t * testing.T ) {
596+ tmpDir := t .TempDir ()
597+
598+ switch runtime .GOOS {
599+ case "windows" :
600+ t .Setenv ("APPDATA" , tmpDir )
601+ case "darwin" :
602+ t .Setenv ("HOME" , tmpDir )
603+ default :
604+ t .Setenv ("XDG_CONFIG_HOME" , tmpDir )
605+ }
606+
607+ dir , err := config .MakeHeadlampKubeConfigsDir ()
608+ require .NoError (t , err )
609+ assert .NotEmpty (t , dir )
610+
611+ info , err := os .Stat (dir )
612+ require .NoError (t , err )
613+ assert .True (t , info .IsDir ())
614+ assert .True (t , strings .HasPrefix (dir , tmpDir ))
615+ }
616+
617+ func TestDefaultHeadlampKubeConfigFile (t * testing.T ) {
618+ tmpDir := t .TempDir ()
619+
620+ switch runtime .GOOS {
621+ case "windows" :
622+ t .Setenv ("APPDATA" , tmpDir )
623+ case "darwin" :
624+ t .Setenv ("HOME" , tmpDir )
625+ default :
626+ t .Setenv ("XDG_CONFIG_HOME" , tmpDir )
627+ }
628+
629+ path , err := config .DefaultHeadlampKubeConfigFile ()
630+ require .NoError (t , err )
631+ assert .NotEmpty (t , path )
632+ assert .Equal (t , "config" , filepath .Base (path ))
633+ assert .True (t , strings .HasPrefix (path , tmpDir ))
634+
635+ info , err := os .Stat (filepath .Dir (path ))
636+ require .NoError (t , err )
637+ assert .True (t , info .IsDir ())
638+ }
0 commit comments