From e6646a40bc0799c614990c952b453e3d65869d4d Mon Sep 17 00:00:00 2001 From: Yijing Yan Date: Thu, 21 May 2026 22:50:00 +1000 Subject: [PATCH 1/3] Skip Redis client init for DBs not in database_config.json Signed-off-by: Yijing Yan --- sonic_data_client/db_client.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sonic_data_client/db_client.go b/sonic_data_client/db_client.go index 5c7a528b7..bf5d83d3b 100644 --- a/sonic_data_client/db_client.go +++ b/sonic_data_client/db_client.go @@ -546,8 +546,15 @@ func useRedisTcpClient() error { } for _, dbNamespace := range AllNamespaces { Target2RedisDb[dbNamespace] = make(map[string]*redis.Client) + configured := configuredDbSet(dbNamespace) for dbName, dbn := range spb.Target_value { if dbName != "OTHERS" { + if configured != nil { + if _, ok := configured[dbName]; !ok { + log.V(2).Infof("Skipping %s in namespace %s: not configured on this platform", dbName, dbNamespace) + continue + } + } addr, err := sdcfg.GetDbTcpAddr(dbName, dbNamespace) if err != nil { log.Warningf("Skipping %s in namespace %s: %v", dbName, dbNamespace, err) @@ -573,6 +580,24 @@ func init() { initRedisDbClients() } +// configuredDbSet returns the set of DB names defined in the device's +// SONiC database_config.json for the given namespace. +func configuredDbSet(dbNamespace string) map[string]struct{} { + dbList, err := sdcfg.GetDbList(dbNamespace) + if err != nil { + log.V(2).Infof("GetDbList failed for namespace %s: %v", dbNamespace, err) + return nil + } + if len(dbList) == 0 { + return nil + } + set := make(map[string]struct{}, len(dbList)) + for _, name := range dbList { + set[name] = struct{}{} + } + return set +} + func initRedisDbClients() { AllNamespaces, err := sdcfg.GetDbAllNamespaces() if err != nil { @@ -581,8 +606,15 @@ func initRedisDbClients() { } for _, dbNamespace := range AllNamespaces { Target2RedisDb[dbNamespace] = make(map[string]*redis.Client) + configured := configuredDbSet(dbNamespace) for dbName, dbn := range spb.Target_value { if dbName != "OTHERS" { + if configured != nil { + if _, ok := configured[dbName]; !ok { + log.V(2).Infof("Skipping %s in namespace %s: not configured on this platform", dbName, dbNamespace) + continue + } + } addr, err := sdcfg.GetDbSock(dbName, dbNamespace) if err != nil { log.Warningf("Skipping %s in namespace %s: %v", dbName, dbNamespace, err) From 6f1fa544612843cb549f91a4485d29d38ff7e1fd Mon Sep 17 00:00:00 2001 From: Yijing Yan Date: Mon, 25 May 2026 10:50:02 +1000 Subject: [PATCH 2/3] add test case to address copilot comment Signed-off-by: Yijing Yan --- sonic_data_client/client_test.go | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/sonic_data_client/client_test.go b/sonic_data_client/client_test.go index e22bb1de0..71e17c33e 100644 --- a/sonic_data_client/client_test.go +++ b/sonic_data_client/client_test.go @@ -872,6 +872,53 @@ func TestInitRedisDbClients(t *testing.T) { } }) + t.Run("SkipUnconfiguredDbWithoutGetDbSock", func(t *testing.T) { + defer saveAndResetTarget2RedisDb()() + + const skippedDb = "CHASSIS_STATE_DB" + configuredDbs := []string{"CONFIG_DB", "APPL_DB", "STATE_DB"} + getDbSockCalls := 0 + getDbSockCalledForSkipped := false + + patches := gomonkey.ApplyFunc(sdcfg.GetDbAllNamespaces, func() ([]string, error) { + return []string{ns}, nil + }) + defer patches.Reset() + + patches.ApplyFunc(sdcfg.GetDbList, func(_ string) ([]string, error) { + return configuredDbs, nil + }) + + patches.ApplyFunc(sdcfg.GetDbSock, func(dbName string, _ string) (string, error) { + getDbSockCalls++ + if dbName == skippedDb { + getDbSockCalledForSkipped = true + } + return "/var/run/redis/redis.sock", nil + }) + + initRedisDbClients() + + nsMap, ok := Target2RedisDb[ns] + if !ok { + t.Fatal("Expected namespace to exist in Target2RedisDb") + } + if _, exists := nsMap[skippedDb]; exists { + t.Errorf("%s should have been skipped because it is not configured", skippedDb) + } + if getDbSockCalledForSkipped { + t.Errorf("GetDbSock should not be called for unconfigured DB %s", skippedDb) + } + if getDbSockCalls != len(configuredDbs) { + t.Errorf("Expected GetDbSock to be called %d times, got %d", len(configuredDbs), getDbSockCalls) + } + for _, dbName := range configuredDbs { + if _, exists := nsMap[dbName]; !exists { + t.Errorf("Expected %s to be initialized", dbName) + } + } + }) + t.Run("AllDbsAvailable", func(t *testing.T) { defer saveAndResetTarget2RedisDb()() From 4c6b43de37a70b27c5f6eb8ec62012e3cee7c5fb Mon Sep 17 00:00:00 2001 From: Yijing Yan Date: Wed, 27 May 2026 09:38:52 +1000 Subject: [PATCH 3/3] add test cases Signed-off-by: Yijing Yan --- sonic_data_client/client_test.go | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/sonic_data_client/client_test.go b/sonic_data_client/client_test.go index 71e17c33e..df13d4155 100644 --- a/sonic_data_client/client_test.go +++ b/sonic_data_client/client_test.go @@ -1055,6 +1055,59 @@ func TestUseRedisTcpClient(t *testing.T) { } }) + t.Run("SkipUnconfiguredDbWithoutGetDbTcpAddr", func(t *testing.T) { + defer saveAndResetTarget2RedisDb()() + origFlag := UseRedisLocalTcpPort + UseRedisLocalTcpPort = true + defer func() { UseRedisLocalTcpPort = origFlag }() + + const skippedDb = "CHASSIS_STATE_DB" + configuredDbs := []string{"CONFIG_DB", "APPL_DB", "STATE_DB"} + getDbTcpAddrCalls := 0 + getDbTcpAddrCalledForSkipped := false + + patches := gomonkey.ApplyFunc(sdcfg.GetDbAllNamespaces, func() ([]string, error) { + return []string{ns}, nil + }) + defer patches.Reset() + + patches.ApplyFunc(sdcfg.GetDbList, func(_ string) ([]string, error) { + return configuredDbs, nil + }) + + patches.ApplyFunc(sdcfg.GetDbTcpAddr, func(dbName string, _ string) (string, error) { + getDbTcpAddrCalls++ + if dbName == skippedDb { + getDbTcpAddrCalledForSkipped = true + } + return "127.0.0.1:6379", nil + }) + + err := useRedisTcpClient() + if err != nil { + t.Fatalf("Expected no error when skipping unconfigured DB, got: %v", err) + } + + nsMap, ok := Target2RedisDb[ns] + if !ok { + t.Fatal("Expected namespace to exist in Target2RedisDb") + } + if _, exists := nsMap[skippedDb]; exists { + t.Errorf("%s should have been skipped because it is not configured", skippedDb) + } + if getDbTcpAddrCalledForSkipped { + t.Errorf("GetDbTcpAddr should not be called for unconfigured DB %s", skippedDb) + } + if getDbTcpAddrCalls != len(configuredDbs) { + t.Errorf("Expected GetDbTcpAddr to be called %d times, got %d", len(configuredDbs), getDbTcpAddrCalls) + } + for _, dbName := range configuredDbs { + if _, exists := nsMap[dbName]; !exists { + t.Errorf("Expected %s to be initialized in TCP mode", dbName) + } + } + }) + t.Run("GetDbAllNamespacesFails", func(t *testing.T) { defer saveAndResetTarget2RedisDb()() origFlag := UseRedisLocalTcpPort @@ -1076,6 +1129,19 @@ func TestUseRedisTcpClient(t *testing.T) { }) } +func TestConfiguredDbSet(t *testing.T) { + t.Run("GetDbListFailureReturnsNil", func(t *testing.T) { + patches := gomonkey.ApplyFunc(sdcfg.GetDbList, func(_ string) ([]string, error) { + return nil, fmt.Errorf("GetDbList failure") + }) + defer patches.Reset() + + if got := configuredDbSet("asic0"); got != nil { + t.Fatalf("expected nil set on GetDbList failure, got: %#v", got) + } + }) +} + // setupTestTarget2RedisDb populates Target2RedisDb with real TCP Redis clients // using the same gomonkey pattern as TestUseRedisTcpClient. func setupTestTarget2RedisDb(t *testing.T) func() {