@@ -791,3 +791,192 @@ func TestTopologyAlignedAllocation(t *testing.T) {
791
791
}
792
792
}
793
793
}
794
+
795
+ func TestGetPreferredAllocationParameters (t * testing.T ) {
796
+ tcases := []struct {
797
+ description string
798
+ resource string
799
+ request int
800
+ allDevices []pluginapi.Device
801
+ allocatedDevices []string
802
+ reusableDevices []string
803
+ hint topologymanager.TopologyHint
804
+ expectedAvailable []string
805
+ expectedMustInclude []string
806
+ expectedSize int
807
+ }{
808
+ {
809
+ description : "Request for 1, socket 0, 0 already allocated, 0 reusable" ,
810
+ resource : "resource" ,
811
+ request : 1 ,
812
+ allDevices : []pluginapi.Device {
813
+ makeNUMADevice ("Dev0" , 0 ),
814
+ makeNUMADevice ("Dev1" , 0 ),
815
+ makeNUMADevice ("Dev2" , 0 ),
816
+ makeNUMADevice ("Dev3" , 0 ),
817
+ },
818
+ allocatedDevices : []string {},
819
+ reusableDevices : []string {},
820
+ hint : topologymanager.TopologyHint {
821
+ NUMANodeAffinity : makeSocketMask (0 ),
822
+ Preferred : true ,
823
+ },
824
+ expectedAvailable : []string {"Dev0" , "Dev1" , "Dev2" , "Dev3" },
825
+ expectedMustInclude : []string {},
826
+ expectedSize : 1 ,
827
+ },
828
+ {
829
+ description : "Request for 4, socket 0, 2 already allocated, 2 reusable" ,
830
+ resource : "resource" ,
831
+ request : 4 ,
832
+ allDevices : []pluginapi.Device {
833
+ makeNUMADevice ("Dev0" , 0 ),
834
+ makeNUMADevice ("Dev1" , 0 ),
835
+ makeNUMADevice ("Dev2" , 0 ),
836
+ makeNUMADevice ("Dev3" , 0 ),
837
+ makeNUMADevice ("Dev4" , 0 ),
838
+ makeNUMADevice ("Dev5" , 0 ),
839
+ makeNUMADevice ("Dev6" , 0 ),
840
+ makeNUMADevice ("Dev7" , 0 ),
841
+ },
842
+ allocatedDevices : []string {"Dev0" , "Dev5" },
843
+ reusableDevices : []string {"Dev0" , "Dev5" },
844
+ hint : topologymanager.TopologyHint {
845
+ NUMANodeAffinity : makeSocketMask (0 ),
846
+ Preferred : true ,
847
+ },
848
+ expectedAvailable : []string {"Dev0" , "Dev1" , "Dev2" , "Dev3" , "Dev4" , "Dev5" , "Dev6" , "Dev7" },
849
+ expectedMustInclude : []string {"Dev0" , "Dev5" },
850
+ expectedSize : 4 ,
851
+ },
852
+ {
853
+ description : "Request for 4, socket 0, 4 already allocated, 2 reusable" ,
854
+ resource : "resource" ,
855
+ request : 4 ,
856
+ allDevices : []pluginapi.Device {
857
+ makeNUMADevice ("Dev0" , 0 ),
858
+ makeNUMADevice ("Dev1" , 0 ),
859
+ makeNUMADevice ("Dev2" , 0 ),
860
+ makeNUMADevice ("Dev3" , 0 ),
861
+ makeNUMADevice ("Dev4" , 0 ),
862
+ makeNUMADevice ("Dev5" , 0 ),
863
+ makeNUMADevice ("Dev6" , 0 ),
864
+ makeNUMADevice ("Dev7" , 0 ),
865
+ },
866
+ allocatedDevices : []string {"Dev0" , "Dev5" , "Dev4" , "Dev1" },
867
+ reusableDevices : []string {"Dev0" , "Dev5" },
868
+ hint : topologymanager.TopologyHint {
869
+ NUMANodeAffinity : makeSocketMask (0 ),
870
+ Preferred : true ,
871
+ },
872
+ expectedAvailable : []string {"Dev0" , "Dev2" , "Dev3" , "Dev5" , "Dev6" , "Dev7" },
873
+ expectedMustInclude : []string {"Dev0" , "Dev5" },
874
+ expectedSize : 4 ,
875
+ },
876
+ {
877
+ description : "Request for 6, multisocket, 2 already allocated, 2 reusable" ,
878
+ resource : "resource" ,
879
+ request : 6 ,
880
+ allDevices : []pluginapi.Device {
881
+ makeNUMADevice ("Dev0" , 0 ),
882
+ makeNUMADevice ("Dev1" , 0 ),
883
+ makeNUMADevice ("Dev2" , 0 ),
884
+ makeNUMADevice ("Dev3" , 0 ),
885
+ makeNUMADevice ("Dev4" , 1 ),
886
+ makeNUMADevice ("Dev5" , 1 ),
887
+ makeNUMADevice ("Dev6" , 1 ),
888
+ makeNUMADevice ("Dev7" , 1 ),
889
+ },
890
+ allocatedDevices : []string {"Dev1" , "Dev6" },
891
+ reusableDevices : []string {"Dev1" , "Dev6" },
892
+ hint : topologymanager.TopologyHint {
893
+ NUMANodeAffinity : makeSocketMask (0 ),
894
+ Preferred : true ,
895
+ },
896
+ expectedAvailable : []string {"Dev0" , "Dev1" , "Dev2" , "Dev3" , "Dev4" , "Dev5" , "Dev6" , "Dev7" },
897
+ expectedMustInclude : []string {"Dev0" , "Dev1" , "Dev2" , "Dev3" , "Dev6" },
898
+ expectedSize : 6 ,
899
+ },
900
+ {
901
+ description : "Request for 6, multisocket, 4 already allocated, 2 reusable" ,
902
+ resource : "resource" ,
903
+ request : 6 ,
904
+ allDevices : []pluginapi.Device {
905
+ makeNUMADevice ("Dev0" , 0 ),
906
+ makeNUMADevice ("Dev1" , 0 ),
907
+ makeNUMADevice ("Dev2" , 0 ),
908
+ makeNUMADevice ("Dev3" , 0 ),
909
+ makeNUMADevice ("Dev4" , 1 ),
910
+ makeNUMADevice ("Dev5" , 1 ),
911
+ makeNUMADevice ("Dev6" , 1 ),
912
+ makeNUMADevice ("Dev7" , 1 ),
913
+ },
914
+ allocatedDevices : []string {"Dev0" , "Dev1" , "Dev6" , "Dev7" },
915
+ reusableDevices : []string {"Dev1" , "Dev6" },
916
+ hint : topologymanager.TopologyHint {
917
+ NUMANodeAffinity : makeSocketMask (0 ),
918
+ Preferred : true ,
919
+ },
920
+ expectedAvailable : []string {"Dev1" , "Dev2" , "Dev3" , "Dev4" , "Dev5" , "Dev6" },
921
+ expectedMustInclude : []string {"Dev1" , "Dev2" , "Dev3" , "Dev6" },
922
+ expectedSize : 6 ,
923
+ },
924
+ }
925
+ for _ , tc := range tcases {
926
+ m := ManagerImpl {
927
+ allDevices : make (map [string ]map [string ]pluginapi.Device ),
928
+ healthyDevices : make (map [string ]sets.String ),
929
+ allocatedDevices : make (map [string ]sets.String ),
930
+ endpoints : make (map [string ]endpointInfo ),
931
+ podDevices : make (podDevices ),
932
+ sourcesReady : & sourcesReadyStub {},
933
+ activePods : func () []* v1.Pod { return []* v1.Pod {} },
934
+ topologyAffinityStore : & mockAffinityStore {tc .hint },
935
+ }
936
+
937
+ m .allDevices [tc .resource ] = make (map [string ]pluginapi.Device )
938
+ m .healthyDevices [tc .resource ] = sets .NewString ()
939
+ for _ , d := range tc .allDevices {
940
+ m.allDevices [tc.resource ][d.ID ] = d
941
+ m .healthyDevices [tc .resource ].Insert (d .ID )
942
+ }
943
+
944
+ m .allocatedDevices [tc .resource ] = sets .NewString ()
945
+ for _ , d := range tc .allocatedDevices {
946
+ m .allocatedDevices [tc .resource ].Insert (d )
947
+ }
948
+
949
+ actualAvailable := []string {}
950
+ actualMustInclude := []string {}
951
+ actualSize := 0
952
+ m .endpoints [tc .resource ] = endpointInfo {
953
+ e : & MockEndpoint {
954
+ getPreferredAllocationFunc : func (available , mustInclude []string , size int ) (* pluginapi.PreferredAllocationResponse , error ) {
955
+ actualAvailable = append (actualAvailable , available ... )
956
+ actualMustInclude = append (actualMustInclude , mustInclude ... )
957
+ actualSize = size
958
+ return nil , nil
959
+ },
960
+ },
961
+ opts : & pluginapi.DevicePluginOptions {GetPreferredAllocationAvailable : true },
962
+ }
963
+
964
+ _ , err := m .devicesToAllocate ("podUID" , "containerName" , tc .resource , tc .request , sets .NewString (tc .reusableDevices ... ))
965
+ if err != nil {
966
+ t .Errorf ("Unexpected error: %v" , err )
967
+ continue
968
+ }
969
+
970
+ if ! sets .NewString (actualAvailable ... ).Equal (sets .NewString (tc .expectedAvailable ... )) {
971
+ t .Errorf ("%v. expected available: %v but got: %v" , tc .description , tc .expectedAvailable , actualAvailable )
972
+ }
973
+
974
+ if ! sets .NewString (actualAvailable ... ).Equal (sets .NewString (tc .expectedAvailable ... )) {
975
+ t .Errorf ("%v. expected mustInclude: %v but got: %v" , tc .description , tc .expectedMustInclude , actualMustInclude )
976
+ }
977
+
978
+ if actualSize != tc .expectedSize {
979
+ t .Errorf ("%v. expected size: %v but got: %v" , tc .description , tc .expectedSize , actualSize )
980
+ }
981
+ }
982
+ }
0 commit comments