@@ -1420,7 +1420,193 @@ func verifyAllPrometheusClientsEqual(t *testing.T, expected, fromReactor, fromPl
14201420}
14211421
14221422// TestPluginPrometheusClientAccess tests that the Prometheus client is accessible through the plugin handle
1423- func TestPluginPrometheusClientAccess (t * testing.T ) {
1423+ func TestPluginPrometheusClientAccess_Secret (t * testing.T ) {
1424+ testCases := []struct {
1425+ name string
1426+ dryRun bool
1427+ }{
1428+ {
1429+ name : "dry run disabled" ,
1430+ dryRun : false ,
1431+ },
1432+ {
1433+ name : "dry run enabled" ,
1434+ dryRun : true ,
1435+ },
1436+ }
1437+
1438+ for _ , tc := range testCases {
1439+ t .Run (tc .name , func (t * testing.T ) {
1440+ ctx := context .Background ()
1441+
1442+ initPluginRegistry ()
1443+
1444+ newInvoked := false
1445+ reactorInvoked := false
1446+ var prometheusClientFromPluginNewHandle promapi.Client
1447+ var prometheusClientFromReactor promapi.Client
1448+
1449+ fakePlugin := & fakeplugin.FakePlugin {
1450+ PluginName : "TestPluginWithPrometheusClient" ,
1451+ }
1452+
1453+ fakePlugin .AddReactor (string (frameworktypes .DescheduleExtensionPoint ), func (action fakeplugin.Action ) (handled , filter bool , err error ) {
1454+ if dAction , ok := action .(fakeplugin.DescheduleAction ); ok {
1455+ reactorInvoked = true
1456+ prometheusClientFromReactor = dAction .Handle ().PrometheusClient ()
1457+ return true , false , nil
1458+ }
1459+ return false , false , nil
1460+ })
1461+
1462+ pluginregistry .Register (
1463+ fakePlugin .PluginName ,
1464+ fakeplugin .NewPluginFncFromFakeWithReactor (fakePlugin , func (action fakeplugin.ActionImpl ) {
1465+ newInvoked = true
1466+ prometheusClientFromPluginNewHandle = action .Handle ().PrometheusClient ()
1467+ }),
1468+ & fakeplugin.FakePlugin {},
1469+ & fakeplugin.FakePluginArgs {},
1470+ fakeplugin .ValidateFakePluginArgs ,
1471+ fakeplugin .SetDefaults_FakePluginArgs ,
1472+ pluginregistry .PluginRegistry ,
1473+ )
1474+
1475+ deschedulerPolicy := & api.DeschedulerPolicy {
1476+ MetricsProviders : []api.MetricsProvider {
1477+ {
1478+ Source : api .PrometheusMetrics ,
1479+ Prometheus : newPrometheusConfig (),
1480+ },
1481+ },
1482+ Profiles : []api.DeschedulerProfile {
1483+ {
1484+ Name : "test-profile" ,
1485+ PluginConfigs : []api.PluginConfig {
1486+ {
1487+ Name : fakePlugin .PluginName ,
1488+ Args : & fakeplugin.FakePluginArgs {},
1489+ },
1490+ },
1491+ Plugins : api.Plugins {
1492+ Deschedule : api.PluginSet {
1493+ Enabled : []string {fakePlugin .PluginName },
1494+ },
1495+ },
1496+ },
1497+ },
1498+ }
1499+
1500+ node1 := test .BuildTestNode ("node1" , 1000 , 2000 , 9 , nil )
1501+ node2 := test .BuildTestNode ("node2" , 1000 , 2000 , 9 , nil )
1502+
1503+ _ , descheduler , runFnc , fakeClient := initDescheduler (t , ctx , initFeatureGates (), deschedulerPolicy , nil , tc .dryRun , node1 , node2 )
1504+
1505+ // Test cycles with different Prometheus client values
1506+ cycles := []struct {
1507+ name string
1508+ operation func () error
1509+ skipWaiting bool
1510+ client promapi.Client
1511+ token string
1512+ }{
1513+ {
1514+ name : "no secret initially" ,
1515+ operation : func () error { return nil },
1516+ skipWaiting : true ,
1517+ client : nil ,
1518+ token : "" ,
1519+ },
1520+ {
1521+ name : "add secret" ,
1522+ operation : func () error {
1523+ secret := newPrometheusAuthSecret (withToken ("token-1" ))
1524+ _ , err := fakeClient .CoreV1 ().Secrets (secret .Namespace ).Create (ctx , secret , metav1.CreateOptions {})
1525+ return err
1526+ },
1527+ client : & mockPrometheusClient {name : "new-init-client" },
1528+ token : "token-1" ,
1529+ },
1530+ {
1531+ name : "update secret" ,
1532+ operation : func () error {
1533+ secret := newPrometheusAuthSecret (withToken ("token-2" ))
1534+ _ , err := fakeClient .CoreV1 ().Secrets (secret .Namespace ).Update (ctx , secret , metav1.UpdateOptions {})
1535+ return err
1536+ },
1537+ client : & mockPrometheusClient {name : "new-client" },
1538+ token : "token-2" ,
1539+ },
1540+ {
1541+ name : "delete secret" ,
1542+ operation : func () error {
1543+ secret := newPrometheusAuthSecret (withToken ("token-3" ))
1544+ return fakeClient .CoreV1 ().Secrets (secret .Namespace ).Delete (ctx , secret .Name , metav1.DeleteOptions {})
1545+ },
1546+ client : nil ,
1547+ token : "" ,
1548+ },
1549+ }
1550+
1551+ for i , cycle := range cycles {
1552+ t .Logf ("Cycle %d: %s" , i + 1 , cycle .name )
1553+
1554+ // Set the descheduler's Prometheus client
1555+ t .Logf ("Setting descheduler.promClientCtrl.promClient from %v to %v" , descheduler .promClientCtrl .promClient , cycle .client )
1556+ descheduler .promClientCtrl .createPrometheusClient = func (url , token string ) (promapi.Client , * http.Transport , error ) {
1557+ if token != cycle .token {
1558+ t .Fatalf ("Expected token to be %q, got %q" , cycle .token , token )
1559+ }
1560+ if url != prometheusURL {
1561+ t .Fatalf ("Expected url to be %q, got %q" , prometheusURL , url )
1562+ }
1563+ return cycle .client , & http.Transport {}, nil
1564+ }
1565+
1566+ if err := cycle .operation (); err != nil {
1567+ t .Fatalf ("operation failed: %v" , err )
1568+ }
1569+
1570+ if ! cycle .skipWaiting {
1571+ err := wait .PollUntilContextTimeout (ctx , 50 * time .Millisecond , 200 * time .Millisecond , true , func (ctx context.Context ) (bool , error ) {
1572+ currentPromClient := descheduler .promClientCtrl .prometheusClient ()
1573+ if currentPromClient != cycle .client {
1574+ t .Logf ("Waiting for prometheus client to be set to %v, got %v instead, waiting" , cycle .client , currentPromClient )
1575+ return false , nil
1576+ }
1577+ return true , nil
1578+ })
1579+ if err != nil {
1580+ t .Fatalf ("Timed out waiting for expected conditions: %v" , err )
1581+ }
1582+ }
1583+
1584+ newInvoked = false
1585+ reactorInvoked = false
1586+ prometheusClientFromPluginNewHandle = nil
1587+ prometheusClientFromReactor = nil
1588+
1589+ if err := runFnc (ctx ); err != nil {
1590+ t .Fatalf ("Unexpected error during running a descheduling cycle: %v" , err )
1591+ }
1592+
1593+ t .Logf ("After cycle %d: prometheusClientFromReactor=%v, descheduler.promClientCtrl.promClient=%v" , i + 1 , prometheusClientFromReactor , descheduler .promClientCtrl .promClient )
1594+
1595+ if ! newInvoked {
1596+ t .Fatalf ("Expected plugin new to be invoked during cycle %d" , i + 1 )
1597+ }
1598+
1599+ if ! reactorInvoked {
1600+ t .Fatalf ("Expected deschedule reactor to be invoked during cycle %d" , i + 1 )
1601+ }
1602+
1603+ verifyAllPrometheusClientsEqual (t , cycle .client , prometheusClientFromReactor , prometheusClientFromPluginNewHandle , descheduler .promClientCtrl .promClient )
1604+ }
1605+ })
1606+ }
1607+ }
1608+
1609+ func TestPluginPrometheusClientAccess_InCluster (t * testing.T ) {
14241610 testCases := []struct {
14251611 name string
14261612 dryRun bool
0 commit comments