mirror of
https://github.com/go-gitea/gitea
synced 2024-12-22 06:27:50 +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>
This commit is contained in:
parent
4b6eb46e69
commit
363c123598
32
modules/cache/cache.go
vendored
32
modules/cache/cache.go
vendored
@ -4,6 +4,7 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@ -35,6 +36,37 @@ func Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
func GetCache() StringCache {
|
||||
return defaultCache
|
||||
|
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
createTestCache()
|
||||
|
||||
|
@ -93,6 +93,7 @@ remove_all = Remove All
|
||||
remove_label_str = Remove item "%s"
|
||||
edit = Edit
|
||||
view = View
|
||||
test = Test
|
||||
|
||||
enabled = Enabled
|
||||
disabled = Disabled
|
||||
@ -3225,6 +3226,10 @@ config.cache_adapter = Cache Adapter
|
||||
config.cache_interval = Cache Interval
|
||||
config.cache_conn = Cache Connection
|
||||
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_provider = Session Provider
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
activities_model "code.gitea.io/gitea/models/activities"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
@ -222,6 +223,14 @@ func SelfCheck(ctx *context.Context) {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -42,6 +43,22 @@ func SendTestMail(ctx *context.Context) {
|
||||
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 {
|
||||
fields := strings.Split(cfgItem, splitter)
|
||||
for i := 0; i < len(fields); i++ {
|
||||
|
@ -692,6 +692,7 @@ func registerRoutes(m *web.Route) {
|
||||
m.Get("", admin.Config)
|
||||
m.Post("", admin.ChangeConfig)
|
||||
m.Post("/test_mail", admin.SendTestMail)
|
||||
m.Post("/test_cache", admin.TestCache)
|
||||
m.Get("/settings", admin.ConfigSettings)
|
||||
})
|
||||
|
||||
|
@ -229,8 +229,8 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt>
|
||||
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd>
|
||||
<div class="divider"></div>
|
||||
<dt class="tw-py-1">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
|
||||
<dd>
|
||||
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
|
||||
<dd class="tw-py-0">
|
||||
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="ui tiny input">
|
||||
@ -260,6 +260,14 @@
|
||||
<dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt>
|
||||
<dd><code>{{.CacheItemTTL}}</code></dd>
|
||||
{{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>
|
||||
</div>
|
||||
|
||||
|
@ -17,32 +17,40 @@
|
||||
<div class="ui attached segment tw-hidden self-check-problem" id="self-check-by-frontend"></div>
|
||||
|
||||
{{if .DatabaseCheckHasProblems}}
|
||||
<div class="ui attached segment self-check-problem">
|
||||
{{if .DatabaseType.IsMySQL}}
|
||||
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mysql"}}</div>
|
||||
{{else if .DatabaseType.IsMSSQL}}
|
||||
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mssql"}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckCollationMismatch}}
|
||||
<div class="ui red message">{{ctx.Locale.Tr "admin.self_check.database_collation_mismatch" .DatabaseCheckResult.ExpectedCollation}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckCollationCaseInsensitive}}
|
||||
<div class="ui warning message">{{ctx.Locale.Tr "admin.self_check.database_collation_case_insensitive" .DatabaseCheckResult.DatabaseCollation}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckInconsistentCollationColumns}}
|
||||
<div class="ui red message">
|
||||
<details>
|
||||
<summary>{{ctx.Locale.Tr "admin.self_check.database_inconsistent_collation_columns" .DatabaseCheckResult.DatabaseCollation}}</summary>
|
||||
<ul class="tw-w-full">
|
||||
{{range .DatabaseCheckInconsistentCollationColumns}}
|
||||
<li>{{.}}</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="ui attached segment self-check-problem">
|
||||
{{if .DatabaseType.IsMySQL}}
|
||||
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mysql"}}</div>
|
||||
{{else if .DatabaseType.IsMSSQL}}
|
||||
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.database_fix_mssql"}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckCollationMismatch}}
|
||||
<div class="ui red message">{{ctx.Locale.Tr "admin.self_check.database_collation_mismatch" .DatabaseCheckResult.ExpectedCollation}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckCollationCaseInsensitive}}
|
||||
<div class="ui warning message">{{ctx.Locale.Tr "admin.self_check.database_collation_case_insensitive" .DatabaseCheckResult.DatabaseCollation}}</div>
|
||||
{{end}}
|
||||
{{if .DatabaseCheckInconsistentCollationColumns}}
|
||||
<div class="ui red message">
|
||||
<details>
|
||||
<summary>{{ctx.Locale.Tr "admin.self_check.database_inconsistent_collation_columns" .DatabaseCheckResult.DatabaseCollation}}</summary>
|
||||
<ul class="tw-w-full">
|
||||
{{range .DatabaseCheckInconsistentCollationColumns}}
|
||||
<li>{{.}}</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{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}}
|
||||
|
||||
{{/* only shown when there is no visible "self-check-problem" */}}
|
||||
<div class="ui attached segment tw-hidden self-check-no-problem">
|
||||
{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}
|
||||
|
Loading…
Reference in New Issue
Block a user