diff --git a/pkg/scheduler/algorithm/predicates/network_predicate.go b/pkg/scheduler/algorithm/predicates/network_predicate.go index 30b030afe4..b6c1e9c7c9 100644 --- a/pkg/scheduler/algorithm/predicates/network_predicate.go +++ b/pkg/scheduler/algorithm/predicates/network_predicate.go @@ -37,7 +37,17 @@ import ( type NetworkPredicate struct { BasePredicate plugin.BasePlugin - networkFreePortCount map[string]int + NetworkNicCountGetter INetworkNicCountGetter + networkFreePortCount map[string]int +} + +func NewNetworkPredicate(getter INetworkNicCountGetter) *NetworkPredicate { + if getter == nil { + getter = models.NetworkManager + } + return &NetworkPredicate{ + NetworkNicCountGetter: getter, + } } func (p *NetworkPredicate) Name() string { @@ -45,7 +55,13 @@ func (p *NetworkPredicate) Name() string { } func (p *NetworkPredicate) Clone() core.FitPredicate { - return &NetworkPredicate{} + return &NetworkPredicate{ + NetworkNicCountGetter: p.NetworkNicCountGetter, + } +} + +type INetworkNicCountGetter interface { + GetTotalNicCount([]string) (map[string]int, error) } func (p *NetworkPredicate) PreExecute(u *core.Unit, cs []core.Candidater) (bool, error) { @@ -59,7 +75,7 @@ func (p *NetworkPredicate) PreExecute(u *core.Unit, cs []core.Candidater) (bool, networkIds.Insert(net.GetId()) } } - netCounts, err := models.NetworkManager.GetTotalNicCount(networkIds.UnsortedList()) + netCounts, err := p.NetworkNicCountGetter.GetTotalNicCount(networkIds.UnsortedList()) if err != nil { return false, errors.Wrap(err, "unable to GetTotalNicCount") } diff --git a/pkg/scheduler/algorithmprovider/defaults.go b/pkg/scheduler/algorithmprovider/defaults.go index 2a466168c3..2db82de958 100644 --- a/pkg/scheduler/algorithmprovider/defaults.go +++ b/pkg/scheduler/algorithmprovider/defaults.go @@ -39,7 +39,7 @@ func defaultPredicates() sets.String { factory.RegisterFitPredicate("g-GuestCPUFilter", &predicateguest.CPUPredicate{}), factory.RegisterFitPredicate("h-GuestMemoryFilter", &predicateguest.MemoryPredicate{}), factory.RegisterFitPredicate("i-GuestStorageFilter", &predicateguest.StoragePredicate{}), - factory.RegisterFitPredicate("j-GuestNetworkFilter", &predicates.NetworkPredicate{}), + factory.RegisterFitPredicate("j-GuestNetworkFilter", predicates.NewNetworkPredicate(nil)), factory.RegisterFitPredicate("k-GuestIsolatedDeviceFilter", &predicates.IsolatedDevicePredicate{}), factory.RegisterFitPredicate("l-GuestResourceTypeFilter", &predicates.ResourceTypePredicate{}), factory.RegisterFitPredicate("m-GuestDiskschedtagFilter", &predicates.DiskSchedtagPredicate{}), diff --git a/pkg/scheduler/test/generic_scheduler_test.go b/pkg/scheduler/test/generic_scheduler_test.go index 0e2c219e9b..6edc4b0f5b 100644 --- a/pkg/scheduler/test/generic_scheduler_test.go +++ b/pkg/scheduler/test/generic_scheduler_test.go @@ -31,11 +31,6 @@ import ( func TestGenericSchedulerSchedule(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - scheduler, err := core.NewGenericScheduler(buildScheduler(ctrl, basePredicateNames...)) - if err != nil { - t.Errorf("NewGenericScheduler: %s", err.Error()) - return - } commonInfo := &api.SchedInfo{ ScheduleInput: &apisdu.ScheduleInput{ ServerConfig: apisdu.ServerConfig{ @@ -114,12 +109,17 @@ func TestGenericSchedulerSchedule(t *testing.T) { TotalMemorySize: 10240, FreeMemorySize: 10240, FreeStorageSizeAnyType: 201330, - FreePort: 10, FreeGroupCount: 1, Skus: []string{"ecs.g1.c1m1"}, } + netowrkNicCount := map[string]int{"nework01": 10} + scheduler, err := core.NewGenericScheduler(buildScheduler(ctrl, netowrkNicCount, basePredicateNames...)) + if err != nil { + t.Errorf("NewGenericScheduler: %s", err.Error()) + return + } candidate := buildCandidate(ctrl, getterParam) - _, err := scheduler.Schedule(preSchedule(info, []core.Candidater{candidate}, false)) + _, err = scheduler.Schedule(preSchedule(info, []core.Candidater{candidate}, false)) if err != nil { t.Errorf("genericScheduler.Schedule error: %s", err.Error()) } @@ -149,7 +149,6 @@ func TestGenericSchedulerSchedule(t *testing.T) { TotalMemorySize: 10240, FreeMemorySize: 10240, FreeStorageSizeAnyType: 201330, - FreePort: 1, Skus: []string{"ecs.g1.c1m1"}, } getterParam2 := getterParam1 @@ -163,6 +162,17 @@ func TestGenericSchedulerSchedule(t *testing.T) { buildCandidate(ctrl, getterParam1), buildCandidate(ctrl, getterParam2), } + netowrkNicCount := map[string]int{ + "network01": 255, + "network02": 256, + "network03": 1, + "network04": 1, + } + scheduler, err := core.NewGenericScheduler(buildScheduler(ctrl, netowrkNicCount, basePredicateNames...)) + if err != nil { + t.Errorf("NewGenericScheduler: %s", err.Error()) + return + } res, err := scheduler.Schedule(preSchedule(info, candidates, true)) if err != nil { t.Errorf("genericScheduler.Schedule error: %s", err.Error()) diff --git a/pkg/scheduler/test/mock/core.go b/pkg/scheduler/test/mock/core.go index 0878a719cb..45a7c770a3 100644 --- a/pkg/scheduler/test/mock/core.go +++ b/pkg/scheduler/test/mock/core.go @@ -884,3 +884,41 @@ func (mr *MockSchedulerMockRecorder) PriorityConfigs() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PriorityConfigs", reflect.TypeOf((*MockScheduler)(nil).PriorityConfigs)) } + +// MockINetworkNicCountGetter is a mock of INetworkNicCountGetter interface +type MockINetworkNicCountGetter struct { + ctrl *gomock.Controller + recorder *MockINetworkNicCountGetterMockRecorder +} + +// MockINetworkNicCountGetterMockRecorder is the mock recorder for MockINetworkNicCountGetter +type MockINetworkNicCountGetterMockRecorder struct { + mock *MockINetworkNicCountGetter +} + +// NewMockINetworkNicCountGetter creates a new mock instance +func NewMockINetworkNicCountGetter(ctrl *gomock.Controller) *MockINetworkNicCountGetter { + mock := &MockINetworkNicCountGetter{ctrl: ctrl} + mock.recorder = &MockINetworkNicCountGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockINetworkNicCountGetter) EXPECT() *MockINetworkNicCountGetterMockRecorder { + return m.recorder +} + +// GetTotalNicCount mocks base method +func (m *MockINetworkNicCountGetter) GetTotalNicCount(arg0 []string) (map[string]int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTotalNicCount", arg0) + ret0, _ := ret[0].(map[string]int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTotalNicCount indicates an expected call of GetTotalNicCount +func (mr *MockINetworkNicCountGetterMockRecorder) GetTotalNicCount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTotalNicCount", reflect.TypeOf((*MockINetworkNicCountGetter)(nil).GetTotalNicCount), arg0) +} diff --git a/pkg/scheduler/test/prepare.go b/pkg/scheduler/test/prepare.go index c72fb63ef9..423ed0f6e1 100644 --- a/pkg/scheduler/test/prepare.go +++ b/pkg/scheduler/test/prepare.go @@ -27,26 +27,28 @@ import ( computeapi "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/compute/models" + pre "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates" _ "yunion.io/x/onecloud/pkg/scheduler/algorithmprovider" "yunion.io/x/onecloud/pkg/scheduler/api" "yunion.io/x/onecloud/pkg/scheduler/core" "yunion.io/x/onecloud/pkg/scheduler/data_manager/sku" "yunion.io/x/onecloud/pkg/scheduler/factory" + schmodels "yunion.io/x/onecloud/pkg/scheduler/models" "yunion.io/x/onecloud/pkg/scheduler/test/mock" ) type sPredicateName string var ( - HostStatus sPredicateName = "a-GuestHostStatusFilter" - Hypervisor sPredicateName = "b-GuestHypervisorFilter" - Migrate sPredicateName = "d-GuestMigrateFilter" - Domain sPredicateName = "e-GuestDomainFilter" - Image sPredicateName = "e-GuestImageFilter" - CPU sPredicateName = "g-GuestCPUFilter" - Memory sPredicateName = "h-GuestMemoryFilter" - Storage sPredicateName = "i-GuestStorageFilter" - Network sPredicateName = "j-GuestNetworkFilter" + HostStatus sPredicateName = "a-GuestHostStatusFilter" + Hypervisor sPredicateName = "b-GuestHypervisorFilter" + Migrate sPredicateName = "d-GuestMigrateFilter" + Domain sPredicateName = "e-GuestDomainFilter" + Image sPredicateName = "e-GuestImageFilter" + CPU sPredicateName = "g-GuestCPUFilter" + Memory sPredicateName = "h-GuestMemoryFilter" + Storage sPredicateName = "i-GuestStorageFilter" + //Network sPredicateName = "j-GuestNetworkFilter" IsolateDevice sPredicateName = "k-GuestIsolatedDeviceFilter" ResourceType sPredicateName = "l-GuestResourceTypeFilter" ServerSku sPredicateName = "n-ServerSkuFilter" @@ -60,7 +62,7 @@ var ( Quota sPredicateName = "z-QuotaFilter" basePredicateNames = []sPredicateName{ - HostStatus, Hypervisor, Migrate, Domain, Image, CPU, Memory, Storage, Network, + HostStatus, Hypervisor, Migrate, Domain, Image, CPU, Memory, Storage, IsolateDevice, ResourceType, ServerSku, } ) @@ -105,7 +107,6 @@ type sGetterParams struct { TotalMemorySize int64 FreeMemorySize int64 FreeStorageSizeAnyType int64 - FreePort int QuotaKeys *models.SComputeResourceKeys FreeGroupCount int Skus []string @@ -170,15 +171,17 @@ func buildGetter(ctrl *gomock.Controller, param sGetterParams) *mock.MockCandida cg.EXPECT().TotalMemorySize(gomock.Any()).AnyTimes().Return(param.TotalMemorySize) cg.EXPECT().FreeMemorySize(gomock.Any()).AnyTimes().Return(param.FreeMemorySize) cg.EXPECT().GetFreeStorageSizeOfType(gomock.Any(), gomock.Any()).AnyTimes().Return(param.FreeStorageSizeAnyType, int64(0)) - cg.EXPECT().GetFreePort(gomock.Any()).AnyTimes().Return(param.FreePort) if param.QuotaKeys != nil { cg.EXPECT().GetQuotaKeys(gomock.Any()).AnyTimes().Return(param.QuotaKeys) } cg.EXPECT().GetFreeGroupCount(gomock.Any()).AnyTimes().Return(param.FreeGroupCount, nil) + cg.EXPECT().GetPendingUsage().AnyTimes().Return(&schmodels.SPendingUsage{ + NetUsage: schmodels.NewResourcePendingUsage(map[string]int{}), + }) return cg } -func buildScheduler(ctrl *gomock.Controller, predicates ...sPredicateName) core.Scheduler { +func buildScheduler(ctrl *gomock.Controller, networkNicCount map[string]int, predicates ...sPredicateName) core.Scheduler { pres := sets.NewString() for _, pre := range predicates { pres.Insert(string(pre)) @@ -186,8 +189,20 @@ func buildScheduler(ctrl *gomock.Controller, predicates ...sPredicateName) core. algorithmProvider, _ := factory.GetAlgorithmProvider(factory.DefaultProvider) mockScheduler := mock.NewMockScheduler(ctrl) mockScheduler.EXPECT().BeforePredicate().AnyTimes().Return(nil) + networkNicGetter := mock.NewMockINetworkNicCountGetter(ctrl) + networkNicGetter.EXPECT().GetTotalNicCount(gomock.AssignableToTypeOf([]string{})).AnyTimes().DoAndReturn(func(netIds []string) (map[string]int, error) { + return networkNicCount, nil + }) mockScheduler.EXPECT().Predicates().AnyTimes().DoAndReturn(func() (map[string]core.FitPredicate, error) { - return factory.GetPredicates(pres) + ret, err := factory.GetPredicates(pres) + if err != nil { + return nil, err + } + if networkNicGetter == nil { + fmt.Printf("networkNicGetter is nil") + } + ret["j-GuestNetworkFilter"] = pre.NewNetworkPredicate(networkNicGetter) + return ret, nil }) mockScheduler.EXPECT().PriorityConfigs().AnyTimes().DoAndReturn(func() ([]core.PriorityConfig, error) { return factory.GetPriorityConfigs(algorithmProvider.PriorityKeys)