mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-11-03 05:45:12 +08:00
Migrates the runner to `connectrpc.com/connect/v2` by pinning actionslib v1.5.0, which carries https://gitea.com/gitea/actionslib/pulls/28. The wire behaviour towards Gitea is unchanged and works against Gitea servers on connect v1 and v2. The client keeps v1's unlimited response size, and the error codes and messages the runner checks stay the same. Reviewed-on: https://gitea.com/gitea/runner/pulls/1325 Reviewed-by: bircni <bircni@icloud.com> Co-authored-by: silverwind <me@silverwind.io>
107 lines
3.5 KiB
Go
107 lines
3.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package report
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.com/gitea/runner/act/common/logging"
|
|
"gitea.com/gitea/runner/internal/pkg/client/mocks"
|
|
"gitea.com/gitea/runner/internal/pkg/config"
|
|
|
|
runnerv1 "gitea.dev/actionslib/runner/v1"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
)
|
|
|
|
var testStart = time.Date(2026, 8, 14, 9, 12, 3, 0, time.UTC)
|
|
|
|
func readJobLog(t *testing.T, joblog *jobLog) string {
|
|
t.Helper()
|
|
content, err := os.ReadFile(joblog.file.Name())
|
|
require.NoError(t, err)
|
|
return string(content)
|
|
}
|
|
|
|
func TestJobLog_MirrorsUploadedRows(t *testing.T) {
|
|
client := mocks.NewClient(t)
|
|
client.On("UpdateLog", mock.Anything, mock.Anything).Return(func(_ context.Context, req *runnerv1.UpdateLogRequest) (*runnerv1.UpdateLogResponse, error) {
|
|
return &runnerv1.UpdateLogResponse{AckIndex: req.Index + int64(len(req.Rows))}, nil
|
|
})
|
|
client.On("UpdateTask", mock.Anything, mock.Anything).Return(&runnerv1.UpdateTaskResponse{}, nil)
|
|
|
|
cfg, err := config.LoadDefault("")
|
|
require.NoError(t, err)
|
|
cfg.Log.Job.Dir = t.TempDir()
|
|
|
|
ctx, cancel := context.WithCancel(t.Context())
|
|
t.Cleanup(cancel)
|
|
task := &runnerv1.Task{Id: 41, Context: &structpb.Struct{}, Secrets: map[string]string{"TOKEN": "s3cret-value"}}
|
|
reporter := NewReporter(ctx, cancel, client, task, cfg)
|
|
require.NotNil(t, reporter.jobLog)
|
|
reporter.RunDaemon()
|
|
reporter.ResetSteps(newTestSteps(1))
|
|
|
|
fire := func(message string) {
|
|
require.NoError(t, fire(reporter, logEntry{
|
|
Message: message,
|
|
Level: logging.LevelInfo,
|
|
Data: map[string]any{"stage": "Main", "stepNumber": 0, "raw_output": true},
|
|
}))
|
|
}
|
|
fire("the token is s3cret-value")
|
|
reporter.AddMask("dyn4mic-value")
|
|
fire("and dyn4mic-value too")
|
|
require.NoError(t, reporter.Close(""))
|
|
|
|
job := readJobLog(t, reporter.jobLog)
|
|
assert.Contains(t, job, "the token is ***")
|
|
assert.Contains(t, job, "and *** too")
|
|
assert.NotContains(t, job, "s3cret-value")
|
|
assert.NotContains(t, job, "dyn4mic-value")
|
|
assert.NotRegexp(t, `(?m)^\S+Z ?$`, job, "the empty row Gitea needs is not job output")
|
|
assert.Contains(t, job, "[runner] task 41 finished: failure")
|
|
}
|
|
|
|
func TestJobLog_MaxSize(t *testing.T) {
|
|
joblog := openJobLog(config.LogJob{Dir: t.TempDir(), MaxSize: 200}, 1, testStart)
|
|
require.NotNil(t, joblog)
|
|
|
|
for range 10 {
|
|
joblog.write(testStart, strings.Repeat("x", 40))
|
|
}
|
|
joblog.close("task 1 finished: success")
|
|
joblog.write(testStart, "after the close") // a container goroutine can outlive the step
|
|
|
|
job := readJobLog(t, joblog)
|
|
assert.Equal(t, 1, strings.Count(job, "log.job.max_size"), "the cap is reported once")
|
|
assert.NotContains(t, job, "after the close")
|
|
assert.Contains(t, job, "[runner] task 1 finished: success", "the trailer is written past the cap")
|
|
}
|
|
|
|
func TestPruneJobLogs(t *testing.T) {
|
|
root := t.TempDir()
|
|
expired := filepath.Join(root, "20200101-000000-task-1.log")
|
|
fresh := filepath.Join(root, testStart.Format(jobLogNameLayout)+"-task-2.log")
|
|
unrelated := filepath.Join(root, "20200101-000000-task-3.txt")
|
|
for _, name := range []string{expired, fresh, unrelated} {
|
|
require.NoError(t, os.WriteFile(name, []byte("log"), 0o600))
|
|
}
|
|
|
|
pruneJobLogs(root, 0, testStart)
|
|
assert.FileExists(t, expired, "retention 0 keeps every log")
|
|
|
|
pruneJobLogs(root, 24*time.Hour, testStart)
|
|
assert.NoFileExists(t, expired)
|
|
assert.FileExists(t, fresh)
|
|
assert.FileExists(t, unrelated)
|
|
}
|