@@ -36,6 +36,7 @@ import (
3636 "sigs.k8s.io/descheduler/pkg/api"
3737 "sigs.k8s.io/descheduler/pkg/descheduler/evictions"
3838 "sigs.k8s.io/descheduler/pkg/features"
39+ fakeplugin "sigs.k8s.io/descheduler/pkg/framework/fake/plugin"
3940 "sigs.k8s.io/descheduler/pkg/framework/pluginregistry"
4041 "sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
4142 "sigs.k8s.io/descheduler/pkg/framework/plugins/nodeutilization"
@@ -1406,3 +1407,126 @@ func TestEvictedPodRestorationInDryRun(t *testing.T) {
14061407 klog .Infof ("Evicted pods cache was cleared after restoration in cycle %d" , i )
14071408 }
14081409}
1410+
1411+ // TestPluginInformerRegistration tests that plugin-specific informers are registered during newDescheduler
1412+ func TestPluginInformerRegistration (t * testing.T ) {
1413+ testCases := []struct {
1414+ name string
1415+ dryRun bool
1416+ }{
1417+ {
1418+ name : "dry run disabled" ,
1419+ dryRun : false ,
1420+ },
1421+ {
1422+ name : "dry run enabled" ,
1423+ dryRun : true ,
1424+ },
1425+ }
1426+
1427+ for _ , tc := range testCases {
1428+ t .Run (tc .name , func (t * testing.T ) {
1429+ ctx := context .Background ()
1430+
1431+ initPluginRegistry ()
1432+
1433+ // Define the custom informers that should be registered by the plugin
1434+ customInformers := []schema.GroupVersionResource {
1435+ {Group : "apps" , Version : "v1" , Resource : "daemonsets" },
1436+ {Group : "apps" , Version : "v1" , Resource : "replicasets" },
1437+ {Group : "apps" , Version : "v1" , Resource : "statefulsets" },
1438+ }
1439+
1440+ callbackInvoked := false
1441+ fakePlugin := & fakeplugin.FakePlugin {
1442+ PluginName : "TestPluginWithInformers" ,
1443+ }
1444+
1445+ // Register our mock plugin using NewPluginFncFromFakeWithReactor
1446+ pluginregistry .Register (
1447+ fakePlugin .PluginName ,
1448+ fakeplugin .NewPluginFncFromFakeWithReactor (fakePlugin , func (action fakeplugin.ActionImpl ) {
1449+ callbackInvoked = true
1450+ for _ , gvr := range customInformers {
1451+ _ , err := action .Handle ().SharedInformerFactory ().ForResource (gvr )
1452+ if err != nil {
1453+ panic (fmt .Sprintf ("Failed to register informer for %s: %v" , gvr .Resource , err ))
1454+ }
1455+ }
1456+ }),
1457+ & fakeplugin.FakePlugin {},
1458+ & fakeplugin.FakePluginArgs {},
1459+ fakeplugin .ValidateFakePluginArgs ,
1460+ fakeplugin .SetDefaults_FakePluginArgs ,
1461+ pluginregistry .PluginRegistry ,
1462+ )
1463+
1464+ deschedulerPolicy := & api.DeschedulerPolicy {
1465+ Profiles : []api.DeschedulerProfile {
1466+ {
1467+ Name : "test-profile" ,
1468+ PluginConfigs : []api.PluginConfig {
1469+ {
1470+ Name : fakePlugin .PluginName ,
1471+ Args : & fakeplugin.FakePluginArgs {},
1472+ },
1473+ },
1474+ Plugins : api.Plugins {
1475+ Deschedule : api.PluginSet {
1476+ Enabled : []string {fakePlugin .PluginName },
1477+ },
1478+ },
1479+ },
1480+ },
1481+ }
1482+
1483+ node1 := test .BuildTestNode ("node1" , 1000 , 2000 , 9 , nil )
1484+ node2 := test .BuildTestNode ("node2" , 1000 , 2000 , 9 , nil )
1485+
1486+ _ , descheduler , _ := initDescheduler (t , ctx , initFeatureGates (), deschedulerPolicy , nil , tc .dryRun , node1 , node2 )
1487+
1488+ if ! callbackInvoked {
1489+ t .Fatal ("Expected plugin initialization callback to be invoked" )
1490+ }
1491+
1492+ // Verify that custom informers were registered in the SharedInformerFactory
1493+ for _ , gvr := range customInformers {
1494+ informer , err := descheduler .sharedInformerFactory .ForResource (gvr )
1495+ if err != nil {
1496+ t .Errorf ("Expected %s informer to be registered in SharedInformerFactory, got error: %v" , gvr .Resource , err )
1497+ continue
1498+ }
1499+
1500+ if informer .Informer () == nil {
1501+ t .Errorf ("Expected %s informer to be registered in SharedInformerFactory" , gvr .Resource )
1502+ continue
1503+ }
1504+
1505+ var informer2 informers.GenericInformer
1506+ informer2 , err = descheduler .sharedInformerFactory .ForResource (gvr )
1507+ if err != nil {
1508+ t .Errorf ("Expected %s informer to be cached in factory, got error: %v" , gvr .Resource , err )
1509+ continue
1510+ }
1511+
1512+ if informer .Informer () != informer2 .Informer () {
1513+ t .Errorf ("Expected %s informer to be cached in factory" , gvr .Resource )
1514+ }
1515+ }
1516+
1517+ // Verify profileRunners were created
1518+ if len (descheduler .profileRunners ) == 0 {
1519+ t .Fatal ("Expected profileRunners to be created, got empty slice" )
1520+ }
1521+
1522+ if len (descheduler .profileRunners ) != 1 {
1523+ t .Fatalf ("Expected 1 profileRunner, got %d" , len (descheduler .profileRunners ))
1524+ }
1525+
1526+ // Verify profile name
1527+ if descheduler .profileRunners [0 ].name != "test-profile" {
1528+ t .Errorf ("Expected profile name to be 'test-profile', got '%s'" , descheduler .profileRunners [0 ].name )
1529+ }
1530+ })
1531+ }
1532+ }
0 commit comments