mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-23 11:01:49 +01:00
Add cache test for admins (#31265)
Add a test to probe the cache similar to the email test func. ![image](https://github.com/go-gitea/gitea/assets/24977596/700e2733-586d-4091-900f-f5f71e6e94bf) ![image](https://github.com/go-gitea/gitea/assets/24977596/2a953802-18fc-4e81-a37d-24ebe1297365) ![image](https://github.com/go-gitea/gitea/assets/24977596/e00d62ad-bb60-41cc-9138-09993daee156) --------- Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: silverwind <me@silverwind.io> (cherry picked from commit 363c1235987793dffa5cc851aaae585eb81f091e) Conflicts: options/locale/locale_en-US.ini templates/admin/self_check.tmpl trivial context conflict
This commit is contained in:
parent
40cd885c11
commit
77da92f42a
8 changed files with 93 additions and 2 deletions
31
modules/cache/cache.go
vendored
31
modules/cache/cache.go
vendored
|
@ -40,6 +40,37 @@ func Init() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
testCacheKey = "DefaultCache.TestKey"
|
||||||
|
SlowCacheThreshold = 100 * time.Microsecond
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test() (time.Duration, error) {
|
||||||
|
if defaultCache == nil {
|
||||||
|
return 0, fmt.Errorf("default cache not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
testData := fmt.Sprintf("%x", make([]byte, 500))
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
if err := defaultCache.Delete(testCacheKey); err != nil {
|
||||||
|
return 0, fmt.Errorf("expect cache to delete data based on key if exist but got: %w", err)
|
||||||
|
}
|
||||||
|
if err := defaultCache.Put(testCacheKey, testData, 10); err != nil {
|
||||||
|
return 0, fmt.Errorf("expect cache to store data but got: %w", err)
|
||||||
|
}
|
||||||
|
testVal, hit := defaultCache.Get(testCacheKey)
|
||||||
|
if !hit {
|
||||||
|
return 0, fmt.Errorf("expect cache hit but got none")
|
||||||
|
}
|
||||||
|
if testVal != testData {
|
||||||
|
return 0, fmt.Errorf("expect cache to return same value as stored but got other")
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Since(start), nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetCache returns the currently configured cache
|
// GetCache returns the currently configured cache
|
||||||
func GetCache() mc.Cache {
|
func GetCache() mc.Cache {
|
||||||
return conn
|
return conn
|
||||||
|
|
12
modules/cache/cache_test.go
vendored
12
modules/cache/cache_test.go
vendored
|
@ -34,6 +34,18 @@ func TestNewContext(t *testing.T) {
|
||||||
assert.Nil(t, con)
|
assert.Nil(t, con)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTest(t *testing.T) {
|
||||||
|
defaultCache = nil
|
||||||
|
_, err := Test()
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
createTestCache()
|
||||||
|
elapsed, err := Test()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// mem cache should take from 300ns up to 1ms on modern hardware ...
|
||||||
|
assert.Less(t, elapsed, SlowCacheThreshold)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetCache(t *testing.T) {
|
func TestGetCache(t *testing.T) {
|
||||||
createTestCache()
|
createTestCache()
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ remove_all = Remove all
|
||||||
remove_label_str = Remove item "%s"
|
remove_label_str = Remove item "%s"
|
||||||
edit = Edit
|
edit = Edit
|
||||||
view = View
|
view = View
|
||||||
|
test = Test
|
||||||
|
|
||||||
enabled = Enabled
|
enabled = Enabled
|
||||||
disabled = Disabled
|
disabled = Disabled
|
||||||
|
@ -3317,6 +3318,11 @@ config.cache_interval = Cache interval
|
||||||
config.cache_conn = Cache connection
|
config.cache_conn = Cache connection
|
||||||
config.cache_item_ttl = Cache item TTL
|
config.cache_item_ttl = Cache item TTL
|
||||||
|
|
||||||
|
config.cache_test = Test Cache
|
||||||
|
config.cache_test_failed = Failed to probe the cache: %v.
|
||||||
|
config.cache_test_slow = Cache test successful, but response is slow: %s.
|
||||||
|
config.cache_test_succeeded = Cache test successful, got a response in %s.
|
||||||
|
|
||||||
config.session_config = Session configuration
|
config.session_config = Session configuration
|
||||||
config.session_provider = Session provider
|
config.session_provider = Session provider
|
||||||
config.provider_config = Provider config
|
config.provider_config = Provider config
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
@ -211,6 +212,14 @@ func SelfCheck(ctx *context.Context) {
|
||||||
|
|
||||||
ctx.Data["DatabaseCheckHasProblems"] = hasProblem
|
ctx.Data["DatabaseCheckHasProblems"] = hasProblem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed, err := cache.Test()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Data["CacheError"] = err
|
||||||
|
} else if elapsed > cache.SlowCacheThreshold {
|
||||||
|
ctx.Data["CacheSlow"] = fmt.Sprint(elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplSelfCheck)
|
ctx.HTML(http.StatusOK, tplSelfCheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
system_model "code.gitea.io/gitea/models/system"
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
@ -42,6 +43,22 @@ func SendTestMail(ctx *context.Context) {
|
||||||
ctx.Redirect(setting.AppSubURL + "/admin/config")
|
ctx.Redirect(setting.AppSubURL + "/admin/config")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestCache test the cache settings
|
||||||
|
func TestCache(ctx *context.Context) {
|
||||||
|
elapsed, err := cache.Test()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Flash.Error(ctx.Tr("admin.config.cache_test_failed", err))
|
||||||
|
} else {
|
||||||
|
if elapsed > cache.SlowCacheThreshold {
|
||||||
|
ctx.Flash.Warning(ctx.Tr("admin.config.cache_test_slow", elapsed))
|
||||||
|
} else {
|
||||||
|
ctx.Flash.Info(ctx.Tr("admin.config.cache_test_succeeded", elapsed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/admin/config")
|
||||||
|
}
|
||||||
|
|
||||||
func shadowPasswordKV(cfgItem, splitter string) string {
|
func shadowPasswordKV(cfgItem, splitter string) string {
|
||||||
fields := strings.Split(cfgItem, splitter)
|
fields := strings.Split(cfgItem, splitter)
|
||||||
for i := 0; i < len(fields); i++ {
|
for i := 0; i < len(fields); i++ {
|
||||||
|
|
|
@ -665,6 +665,7 @@ func registerRoutes(m *web.Route) {
|
||||||
m.Get("", admin.Config)
|
m.Get("", admin.Config)
|
||||||
m.Post("", admin.ChangeConfig)
|
m.Post("", admin.ChangeConfig)
|
||||||
m.Post("/test_mail", admin.SendTestMail)
|
m.Post("/test_mail", admin.SendTestMail)
|
||||||
|
m.Post("/test_cache", admin.TestCache)
|
||||||
m.Get("/settings", admin.ConfigSettings)
|
m.Get("/settings", admin.ConfigSettings)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -233,8 +233,8 @@
|
||||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt>
|
<dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt>
|
||||||
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd>
|
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<dt class="tw-py-1">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
|
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
|
||||||
<dd>
|
<dd class="tw-py-0">
|
||||||
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
|
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
<div class="ui tiny input">
|
<div class="ui tiny input">
|
||||||
|
@ -264,6 +264,14 @@
|
||||||
<dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt>
|
<dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt>
|
||||||
<dd><code>{{.CacheItemTTL}}</code></dd>
|
<dd><code>{{.CacheItemTTL}}</code></dd>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
<div class="divider"></div>
|
||||||
|
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.cache_test"}}</dt>
|
||||||
|
<dd class="tw-py-0">
|
||||||
|
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_cache" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<button class="ui tiny primary button">{{ctx.Locale.Tr "test"}}</button>
|
||||||
|
</form>
|
||||||
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div>
|
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{if .CacheError}}
|
||||||
|
<div class="ui red message">{{ctx.Locale.Tr "admin.config.cache_test_failed" .CacheError}}</div>
|
||||||
|
{{end}}
|
||||||
|
{{if .CacheSlow}}
|
||||||
|
<div class="ui warning message">{{ctx.Locale.Tr "admin.config.cache_test_slow" .CacheSlow}}</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue