Merge pull request '[GITEA] Show manual cron run's last time' (#1167) from Gusted/forgejo:backport-1087 into v1.20/forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1167
This commit is contained in:
Gusted 2023-07-31 20:29:47 +00:00
commit d21b0026c7
3 changed files with 66 additions and 0 deletions

View file

@ -96,6 +96,12 @@ func ListTasks() TaskTable {
next = e.Next
prev = e.Prev
}
// If the manual run is after the cron run, use that instead.
if prev.Before(task.LastRun) {
prev = task.LastRun
}
task.lock.Lock()
tTable = append(tTable, &TaskTableRow{
Name: task.Name,

View file

@ -8,6 +8,7 @@ import (
"fmt"
"reflect"
"sync"
"time"
"code.gitea.io/gitea/models/db"
system_model "code.gitea.io/gitea/models/system"
@ -36,6 +37,8 @@ type Task struct {
LastMessage string
LastDoer string
ExecTimes int64
// This stores the time of the last manual run of this task.
LastRun time.Time
}
// DoRunAtStart returns if this task should run at the start
@ -87,6 +90,12 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
}
}()
graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) {
// Store the time of this run, before the function is executed, so it
// matches the behavior of what the cron library does.
t.lock.Lock()
t.LastRun = time.Now()
t.lock.Unlock()
pm := process.GetManager()
doerName := ""
if doer != nil && doer.ID != -1 {

View file

@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"testing"
"time"
asymkey_model "code.gitea.io/gitea/models/asymkey"
auth_model "code.gitea.io/gitea/models/auth"
@ -282,3 +283,53 @@ func TestAPIRenameUser(t *testing.T) {
})
MakeRequest(t, req, http.StatusOK)
}
func TestAPICron(t *testing.T) {
defer tests.PrepareTestEnv(t)()
// user1 is an admin user
session := loginUser(t, "user1")
t.Run("List", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin)
urlStr := fmt.Sprintf("/api/v1/admin/cron?token=%s", token)
req := NewRequest(t, "GET", urlStr)
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "25", resp.Header().Get("X-Total-Count"))
var crons []api.Cron
DecodeJSON(t, resp, &crons)
assert.Len(t, crons, 25)
})
t.Run("Execute", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
now := time.Now()
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin)
/// Archive cleanup is harmless, because in the text environment there are none
/// and is thus an NOOP operation and therefore doesn't interfere with any other
/// tests.
urlStr := fmt.Sprintf("/api/v1/admin/cron/archive_cleanup?token=%s", token)
req := NewRequest(t, "POST", urlStr)
MakeRequest(t, req, http.StatusNoContent)
// Check for the latest run time for this cron, to ensure it
// has been run.
urlStr = fmt.Sprintf("/api/v1/admin/cron?token=%s", token)
req = NewRequest(t, "GET", urlStr)
resp := MakeRequest(t, req, http.StatusOK)
var crons []api.Cron
DecodeJSON(t, resp, &crons)
for _, cron := range crons {
if cron.Name == "archive_cleanup" {
assert.True(t, now.Before(cron.Prev))
}
}
})
}