From 42afa0a2cca19c9738b7e283f77b37ec60da9309 Mon Sep 17 00:00:00 2001 From: Matt Mix Date: Wed, 1 Jan 2020 00:23:59 -0500 Subject: [PATCH] Adding in missing Registry unit tests. --- .../framework/v1alpha1/registry_test.go | 221 ++++++++++++++++-- 1 file changed, 204 insertions(+), 17 deletions(-) diff --git a/pkg/scheduler/framework/v1alpha1/registry_test.go b/pkg/scheduler/framework/v1alpha1/registry_test.go index 17bff96d99b..bf73ed87369 100644 --- a/pkg/scheduler/framework/v1alpha1/registry_test.go +++ b/pkg/scheduler/framework/v1alpha1/registry_test.go @@ -32,7 +32,7 @@ func TestDecodeInto(t *testing.T) { tests := []struct { name string schedulerConfig string - expeted PluginFooConfig + expected PluginFooConfig }{ { name: "test decode for JSON config", @@ -57,7 +57,7 @@ func TestDecodeInto(t *testing.T) { } ] }`, - expeted: PluginFooConfig{ + expected: PluginFooConfig{ FooTest: "test decode", }, }, @@ -74,25 +74,28 @@ pluginConfig: - name: foo args: foo_test: "test decode"`, - expeted: PluginFooConfig{ + expected: PluginFooConfig{ FooTest: "test decode", }, }, } - for i, test := range tests { - schedulerConf, err := loadConfig([]byte(test.schedulerConfig)) - if err != nil { - t.Errorf("Test #%v(%s): failed to load scheduler config: %v", i, test.name, err) - } - var pluginFooConf PluginFooConfig - if err := DecodeInto(&schedulerConf.PluginConfig[0].Args, &pluginFooConf); err != nil { - t.Errorf("Test #%v(%s): failed to decode args %+v: %v", - i, test.name, schedulerConf.PluginConfig[0].Args, err) - } - if !reflect.DeepEqual(pluginFooConf, test.expeted) { - t.Errorf("Test #%v(%s): failed to decode plugin config, expected: %+v, got: %+v", - i, test.name, test.expeted, pluginFooConf) - } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + schedulerConf, err := loadConfig([]byte(test.schedulerConfig)) + if err != nil { + t.Errorf("loadConfig(): failed to load scheduler config: %v", err) + } + var pluginFooConf PluginFooConfig + if err := DecodeInto(&schedulerConf.PluginConfig[0].Args, &pluginFooConf); err != nil { + t.Errorf("DecodeInto(): failed to decode args %+v: %v", + schedulerConf.PluginConfig[0].Args, err) + } + if !reflect.DeepEqual(test.expected, pluginFooConf) { + t.Errorf("DecodeInto(): failed to decode plugin config, expected: %+v, got: %+v", + test.expected, pluginFooConf) + } + }) } } @@ -104,3 +107,187 @@ func loadConfig(data []byte) (*config.KubeSchedulerConfiguration, error) { return configObj, nil } + +// isRegistryEqual compares two registries for equality. This function is used in place of +// reflect.DeepEqual() and cmp() as they don't compare function values. +func isRegistryEqual(registryX, registryY Registry) bool { + for name, pluginFactory := range registryY { + if val, ok := registryX[name]; ok { + if reflect.ValueOf(pluginFactory) != reflect.ValueOf(val) { + // pluginFactory functions are not the same. + return false + } + } else { + // registryY contains an entry that is not present in registryX + return false + } + } + + for name := range registryX { + if _, ok := registryY[name]; !ok { + // registryX contains an entry that is not present in registryY + return false + } + } + + return true +} + +type mockNoopPlugin struct{} + +func (p *mockNoopPlugin) Name() string { + return "MockNoop" +} + +func NewMockNoopPluginFactory() PluginFactory { + return func(_ *runtime.Unknown, _ FrameworkHandle) (Plugin, error) { + return &mockNoopPlugin{}, nil + } +} + +func TestMerge(t *testing.T) { + tests := []struct { + name string + primaryRegistry Registry + registryToMerge Registry + expected Registry + shouldError bool + }{ + { + name: "valid Merge", + primaryRegistry: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + registryToMerge: Registry{ + "pluginFactory2": NewMockNoopPluginFactory(), + }, + expected: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + "pluginFactory2": NewMockNoopPluginFactory(), + }, + shouldError: false, + }, + { + name: "Merge duplicate factories", + primaryRegistry: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + registryToMerge: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + expected: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + shouldError: true, + }, + } + + for _, scenario := range tests { + t.Run(scenario.name, func(t *testing.T) { + err := scenario.primaryRegistry.Merge(scenario.registryToMerge) + + if (err == nil) == scenario.shouldError { + t.Errorf("Merge() shouldError is: %v, however err is: %v.", scenario.shouldError, err) + return + } + + if !isRegistryEqual(scenario.expected, scenario.primaryRegistry) { + t.Errorf("Merge(). Expected %v. Got %v instead.", scenario.expected, scenario.primaryRegistry) + } + }) + } +} + +func TestRegister(t *testing.T) { + tests := []struct { + name string + registry Registry + nameToRegister string + factoryToRegister PluginFactory + expected Registry + shouldError bool + }{ + { + name: "valid Register", + registry: Registry{}, + nameToRegister: "pluginFactory1", + factoryToRegister: NewMockNoopPluginFactory(), + expected: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + shouldError: false, + }, + { + name: "Register duplicate factories", + registry: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + nameToRegister: "pluginFactory1", + factoryToRegister: NewMockNoopPluginFactory(), + expected: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + }, + shouldError: true, + }, + } + + for _, scenario := range tests { + t.Run(scenario.name, func(t *testing.T) { + err := scenario.registry.Register(scenario.nameToRegister, scenario.factoryToRegister) + + if (err == nil) == scenario.shouldError { + t.Errorf("Register() shouldError is: %v however err is: %v.", scenario.shouldError, err) + return + } + + if !isRegistryEqual(scenario.expected, scenario.registry) { + t.Errorf("Register(). Expected %v. Got %v instead.", scenario.expected, scenario.registry) + } + }) + } +} + +func TestUnregister(t *testing.T) { + tests := []struct { + name string + registry Registry + nameToUnregister string + expected Registry + shouldError bool + }{ + { + name: "valid Unregister", + registry: Registry{ + "pluginFactory1": NewMockNoopPluginFactory(), + "pluginFactory2": NewMockNoopPluginFactory(), + }, + nameToUnregister: "pluginFactory1", + expected: Registry{ + "pluginFactory2": NewMockNoopPluginFactory(), + }, + shouldError: false, + }, + { + name: "Unregister non-existent plugin factory", + registry: Registry{}, + nameToUnregister: "pluginFactory1", + expected: Registry{}, + shouldError: true, + }, + } + + for _, scenario := range tests { + t.Run(scenario.name, func(t *testing.T) { + err := scenario.registry.Unregister(scenario.nameToUnregister) + + if (err == nil) == scenario.shouldError { + t.Errorf("Unregister() shouldError is: %v however err is: %v.", scenario.shouldError, err) + return + } + + if !isRegistryEqual(scenario.expected, scenario.registry) { + t.Errorf("Unregister(). Expected %v. Got %v instead.", scenario.expected, scenario.registry) + } + }) + } +}