Skip to content

Commit c146cfb

Browse files
authored
Merge pull request #890 from AliyunContainerService/cursor/add-unit-tests-for-terway-methods-2d2c
Add unit tests for terway methods
2 parents 2f1eb0c + 3bffe98 commit c146cfb

File tree

4 files changed

+1458
-26
lines changed

4 files changed

+1458
-26
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
125125

126126
## Tool Versions
127127
CONTROLLER_TOOLS_VERSION ?= v0.17.2
128-
ENVTEST_VERSION ?= latest
128+
ENVTEST_VERSION ?= release-0.20
129129
GOLANGCI_LINT_VERSION ?= v2.1.6
130130

131131
.PHONY: controller-gen

cmd/terway-cli/node_test.go

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,3 +601,295 @@ func TestSymmetricRoutingParseError(t *testing.T) {
601601
err = setSymmetricRouting(cniFilePath)
602602
require.Error(t, err, "parse error")
603603
}
604+
605+
// TestDualStackWithNilConfig tests dualStack with nil eniCfg
606+
func TestDualStackWithNilConfig(t *testing.T) {
607+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
608+
assert.NoError(t, err)
609+
defer os.Remove(tempFile.Name())
610+
611+
// Set eniCfg to nil to test error handling
612+
originalEniCfg := eniCfg
613+
eniCfg = nil
614+
defer func() { eniCfg = originalEniCfg }()
615+
616+
cmd := &cobra.Command{}
617+
args := []string{}
618+
619+
// Create a test function that uses the temp file
620+
testDualStack := func(cmd *cobra.Command, args []string) error {
621+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
622+
623+
val := ""
624+
if eniCfg != nil {
625+
switch eniCfg.IPStack {
626+
case "dual", "ipv6":
627+
val = True
628+
default:
629+
val = False
630+
}
631+
} else {
632+
val = False // default behavior when eniCfg is nil
633+
}
634+
635+
err := store.Load()
636+
if err != nil {
637+
return err
638+
}
639+
640+
store.Set(nodecap.NodeCapabilityIPv6, val)
641+
return store.Save()
642+
}
643+
644+
err = testDualStack(cmd, args)
645+
assert.NoError(t, err)
646+
647+
// Verify the capability was set to False when eniCfg is nil
648+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
649+
err = store.Load()
650+
assert.NoError(t, err)
651+
assert.Equal(t, False, store.Get(nodecap.NodeCapabilityIPv6))
652+
}
653+
654+
// TestDualStackStoreLoadError tests dualStack when store.Load() fails
655+
func TestDualStackStoreLoadError(t *testing.T) {
656+
// Use a directory path instead of file path to cause Load() to fail
657+
tempDir, err := os.MkdirTemp("", "test_node_capabilities_dir")
658+
assert.NoError(t, err)
659+
defer os.RemoveAll(tempDir)
660+
661+
eniCfg = &daemon.Config{IPStack: "dual"}
662+
663+
testDualStack := func(cmd *cobra.Command, args []string) error {
664+
store := nodecap.NewFileNodeCapabilities(tempDir) // directory instead of file
665+
666+
val := ""
667+
switch eniCfg.IPStack {
668+
case "dual", "ipv6":
669+
val = True
670+
default:
671+
val = False
672+
}
673+
674+
err := store.Load()
675+
if err != nil {
676+
return err
677+
}
678+
679+
store.Set(nodecap.NodeCapabilityIPv6, val)
680+
return store.Save()
681+
}
682+
683+
cmd := &cobra.Command{}
684+
args := []string{}
685+
err = testDualStack(cmd, args)
686+
assert.Error(t, err) // Should error because Load() fails on directory
687+
}
688+
689+
// TestEnableKPRFeatureDisabled tests enableKPR when KubeProxyReplacement feature is disabled
690+
func TestEnableKPRFeatureDisabled(t *testing.T) {
691+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
692+
assert.NoError(t, err)
693+
defer os.Remove(tempFile.Name())
694+
695+
cmd := &cobra.Command{}
696+
args := []string{}
697+
698+
// Create a test function that mimics enableKPR but without feature gate check
699+
testEnableKPRDisabled := func(cmd *cobra.Command, args []string) error {
700+
// Simulate feature disabled by returning early
701+
return nil
702+
}
703+
704+
err = testEnableKPRDisabled(cmd, args)
705+
assert.NoError(t, err)
706+
}
707+
708+
// TestEnableKPRStoreLoadError tests enableKPR when store.Load() fails
709+
func TestEnableKPRStoreLoadError(t *testing.T) {
710+
// Use a directory path instead of file path to cause Load() to fail
711+
tempDir, err := os.MkdirTemp("", "test_node_capabilities_dir")
712+
assert.NoError(t, err)
713+
defer os.RemoveAll(tempDir)
714+
715+
cmd := &cobra.Command{}
716+
args := []string{}
717+
718+
testEnableKPRLoadError := func(cmd *cobra.Command, args []string) error {
719+
store := nodecap.NewFileNodeCapabilities(tempDir) // directory instead of file
720+
721+
err := store.Load()
722+
if err != nil {
723+
return err
724+
}
725+
726+
prev := store.Get(nodecap.NodeCapabilityKubeProxyReplacement)
727+
if prev != "" {
728+
return nil
729+
}
730+
731+
store.Set(nodecap.NodeCapabilityKubeProxyReplacement, True)
732+
return store.Save()
733+
}
734+
735+
err = testEnableKPRLoadError(cmd, args)
736+
assert.Error(t, err) // Should error because Load() fails on directory
737+
}
738+
739+
// TestEnableKPRAlreadySet tests enableKPR when capability is already set
740+
func TestEnableKPRAlreadySet(t *testing.T) {
741+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
742+
assert.NoError(t, err)
743+
defer os.Remove(tempFile.Name())
744+
745+
// Pre-populate the file with existing capability
746+
err = os.WriteFile(tempFile.Name(), []byte("cni_kube_proxy_replacement = true"), 0644)
747+
assert.NoError(t, err)
748+
749+
cmd := &cobra.Command{}
750+
args := []string{}
751+
752+
testEnableKPRAlreadySet := func(cmd *cobra.Command, args []string) error {
753+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
754+
755+
err := store.Load()
756+
if err != nil {
757+
return err
758+
}
759+
760+
prev := store.Get(nodecap.NodeCapabilityKubeProxyReplacement)
761+
if prev != "" {
762+
return nil // Should return early
763+
}
764+
765+
store.Set(nodecap.NodeCapabilityKubeProxyReplacement, True)
766+
return store.Save()
767+
}
768+
769+
err = testEnableKPRAlreadySet(cmd, args)
770+
assert.NoError(t, err)
771+
772+
// Verify the capability remains unchanged
773+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
774+
err = store.Load()
775+
assert.NoError(t, err)
776+
assert.Equal(t, "true", store.Get(nodecap.NodeCapabilityKubeProxyReplacement))
777+
}
778+
779+
// TestEnableKPRStoreSaveError tests enableKPR when store.Save() fails
780+
func TestEnableKPRStoreSaveError(t *testing.T) {
781+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
782+
assert.NoError(t, err)
783+
defer os.Remove(tempFile.Name())
784+
785+
cmd := &cobra.Command{}
786+
args := []string{}
787+
788+
testEnableKPRSaveError := func(cmd *cobra.Command, args []string) error {
789+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
790+
791+
err := store.Load()
792+
if err != nil {
793+
return err
794+
}
795+
796+
prev := store.Get(nodecap.NodeCapabilityKubeProxyReplacement)
797+
if prev != "" {
798+
return nil
799+
}
800+
801+
store.Set(nodecap.NodeCapabilityKubeProxyReplacement, True)
802+
803+
// Remove the file to make Save() fail
804+
os.Remove(tempFile.Name())
805+
// Create a directory with the same name to make Save() fail
806+
os.Mkdir(tempFile.Name(), 0755)
807+
defer os.RemoveAll(tempFile.Name())
808+
809+
return store.Save()
810+
}
811+
812+
err = testEnableKPRSaveError(cmd, args)
813+
assert.Error(t, err) // Should error because Save() fails
814+
}
815+
816+
// TestOverrideCNIGetAllConfigError tests overrideCNI when getAllConfig fails
817+
func TestOverrideCNIGetAllConfigError(t *testing.T) {
818+
// Set environment variable for node name
819+
os.Setenv("K8S_NODE_NAME", "test-node")
820+
defer os.Unsetenv("K8S_NODE_NAME")
821+
822+
// Create a temporary directory without required files to make getAllConfig fail
823+
tempDir, err := os.MkdirTemp("", "test_override_cni")
824+
assert.NoError(t, err)
825+
defer os.RemoveAll(tempDir)
826+
827+
cmd := &cobra.Command{}
828+
args := []string{}
829+
830+
// Test function that mimics getENIConfig but uses our temp directory
831+
testGetENIConfigError := func(cmd *cobra.Command, args []string) error {
832+
_, err := getAllConfig(tempDir) // This should fail due to missing files
833+
return err
834+
}
835+
836+
err = testGetENIConfigError(cmd, args)
837+
assert.Error(t, err) // Should error because required files are missing
838+
}
839+
840+
// TestSetExclusiveModeWithInvalidCNIPath tests setExclusiveMode with invalid CNI path
841+
func TestSetExclusiveModeWithInvalidCNIPath(t *testing.T) {
842+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
843+
assert.NoError(t, err)
844+
defer os.Remove(tempFile.Name())
845+
846+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
847+
labels := map[string]string{
848+
"k8s.aliyun.com/exclusive-mode-eni-type": "eniOnly",
849+
}
850+
// Use an invalid directory path for CNI config
851+
cniPath := "/invalid/directory/path/cni_config"
852+
853+
err = setExclusiveMode(store, labels, cniPath)
854+
assert.Error(t, err) // Should error because CNI path is invalid
855+
}
856+
857+
// TestSetExclusiveModeWithMissingLabel tests setExclusiveMode with missing exclusive mode label
858+
func TestSetExclusiveModeWithMissingLabel(t *testing.T) {
859+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
860+
assert.NoError(t, err)
861+
defer os.Remove(tempFile.Name())
862+
863+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
864+
labels := map[string]string{} // Empty labels
865+
cniPath := tempFile.Name() + "_cni_config"
866+
867+
err = setExclusiveMode(store, labels, cniPath)
868+
assert.NoError(t, err)
869+
870+
// Verify default mode was set
871+
err = store.Load()
872+
assert.NoError(t, err)
873+
assert.Equal(t, "default", store.Get(nodecap.NodeCapabilityExclusiveENI))
874+
}
875+
876+
// TestSetExclusiveModeWithUnknownLabel tests setExclusiveMode with unknown exclusive mode label
877+
func TestSetExclusiveModeWithUnknownLabel(t *testing.T) {
878+
tempFile, err := os.CreateTemp("", "test_node_capabilities")
879+
assert.NoError(t, err)
880+
defer os.Remove(tempFile.Name())
881+
882+
store := nodecap.NewFileNodeCapabilities(tempFile.Name())
883+
labels := map[string]string{
884+
"k8s.aliyun.com/exclusive-mode-eni-type": "unknown",
885+
}
886+
cniPath := tempFile.Name() + "_cni_config"
887+
888+
err = setExclusiveMode(store, labels, cniPath)
889+
assert.NoError(t, err)
890+
891+
// Verify default mode was set for unknown label value
892+
err = store.Load()
893+
assert.NoError(t, err)
894+
assert.Equal(t, "default", store.Get(nodecap.NodeCapabilityExclusiveENI))
895+
}

0 commit comments

Comments
 (0)