77 "encoding/json"
88 "fmt"
99 "reflect"
10+ "strconv"
1011 "testing"
1112
1213 "github.com/Azure/azure-container-networking/cns"
3738 PodName : "testpod3" ,
3839 PodNamespace : "testpod3namespace" ,
3940 }
41+
42+ testIP4 = "10.0.0.4"
43+ testPod4GUID = "718e04ac-5a13-4dce-84b3-040accaa9b42"
4044)
4145
4246func getTestService () * HTTPRestService {
@@ -550,7 +554,7 @@ func TestIPAMMarkIPCountAsPending(t *testing.T) {
550554 }
551555
552556 // Release Test Pod 1
553- ips , err := svc .MarkIPsAsPending (1 )
557+ ips , err := svc .MarkIPAsPendingRelease (1 )
554558 if err != nil {
555559 t .Fatalf ("Unexpected failure releasing IP: %+v" , err )
556560 }
@@ -575,6 +579,93 @@ func TestIPAMMarkIPCountAsPending(t *testing.T) {
575579 if err != nil {
576580 t .Fatalf ("Unexpected failure releasing IP: %+v" , err )
577581 }
582+
583+ // Try to release IP when no IP can be released. It should return error and ips will be nil
584+ ips , err = svc .MarkIPAsPendingRelease (1 )
585+ if err == nil || ips != nil {
586+ t .Fatalf ("We are expecting err and ips should be nil, however, return these IP %v" , ips )
587+ }
588+ }
589+
590+ func TestIPAMMarkIPAsPendingWithPendingProgrammingIPs (t * testing.T ) {
591+ svc := getTestService ()
592+
593+ secondaryIPConfigs := make (map [string ]cns.SecondaryIPConfig )
594+ // Default Programmed NC version is -1, set nc version as 0 will result in pending programming state.
595+ constructSecondaryIPConfigs (testIP1 , testPod1GUID , 0 , secondaryIPConfigs )
596+ constructSecondaryIPConfigs (testIP3 , testPod3GUID , 0 , secondaryIPConfigs )
597+ // Default Programmed NC version is -1, set nc version as -1 will result in available state.
598+ constructSecondaryIPConfigs (testIP2 , testPod2GUID , - 1 , secondaryIPConfigs )
599+ constructSecondaryIPConfigs (testIP4 , testPod4GUID , - 1 , secondaryIPConfigs )
600+
601+ // createNCRequest with NC version 0
602+ req := generateNetworkContainerRequest (secondaryIPConfigs , testNCID , strconv .Itoa (0 ))
603+ returnCode := svc .CreateOrUpdateNetworkContainerInternal (req , fakes .NewFakeScalar (releasePercent , requestPercent , batchSize ), fakes .NewFakeNodeNetworkConfigSpec (initPoolSize ))
604+ if returnCode != 0 {
605+ t .Fatalf ("Failed to createNetworkContainerRequest, req: %+v, err: %d" , req , returnCode )
606+ }
607+
608+ // Release pending programming IPs
609+ ips , err := svc .MarkIPAsPendingRelease (2 )
610+ if err != nil {
611+ t .Fatalf ("Unexpected failure releasing IP: %+v" , err )
612+ }
613+ // Check returning released IPs are from pod 1 and 3
614+ if _ , exists := ips [testPod1GUID ]; ! exists {
615+ t .Fatalf ("Expected ID not marked as pending: %+v, ips is %s" , err , ips )
616+ }
617+ if _ , exists := ips [testPod3GUID ]; ! exists {
618+ t .Fatalf ("Expected ID not marked as pending: %+v, ips is %s" , err , ips )
619+ }
620+
621+ pendingRelease := svc .GetPendingReleaseIPConfigs ()
622+ if len (pendingRelease ) != 2 {
623+ t .Fatalf ("Expected 2 pending release IPs but got %d pending release IP" , len (pendingRelease ))
624+ }
625+ // Check pending release IDs are from pod 1 and 3
626+ for _ , config := range pendingRelease {
627+ if config .ID != testPod1GUID && config .ID != testPod3GUID {
628+ t .Fatalf ("Expected pending release ID is either from pod 1 or pod 3 but got ID as %s " , config .ID )
629+ }
630+ }
631+
632+ available := svc .GetAvailableIPConfigs ()
633+ if len (available ) != 2 {
634+ t .Fatalf ("Expected 1 available IP with test pod 2 but got available %d IP" , len (available ))
635+ }
636+
637+ // Call release again, should be fine
638+ err = svc .releaseIPConfig (testPod1Info )
639+ if err != nil {
640+ t .Fatalf ("Unexpected failure releasing IP: %+v" , err )
641+ }
642+
643+ // Release 2 more IPs
644+ ips , err = svc .MarkIPAsPendingRelease (2 )
645+ if err != nil {
646+ t .Fatalf ("Unexpected failure releasing IP: %+v" , err )
647+ }
648+ // Make sure newly released IPs are from pod 2 and pod 4
649+ if _ , exists := ips [testPod2GUID ]; ! exists {
650+ t .Fatalf ("Expected ID not marked as pending: %+v, ips is %s" , err , ips )
651+ }
652+ if _ , exists := ips [testPod4GUID ]; ! exists {
653+ t .Fatalf ("Expected ID not marked as pending: %+v, ips is %s" , err , ips )
654+ }
655+
656+ // Get all pending release IPs and check total number is 4
657+ pendingRelease = svc .GetPendingReleaseIPConfigs ()
658+ if len (pendingRelease ) != 4 {
659+ t .Fatalf ("Expected 4 pending release IPs but got %d pending release IP" , len (pendingRelease ))
660+ }
661+ }
662+
663+ func constructSecondaryIPConfigs (ipAddress , uuid string , ncVersion int , secondaryIPConfigs map [string ]cns.SecondaryIPConfig ) {
664+ secIpConfig := cns.SecondaryIPConfig {
665+ IPAddress : ipAddress ,
666+ NCVersion : ncVersion ,
667+ }
668+ secondaryIPConfigs [uuid ] = secIpConfig
578669}
579670
580671func TestIPAMMarkExistingIPConfigAsPending (t * testing.T ) {
0 commit comments