chore: stabilize lint and verify builds
This commit is contained in:
@@ -3,16 +3,18 @@ package event
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"quyun/v2/app/commands"
|
||||
"quyun/v2/app/errorx"
|
||||
"quyun/v2/app/events/subscribers"
|
||||
"quyun/v2/providers/app"
|
||||
"quyun/v2/providers/event"
|
||||
"quyun/v2/providers/postgres"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
@@ -45,14 +47,19 @@ type Service struct {
|
||||
Initials []contracts.Initial `group:"initials"`
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
func Serve(_ *cobra.Command, _ []string) error {
|
||||
err := container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{})
|
||||
|
||||
if svc.App.IsDevMode() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
return svc.PubSub.Serve(ctx)
|
||||
})
|
||||
if err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"quyun/v2/app/commands"
|
||||
"quyun/v2/app/errorx"
|
||||
"quyun/v2/app/grpc/users"
|
||||
"quyun/v2/providers/app"
|
||||
"quyun/v2/providers/grpc"
|
||||
"quyun/v2/providers/postgres"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
@@ -44,14 +45,19 @@ type Service struct {
|
||||
Initials []contracts.Initial `group:"initials"`
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(svc Service) error {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
func Serve(_ *cobra.Command, _ []string) error {
|
||||
err := container.Container.Invoke(func(svc Service) error {
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{})
|
||||
|
||||
if svc.App.IsDevMode() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
return svc.Grpc.Serve()
|
||||
})
|
||||
if err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"quyun/v2/app/middlewares"
|
||||
"quyun/v2/app/services"
|
||||
"quyun/v2/database"
|
||||
_ "quyun/v2/docs"
|
||||
docs "quyun/v2/docs"
|
||||
"quyun/v2/providers/app"
|
||||
"quyun/v2/providers/http"
|
||||
"quyun/v2/providers/http/swagger"
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"go.ipao.vip/atom/contracts"
|
||||
|
||||
"github.com/gofiber/fiber/v3/middleware/favicon"
|
||||
log "github.com/sirupsen/logrus"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
@@ -65,31 +65,36 @@ type Service struct {
|
||||
|
||||
App *app.Config
|
||||
Job *job.Job
|
||||
Http *http.Service
|
||||
HTTP *http.Service
|
||||
DB *sql.DB
|
||||
Initials []contracts.Initial `group:"initials"`
|
||||
Routes []contracts.HttpRoute `group:"routes"`
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
func Serve(_ *cobra.Command, _ []string) error {
|
||||
if err := container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
_ = docs.SwaggerSpec
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{})
|
||||
|
||||
if svc.App.Mode == app.AppModeDevelopment {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
|
||||
svc.Http.Engine.Get("/swagger/*", swagger.HandlerDefault)
|
||||
svc.HTTP.Engine.Get("/swagger/*", swagger.HandlerDefault)
|
||||
}
|
||||
svc.Http.Engine.Use(errorx.Middleware)
|
||||
svc.Http.Engine.Use(favicon.New(favicon.Config{
|
||||
svc.HTTP.Engine.Use(errorx.Middleware)
|
||||
svc.HTTP.Engine.Use(favicon.New(favicon.Config{
|
||||
Data: []byte{},
|
||||
}))
|
||||
|
||||
for _, route := range svc.Routes {
|
||||
group := svc.Http.Engine.Group(route.Path(), route.Middlewares()...).Name(route.Name())
|
||||
group := svc.HTTP.Engine.Group(route.Path(), route.Middlewares()...).Name(route.Name())
|
||||
route.Register(group)
|
||||
}
|
||||
|
||||
return svc.Http.Serve(ctx)
|
||||
})
|
||||
return svc.HTTP.Serve(ctx)
|
||||
}); err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"quyun/v2/app/commands"
|
||||
"quyun/v2/app/errorx"
|
||||
"quyun/v2/database"
|
||||
"quyun/v2/providers/postgres"
|
||||
|
||||
"github.com/pressly/goose/v3"
|
||||
log "github.com/sirupsen/logrus"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
@@ -42,8 +43,8 @@ type Service struct {
|
||||
}
|
||||
|
||||
// migrate
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
func Serve(_ *cobra.Command, args []string) error {
|
||||
err := container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
if len(args) == 0 {
|
||||
args = append(args, "up")
|
||||
}
|
||||
@@ -53,7 +54,7 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
action, args := args[0], args[1:]
|
||||
log.Infof("migration action: %s args: %+v", action, args)
|
||||
logrus.Infof("migration action: %s args: %+v", action, args)
|
||||
|
||||
goose.SetBaseFS(database.MigrationFS)
|
||||
goose.SetTableName("migrations")
|
||||
@@ -66,6 +67,7 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
_, err = migrator.Migrate(ctx, rivermigrate.DirectionUp, &rivermigrate.MigrateOpts{TargetVersion: -1})
|
||||
|
||||
return err
|
||||
},
|
||||
func(ctx context.Context, db *sql.DB) error {
|
||||
@@ -75,9 +77,15 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
_, err = migrator.Migrate(ctx, rivermigrate.DirectionDown, &rivermigrate.MigrateOpts{TargetVersion: -1})
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
return goose.RunContext(context.Background(), action, svc.DB, "migrations", args...)
|
||||
return goose.RunContext(ctx, action, svc.DB, "migrations", args...)
|
||||
})
|
||||
if err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,19 +5,21 @@ import (
|
||||
|
||||
"github.com/riverqueue/river"
|
||||
"github.com/riverqueue/river/rivertype"
|
||||
log "github.com/sirupsen/logrus"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type CustomErrorHandler struct{}
|
||||
|
||||
func (*CustomErrorHandler) HandleError(ctx context.Context, job *rivertype.JobRow, err error) *river.ErrorHandlerResult {
|
||||
log.Infof("Job errored with: %s\n", err)
|
||||
func (*CustomErrorHandler) HandleError(_ context.Context, _ *rivertype.JobRow, err error) *river.ErrorHandlerResult {
|
||||
logrus.Infof("Job errored with: %s\n", err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*CustomErrorHandler) HandlePanic(ctx context.Context, job *rivertype.JobRow, panicVal any, trace string) *river.ErrorHandlerResult {
|
||||
log.Infof("Job panicked with: %v\n", panicVal)
|
||||
log.Infof("Stack trace: %s\n", trace)
|
||||
func (*CustomErrorHandler) HandlePanic(_ context.Context, _ *rivertype.JobRow, panicVal any, trace string) *river.ErrorHandlerResult {
|
||||
logrus.Infof("Job panicked with: %v\n", panicVal)
|
||||
logrus.Infof("Stack trace: %s\n", trace)
|
||||
|
||||
return &river.ErrorHandlerResult{
|
||||
SetCancelled: true,
|
||||
}
|
||||
|
||||
@@ -3,11 +3,8 @@ package queue
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
|
||||
"quyun/v2/app/commands"
|
||||
"quyun/v2/app/errorx"
|
||||
"quyun/v2/app/jobs"
|
||||
"quyun/v2/app/services"
|
||||
"quyun/v2/database"
|
||||
@@ -17,8 +14,11 @@ import (
|
||||
"quyun/v2/providers/postgres"
|
||||
"quyun/v2/providers/storage"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
logrus "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/container"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
@@ -56,20 +56,25 @@ type Service struct {
|
||||
CronJobs []contracts.CronJob `group:"cron_jobs"`
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
func Serve(_ *cobra.Command, _ []string) error {
|
||||
if err := container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{})
|
||||
|
||||
if svc.App.IsDevMode() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
if err := svc.Job.Start(ctx); err != nil {
|
||||
return err
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
defer svc.Job.Close()
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
return nil
|
||||
})
|
||||
}); err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package seed
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"quyun/v2/app/commands"
|
||||
"quyun/v2/app/errorx"
|
||||
"quyun/v2/database"
|
||||
"quyun/v2/database/fields"
|
||||
"quyun/v2/database/models"
|
||||
@@ -45,8 +47,8 @@ type Service struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
func Serve(_ *cobra.Command, _ []string) error {
|
||||
err := container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
models.SetDefault(svc.DB)
|
||||
fmt.Println("Cleaning existing data...")
|
||||
|
||||
@@ -137,10 +139,14 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// 2. Tenant
|
||||
tenantCodeSuffix, err := randomIntString(1000)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate tenant code: %w", err)
|
||||
}
|
||||
tenant := &models.Tenant{
|
||||
UserID: creator.ID,
|
||||
Name: "梅派艺术工作室",
|
||||
Code: "meipai_" + cast.ToString(rand.Intn(1000)),
|
||||
Code: "meipai_" + tenantCodeSuffix,
|
||||
UUID: types.UUID(uuid.New()),
|
||||
Status: consts.TenantStatusVerified,
|
||||
}
|
||||
@@ -189,6 +195,15 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
price = 990
|
||||
} // 9.90
|
||||
|
||||
viewsValue, err := randomIntWithLimit(10000)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate views: %w", err)
|
||||
}
|
||||
likesValue, err := randomIntWithLimit(1000)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate likes: %w", err)
|
||||
}
|
||||
|
||||
c := &models.Content{
|
||||
TenantID: tenant.ID,
|
||||
UserID: creator.ID,
|
||||
@@ -197,8 +212,8 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
Genre: "京剧",
|
||||
Status: consts.ContentStatusPublished,
|
||||
Visibility: consts.ContentVisibilityPublic,
|
||||
Views: int32(rand.Intn(10000)),
|
||||
Likes: int32(rand.Intn(1000)),
|
||||
Views: int32(viewsValue),
|
||||
Likes: int32(likesValue),
|
||||
}
|
||||
if err := models.ContentQuery.WithContext(ctx).Create(c); err == nil {
|
||||
seededContents = append(seededContents, c)
|
||||
@@ -413,10 +428,14 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
DecidedOperatorUserID: creator.ID,
|
||||
DecidedReason: "符合要求",
|
||||
})
|
||||
inviteSuffix, err := randomIntWithLimit(100000)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate invite code: %w", err)
|
||||
}
|
||||
models.TenantInviteQuery.WithContext(ctx).Create(&models.TenantInvite{
|
||||
TenantID: tenant.ID,
|
||||
UserID: creator.ID,
|
||||
Code: "invite" + cast.ToString(rand.Intn(100000)),
|
||||
Code: "invite" + cast.ToString(inviteSuffix),
|
||||
Status: "active",
|
||||
MaxUses: 5,
|
||||
UsedCount: 0,
|
||||
@@ -459,6 +478,7 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
})
|
||||
|
||||
// 8. System config
|
||||
|
||||
models.SystemConfigQuery.WithContext(ctx).Create(&models.SystemConfig{
|
||||
ConfigKey: "site_name",
|
||||
Value: types.JSON([]byte(`{"value":"曲韵平台"}`)),
|
||||
@@ -577,6 +597,34 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
fmt.Println("Seed done.")
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func randomIntString(limitValue int64) (string, error) {
|
||||
value, err := randomIntWithLimit(limitValue)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return cast.ToString(value), nil
|
||||
}
|
||||
|
||||
func randomIntWithLimit(limitValue int64) (int64, error) {
|
||||
if limitValue <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
limit := big.NewInt(limitValue)
|
||||
value, err := rand.Int(rand.Reader, limit)
|
||||
if err != nil {
|
||||
return 0, errorx.ErrOperationFailed.WithCause(err)
|
||||
}
|
||||
|
||||
return value.Int64(), nil
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"go.ipao.vip/atom/container"
|
||||
"quyun/v2/providers/app"
|
||||
"quyun/v2/providers/event"
|
||||
|
||||
"go.ipao.vip/atom/container"
|
||||
)
|
||||
|
||||
func Default(providers ...container.ProviderContainer) container.Providers {
|
||||
|
||||
@@ -2,7 +2,7 @@ package storage_migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -36,7 +36,7 @@ func defaultProviders() container.Providers {
|
||||
func Command() atom.Option {
|
||||
return atom.Command(
|
||||
atom.Name("storage-migrate"),
|
||||
atom.Short("migrate media assets to md5 object keys"),
|
||||
atom.Short("migrate media assets to sha256 object keys"),
|
||||
atom.Arguments(func(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("dry-run", false, "preview changes without writing")
|
||||
cmd.Flags().Int("batch", 200, "batch size per scan")
|
||||
@@ -54,7 +54,7 @@ type Service struct {
|
||||
Storage *storage.Storage
|
||||
}
|
||||
|
||||
func Serve(cmd *cobra.Command, args []string) error {
|
||||
func Serve(cmd *cobra.Command, _ []string) error {
|
||||
return container.Container.Invoke(func(ctx context.Context, svc Service) error {
|
||||
models.SetDefault(svc.DB)
|
||||
|
||||
@@ -84,7 +84,6 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
for _, asset := range list {
|
||||
// 仅处理本地存储且有实际文件路径的资源。
|
||||
if strings.ToLower(asset.Provider) != "local" {
|
||||
continue
|
||||
}
|
||||
@@ -96,13 +95,15 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
srcPath := asset.ObjectKey
|
||||
|
||||
if !filepath.IsAbs(srcPath) {
|
||||
srcPath = filepath.Join(localPath, filepath.FromSlash(srcPath))
|
||||
}
|
||||
|
||||
hash, size, err := fileMD5(srcPath)
|
||||
hash, size, err := fileSHA256(srcPath)
|
||||
if err != nil {
|
||||
fmt.Printf("skip asset=%d err=%v\n", asset.ID, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -164,26 +165,27 @@ func Serve(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func buildObjectKey(tenant *models.Tenant, hash, filename string) string {
|
||||
// 按租户维度组织对象路径:quyun/<tenant_uuid>/<md5>.<ext>
|
||||
tenantUUID := "public"
|
||||
if tenant != nil && tenant.UUID.String() != "" {
|
||||
tenantUUID = tenant.UUID.String()
|
||||
}
|
||||
ext := strings.ToLower(filepath.Ext(filename))
|
||||
|
||||
return path.Join("quyun", tenantUUID, hash+ext)
|
||||
}
|
||||
|
||||
func fileMD5(filename string) (string, int64, error) {
|
||||
func fileSHA256(filename string) (string, int64, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := md5.New()
|
||||
h := sha256.New()
|
||||
size, err := io.Copy(h, f)
|
||||
if err != nil {
|
||||
return "", size, err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil)), size, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package testx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -21,7 +22,7 @@ import (
|
||||
"go.uber.org/dig"
|
||||
|
||||
"github.com/rogeecn/fabfile"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
convey "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Default(providers ...container.ProviderContainer) container.Providers {
|
||||
@@ -39,7 +40,7 @@ type orderRefundTestWorker struct {
|
||||
river.WorkerDefaults[jobs_args.OrderRefundJob]
|
||||
}
|
||||
|
||||
func (w *orderRefundTestWorker) Work(ctx context.Context, job *river.Job[jobs_args.OrderRefundJob]) error {
|
||||
func (w *orderRefundTestWorker) Work(_ context.Context, _ *river.Job[jobs_args.OrderRefundJob]) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ type mediaAssetProcessTestWorker struct {
|
||||
river.WorkerDefaults[jobs_args.MediaAssetProcessJob]
|
||||
}
|
||||
|
||||
func (w *mediaAssetProcessTestWorker) Work(ctx context.Context, job *river.Job[jobs_args.MediaAssetProcessJob]) error {
|
||||
func (w *mediaAssetProcessTestWorker) Work(_ context.Context, _ *river.Job[jobs_args.MediaAssetProcessJob]) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -65,26 +66,29 @@ func (w *notificationTestWorker) Work(ctx context.Context, job *river.Job[jobs_a
|
||||
Content: arg.Content,
|
||||
IsRead: false,
|
||||
}
|
||||
|
||||
return models.NotificationQuery.WithContext(ctx).Create(n)
|
||||
}
|
||||
|
||||
func testJobWorkersProvider() container.ProviderContainer {
|
||||
return container.ProviderContainer{
|
||||
Provider: func(opts ...opt.Option) error {
|
||||
Provider: func(_ ...opt.Option) error {
|
||||
return container.Container.Provide(func(__job *job.Job) (contracts.Initial, error) {
|
||||
obj := &orderRefundTestWorker{}
|
||||
if err := river.AddWorkerSafely(__job.Workers, obj); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("register order refund test worker: %w", err)
|
||||
}
|
||||
|
||||
obj2 := &mediaAssetProcessTestWorker{}
|
||||
if err := river.AddWorkerSafely(__job.Workers, obj2); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("register media process test worker: %w", err)
|
||||
}
|
||||
|
||||
obj3 := ¬ificationTestWorker{}
|
||||
if err := river.AddWorkerSafely(__job.Workers, obj3); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("register notification test worker: %w", err)
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}, atom.GroupInitial)
|
||||
},
|
||||
@@ -92,40 +96,38 @@ func testJobWorkersProvider() container.ProviderContainer {
|
||||
}
|
||||
|
||||
func Serve(providers container.Providers, t *testing.T, invoke any) {
|
||||
Convey("tests boot up", t, func() {
|
||||
// 关键语义:测试用例可能会在同一进程内多次调用 Serve。
|
||||
// atom/config.Load 会向全局 dig 容器重复 Provide *viper.Viper,若不重置会导致 “already provided”。
|
||||
// 因此每次测试启动前都重置容器,保证各测试套件相互独立。
|
||||
convey.Convey("tests boot up", t, func() {
|
||||
baseCtx := context.Background()
|
||||
container.Close()
|
||||
container.Container = dig.New()
|
||||
So(container.Container.Provide(func() context.Context { return context.Background() }), ShouldBeNil)
|
||||
convey.So(container.Container.Provide(func() context.Context { return baseCtx }), convey.ShouldBeNil)
|
||||
|
||||
file := fabfile.MustFind("config.toml")
|
||||
// 支持通过 ENV_LOCAL 指定测试环境配置:config.<env>.toml
|
||||
localEnv := os.Getenv("ENV_LOCAL")
|
||||
if localEnv != "" {
|
||||
file = fabfile.MustFind("config." + localEnv + ".toml")
|
||||
}
|
||||
|
||||
So(atom.LoadProviders(file, providers), ShouldBeNil)
|
||||
So(os.Setenv("JOB_INLINE", "1"), ShouldBeNil)
|
||||
convey.So(atom.LoadProviders(file, providers), convey.ShouldBeNil)
|
||||
convey.So(os.Setenv("JOB_INLINE", "1"), convey.ShouldBeNil)
|
||||
t.Cleanup(func() {
|
||||
_ = os.Unsetenv("JOB_INLINE")
|
||||
})
|
||||
So(container.Container.Invoke(func(p struct {
|
||||
convey.So(container.Container.Invoke(func(params struct {
|
||||
dig.In
|
||||
Initials []contracts.Initial `group:"initials"`
|
||||
Job *job.Job
|
||||
},
|
||||
) error {
|
||||
_ = p.Initials
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
_ = params.Initials
|
||||
jobCtx, cancel := context.WithCancel(baseCtx)
|
||||
t.Cleanup(cancel)
|
||||
go func() {
|
||||
_ = p.Job.Start(ctx)
|
||||
_ = params.Job.Start(jobCtx)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}), ShouldBeNil)
|
||||
So(container.Container.Invoke(invoke), ShouldBeNil)
|
||||
}), convey.ShouldBeNil)
|
||||
convey.So(container.Container.Invoke(invoke), convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user