mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-30 20:37:52 +00:00
feat(setting): add shared [redis] section as default for redis-backed subsystems (#38550)
Adds a shared `[redis]` config section with a single `CONN_STR` key that acts as the default Redis connection for every redis-backed subsystem whose own connection string is empty: `[cache].HOST`, `[session].PROVIDER_CONFIG`, `[queue].CONN_STR` and `[global_lock].SERVICE_CONN_STR`. Precedence: per-subsystem value > shared `[redis].CONN_STR` > existing built-in defaults. Fully backward compatible: when `[redis]` is not set, every code path behaves exactly as before. Motivation: today an admin with one Redis instance has to repeat the same connection string in up to four places (five once WebSocket lands). Requested by @wxiaoguang in [this review discussion](https://github.com/go-gitea/gitea/pull/36965#discussion_r3613306976) as a prerequisite for #36965. This follows the pattern used by GitLab and Mastodon: one global Redis definition, per-subsystem overrides fall back to it. Since #12385 all identical connection strings already share one client via `nosql.Manager`, so pointing all subsystems at `[redis].CONN_STR` naturally converges onto a single shared connection pool. Covered by table-driven unit tests per subsystem (fallback applies, own value wins, absent `[redis]` = unchanged behavior). A config-cheat-sheet update for gitea/docs will follow once this is merged. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
This commit is contained in:
@@ -1603,6 +1603,19 @@ LEVEL = Info
|
||||
;; If you'd like to enable it, you can set it to a value between 0 and 2.
|
||||
;TYPE_BLEVE_MAX_FUZZINESS = 0
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[redis]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Shared redis connection, used as the default for every redis-backed subsystem
|
||||
;; (cache, session, queue, global lock, etc.) whose own connection string is left empty.
|
||||
;; A per-subsystem connection value always takes precedence over this shared default.
|
||||
;; When left empty, each subsystem keeps its previous behavior (no shared default).
|
||||
;; e.g. `redis://127.0.0.1:6379/0` (or `redis+cluster://127.0.0.1:6379/0` for a Redis cluster)
|
||||
;CONN_STR =
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[queue]
|
||||
@@ -1628,10 +1641,10 @@ LEVEL = Info
|
||||
;; Batch size to send for batched queues
|
||||
;BATCH_LENGTH = 20
|
||||
;;
|
||||
;; Connection string for redis queues this will store the redis (or Redis cluster) connection string.
|
||||
;; When `TYPE` is `persistable-channel`, this provides a directory for the underlying leveldb
|
||||
;; or additional options of the form `leveldb://path/to/db?option=value&....`, and will override `DATADIR`.
|
||||
;CONN_STR = "redis://127.0.0.1:6379/0"
|
||||
;; When `TYPE` is `redis` and this is left empty, it falls back to the shared [redis] CONN_STR.
|
||||
;CONN_STR =
|
||||
;;
|
||||
;; Provides the suffix of the default redis/disk queue name - specific queues can be overridden within in their [queue.name] sections.
|
||||
;QUEUE_NAME = "_queue"
|
||||
@@ -1929,7 +1942,7 @@ LEVEL = Info
|
||||
;INTERVAL = 60
|
||||
;;
|
||||
;; For "redis" and "memcache", connection host address
|
||||
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
|
||||
;; redis: default to shared [redis] CONN_STR
|
||||
;; memcache: `127.0.0.1:11211`
|
||||
;; twoqueue: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000`
|
||||
;HOST =
|
||||
@@ -1965,10 +1978,10 @@ LEVEL = Info
|
||||
;;
|
||||
;; Provider config options
|
||||
;; memory: doesn't have any config yet
|
||||
;; file: session file path, e.g. `data/sessions`
|
||||
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
|
||||
;; file: session file path, e.g. `data/sessions`, relative paths will be made absolute against _`AppWorkPath`_.
|
||||
;; redis: default to [redis] CONN_STR
|
||||
;; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
|
||||
;PROVIDER_CONFIG = data/sessions ; Relative paths will be made absolute against _`AppWorkPath`_.
|
||||
;PROVIDER_CONFIG =
|
||||
;;
|
||||
;; Session cookie name
|
||||
;COOKIE_NAME = i_like_gitea
|
||||
@@ -3027,5 +3040,5 @@ LEVEL = Info
|
||||
;[global_lock]
|
||||
;; Lock service type, could be memory or redis
|
||||
;SERVICE_TYPE = memory
|
||||
;; Ignored for the "memory" type. For "redis" use something like `redis://127.0.0.1:6379/0`
|
||||
;; Ignored for the "memory" type. For "redis", default to [redis] CONN_STR.
|
||||
;SERVICE_CONN_STR =
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.dev/modules/log"
|
||||
@@ -14,7 +13,7 @@ import (
|
||||
type Cache struct {
|
||||
Adapter string
|
||||
Interval int
|
||||
Conn string
|
||||
Conn string `ini:"-"`
|
||||
TTL time.Duration `ini:"ITEM_TTL"`
|
||||
}
|
||||
|
||||
@@ -53,13 +52,12 @@ func loadCacheFrom(rootCfg ConfigProvider) {
|
||||
CacheService.Adapter = sec.Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache", "twoqueue"})
|
||||
switch CacheService.Adapter {
|
||||
case "memory":
|
||||
case "redis", "memcache":
|
||||
CacheService.Conn = strings.Trim(sec.Key("HOST").String(), "\" ")
|
||||
case "memcache":
|
||||
CacheService.Conn = sec.Key("HOST").String()
|
||||
case "redis":
|
||||
CacheService.Conn = sec.Key("HOST").MustString(Redis.ConnStr)
|
||||
case "twoqueue":
|
||||
CacheService.Conn = strings.TrimSpace(sec.Key("HOST").String())
|
||||
if CacheService.Conn == "" {
|
||||
CacheService.Conn = "50000"
|
||||
}
|
||||
CacheService.Conn = sec.Key("HOST").MustString("50000")
|
||||
default:
|
||||
log.Fatal("Unknown cache adapter: %s", CacheService.Adapter)
|
||||
}
|
||||
|
||||
71
modules/setting/cache_test.go
Normal file
71
modules/setting/cache_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCacheRedisSharedConnFallback(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
iniStr string
|
||||
wantConn string
|
||||
}{
|
||||
{
|
||||
name: "redis adapter with empty HOST falls back to shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[cache]
|
||||
ADAPTER = redis
|
||||
`,
|
||||
wantConn: "redis://127.0.0.1:6379/0",
|
||||
},
|
||||
{
|
||||
name: "cache HOST wins over shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[cache]
|
||||
ADAPTER = redis
|
||||
HOST = redis://10.0.0.1:6379/1
|
||||
`,
|
||||
wantConn: "redis://10.0.0.1:6379/1",
|
||||
},
|
||||
{
|
||||
name: "no shared [redis] keeps previous behavior (empty conn)",
|
||||
iniStr: `
|
||||
[cache]
|
||||
ADAPTER = redis
|
||||
`,
|
||||
wantConn: "",
|
||||
},
|
||||
{
|
||||
name: "memcache adapter is never affected by shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[cache]
|
||||
ADAPTER = memcache
|
||||
`,
|
||||
wantConn: "",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
cfg, err := NewConfigProviderFromData(tt.iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadCacheFrom(cfg)
|
||||
assert.Equal(t, tt.wantConn, CacheService.Conn)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func loadGlobalLockFrom(rootCfg ConfigProvider) {
|
||||
switch GlobalLock.ServiceType {
|
||||
case "memory":
|
||||
case "redis":
|
||||
connStr := sec.Key("SERVICE_CONN_STR").String()
|
||||
connStr := sec.Key("SERVICE_CONN_STR").MustString(Redis.ConnStr)
|
||||
if connStr == "" {
|
||||
log.Fatal("SERVICE_CONN_STR is empty for redis")
|
||||
}
|
||||
@@ -6,20 +6,24 @@ package setting
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLoadGlobalLockConfig(t *testing.T) {
|
||||
t.Run("DefaultGlobalLockConfig", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
iniStr := ``
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadGlobalLockFrom(cfg)
|
||||
assert.Equal(t, "memory", GlobalLock.ServiceType)
|
||||
})
|
||||
|
||||
t.Run("RedisGlobalLockConfig", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
iniStr := `
|
||||
[global_lock]
|
||||
SERVICE_TYPE = redis
|
||||
@@ -27,9 +31,44 @@ SERVICE_CONN_STR = addrs=127.0.0.1:6379 db=0
|
||||
`
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadGlobalLockFrom(cfg)
|
||||
assert.Equal(t, "redis", GlobalLock.ServiceType)
|
||||
assert.Equal(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr)
|
||||
})
|
||||
|
||||
t.Run("RedisGlobalLockFallsBackToSharedRedis", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
iniStr := `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[global_lock]
|
||||
SERVICE_TYPE = redis
|
||||
`
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadGlobalLockFrom(cfg)
|
||||
assert.Equal(t, "redis", GlobalLock.ServiceType)
|
||||
assert.Equal(t, "redis://127.0.0.1:6379/0", GlobalLock.ServiceConnStr)
|
||||
})
|
||||
|
||||
t.Run("RedisGlobalLockOwnConnWinsOverSharedRedis", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
iniStr := `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[global_lock]
|
||||
SERVICE_TYPE = redis
|
||||
SERVICE_CONN_STR = redis://10.0.0.1:6379/1
|
||||
`
|
||||
cfg, err := NewConfigProviderFromData(iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadGlobalLockFrom(cfg)
|
||||
assert.Equal(t, "redis", GlobalLock.ServiceType)
|
||||
assert.Equal(t, "redis://10.0.0.1:6379/1", GlobalLock.ServiceConnStr)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,6 +21,10 @@ var (
|
||||
// AppWorkPath is the "working directory" of Gitea. It maps to the: WORK_PATH in app.ini, "--work-path" flag, environment variable GITEA_WORK_DIR.
|
||||
// If that is not set it is the default set here by the linker or failing that the directory of AppPath.
|
||||
// It is used as the base path for several other paths.
|
||||
// Do remember:
|
||||
// * Work path might not be the POSIX current working directory or the Gitea's binary directory, Gitea binary is not FHS-compliant
|
||||
// * Work path sometimes is not writable (e.g.: /usr/local/bin) or not persistent (https://github.com/go-gitea/gitea/pull/35851)
|
||||
// * Work path, custom path and data path, some of them are the same sometimes (e.g.: docker image, some downstream packages, some manual installations)
|
||||
AppWorkPath string
|
||||
CustomPath string // Custom directory path. Env: GITEA_CUSTOM
|
||||
CustomConf string
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"gitea.dev/modules/json"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/util"
|
||||
)
|
||||
|
||||
// QueueSettings represent the settings for a queue from the ini
|
||||
@@ -77,8 +78,10 @@ func GetQueueSettings(rootCfg ConfigProvider, name string) (QueueSettings, error
|
||||
}
|
||||
cfg.Datadir = filepath.ToSlash(cfg.Datadir)
|
||||
|
||||
// redis fallback order: [queue]/[queue.name] CONN_STR (already merged above) wins,
|
||||
// then the shared [redis] conn, then the built-in localhost default for compatibility
|
||||
if cfg.Type == "redis" && cfg.ConnStr == "" {
|
||||
cfg.ConnStr = "redis://127.0.0.1:6379/0"
|
||||
cfg.ConnStr = util.IfZero(Redis.ConnStr, "redis://127.0.0.1:6379/0")
|
||||
}
|
||||
|
||||
if cfg.Length <= 0 {
|
||||
|
||||
92
modules/setting/queue_test.go
Normal file
92
modules/setting/queue_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestQueueRedisSharedConnFallback(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
iniStr string
|
||||
queueName string
|
||||
wantConn string
|
||||
}{
|
||||
{
|
||||
name: "redis queue with empty CONN_STR falls back to shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[queue]
|
||||
TYPE = redis
|
||||
`,
|
||||
queueName: "test",
|
||||
wantConn: "redis://127.0.0.1:6379/0",
|
||||
},
|
||||
{
|
||||
name: "base [queue] CONN_STR wins over shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[queue]
|
||||
TYPE = redis
|
||||
CONN_STR = redis://10.0.0.1:6379/1
|
||||
`,
|
||||
queueName: "test",
|
||||
wantConn: "redis://10.0.0.1:6379/1",
|
||||
},
|
||||
{
|
||||
name: "per-queue CONN_STR wins over shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[queue]
|
||||
TYPE = redis
|
||||
[queue.test]
|
||||
CONN_STR = redis://10.0.0.1:6379/2
|
||||
`,
|
||||
queueName: "test",
|
||||
wantConn: "redis://10.0.0.1:6379/2",
|
||||
},
|
||||
{
|
||||
name: "other queues still fall back to shared [redis] when only one is overridden",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[queue]
|
||||
TYPE = redis
|
||||
[queue.test]
|
||||
CONN_STR = redis://10.0.0.1:6379/2
|
||||
`,
|
||||
queueName: "other",
|
||||
wantConn: "redis://127.0.0.1:6379/0",
|
||||
},
|
||||
{
|
||||
name: "no shared [redis] keeps previous behavior (built-in localhost default)",
|
||||
iniStr: `
|
||||
[queue]
|
||||
TYPE = redis
|
||||
`,
|
||||
queueName: "test",
|
||||
wantConn: "redis://127.0.0.1:6379/0",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
cfg, err := NewConfigProviderFromData(tt.iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
q, err := GetQueueSettings(cfg, tt.queueName)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantConn, q.ConnStr)
|
||||
})
|
||||
}
|
||||
}
|
||||
18
modules/setting/redis.go
Normal file
18
modules/setting/redis.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
type RedisType struct {
|
||||
ConnStr string
|
||||
}
|
||||
|
||||
// Redis represents the shared redis configuration. Its connection string is used
|
||||
// as the default for every redis-backed subsystem (cache, session, queue, global
|
||||
// lock) whose own connection string is empty. A per-subsystem value always wins.
|
||||
var Redis *RedisType
|
||||
|
||||
func loadRedisFrom(rootCfg ConfigProvider) {
|
||||
Redis = &RedisType{} // make sure the Redis config is correctly loaded before it is accessed by other subsystems
|
||||
Redis.ConnStr = rootCfg.Section("redis").Key("CONN_STR").String()
|
||||
}
|
||||
@@ -42,13 +42,23 @@ var SessionConfig = struct {
|
||||
|
||||
func loadSessionFrom(rootCfg ConfigProvider) {
|
||||
sec := rootCfg.Section("session")
|
||||
SessionConfig.Provider = sec.Key("PROVIDER").In("memory",
|
||||
[]string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "db"})
|
||||
SessionConfig.ProviderConfig = strings.Trim(sec.Key("PROVIDER_CONFIG").MustString(filepath.Join(AppDataPath, "sessions")), "\" ")
|
||||
if SessionConfig.Provider == "file" && !filepath.IsAbs(SessionConfig.ProviderConfig) {
|
||||
SessionConfig.ProviderConfig = filepath.Join(AppWorkPath, SessionConfig.ProviderConfig)
|
||||
SessionConfig.Provider = sec.Key("PROVIDER").In("memory", []string{"memory", "file", "redis", "mysql", "postgres", "couchbase", "memcache", "db"})
|
||||
|
||||
switch SessionConfig.Provider {
|
||||
case "redis":
|
||||
SessionConfig.ProviderConfig = sec.Key("PROVIDER_CONFIG").MustString(Redis.ConnStr)
|
||||
case "file":
|
||||
SessionConfig.ProviderConfig = sec.Key("PROVIDER_CONFIG").MustString(filepath.Join(AppDataPath, "sessions"))
|
||||
if !filepath.IsAbs(SessionConfig.ProviderConfig) {
|
||||
// Although the "data path" should be used as Gitea's "data" base directory (work path sometimes is not writable),
|
||||
// document says the relative session path is based on the "work path", so keep the behavior
|
||||
SessionConfig.ProviderConfig = filepath.Join(AppWorkPath, SessionConfig.ProviderConfig)
|
||||
}
|
||||
checkOverlappedPath("[session].PROVIDER_CONFIG", SessionConfig.ProviderConfig)
|
||||
default:
|
||||
SessionConfig.ProviderConfig = sec.Key("PROVIDER_CONFIG").String()
|
||||
}
|
||||
|
||||
SessionConfig.CookieName = sec.Key("COOKIE_NAME").MustString("i_like_gitea")
|
||||
// HINT: INSTALL-PAGE-COOKIE-INIT: the cookie system is not properly initialized on the Install page, so there is no CookiePath
|
||||
SessionConfig.CookiePath = util.IfZero(AppSubURL, "/")
|
||||
|
||||
79
modules/setting/session_test.go
Normal file
79
modules/setting/session_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package setting
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSessionRedisSharedConnFallback(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
iniStr string
|
||||
wantContain string
|
||||
wantMissing string
|
||||
}{
|
||||
{
|
||||
name: "redis provider with empty PROVIDER_CONFIG falls back to shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[session]
|
||||
PROVIDER = redis
|
||||
`,
|
||||
wantContain: "redis://127.0.0.1:6379/0",
|
||||
},
|
||||
{
|
||||
name: "session PROVIDER_CONFIG wins over shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[session]
|
||||
PROVIDER = redis
|
||||
PROVIDER_CONFIG = redis://10.0.0.1:6379/1
|
||||
`,
|
||||
wantContain: "redis://10.0.0.1:6379/1",
|
||||
wantMissing: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
name: "no shared [redis]",
|
||||
iniStr: `
|
||||
[session]
|
||||
PROVIDER = redis
|
||||
`,
|
||||
wantContain: "",
|
||||
wantMissing: "redis://",
|
||||
},
|
||||
{
|
||||
name: "file provider default path is untouched by shared [redis]",
|
||||
iniStr: `
|
||||
[redis]
|
||||
CONN_STR = redis://127.0.0.1:6379/0
|
||||
[session]
|
||||
PROVIDER = file
|
||||
`,
|
||||
wantContain: "sessions",
|
||||
wantMissing: "redis://",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defer test.MockVariableValue(&Redis)()
|
||||
cfg, err := NewConfigProviderFromData(tt.iniStr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
loadRedisFrom(cfg)
|
||||
loadSessionFrom(cfg)
|
||||
// ProviderConfig is shadowed into a JSON blob at the end of loadSessionFrom
|
||||
assert.Contains(t, SessionConfig.ProviderConfig, tt.wantContain)
|
||||
if tt.wantMissing != "" {
|
||||
assert.NotContains(t, SessionConfig.ProviderConfig, tt.wantMissing)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -156,6 +156,7 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error {
|
||||
loadGitFrom(cfg)
|
||||
loadMirrorFrom(cfg)
|
||||
loadMarkupFrom(cfg)
|
||||
loadRedisFrom(cfg)
|
||||
loadGlobalLockFrom(cfg)
|
||||
loadOtherFrom(cfg)
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user