mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-23 11:28:12 +02:00
Migrations should never use model structs directly, because the model structs can be different in different releases. e.g. if one migration uses "User" model, it works in the early releases, then one day, when the User model changes, the migration breaks because it will use the new (incorrect) User model, it should only use the old User model. The same to "modules/structs". --------- Signed-off-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: delvh <dev.lh@web.de>
157 lines
4.7 KiB
Go
157 lines
4.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package v1_27
|
|
|
|
import (
|
|
"context"
|
|
"slices"
|
|
"testing"
|
|
|
|
"gitea.dev/modelmigration/migrationtest"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"xorm.io/xorm/schemas"
|
|
)
|
|
|
|
type actionRunBeforeV331 struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
ConcurrencyGroup string
|
|
ConcurrencyCancel bool
|
|
LatestAttemptID int64 `xorm:"-"`
|
|
}
|
|
|
|
func (actionRunBeforeV331) TableName() string {
|
|
return "action_run"
|
|
}
|
|
|
|
type actionRunJobBeforeV331 struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
RunID int64 `xorm:"index"`
|
|
RepoID int64 `xorm:"index"`
|
|
}
|
|
|
|
func (actionRunJobBeforeV331) TableName() string {
|
|
return "action_run_job"
|
|
}
|
|
|
|
type actionArtifactBeforeV331 struct {
|
|
ID int64 `xorm:"pk autoincr"`
|
|
RunID int64 `xorm:"index unique(runid_name_path)"`
|
|
RepoID int64 `xorm:"index"`
|
|
ArtifactPath string `xorm:"index unique(runid_name_path)"`
|
|
ArtifactName string `xorm:"index unique(runid_name_path)"`
|
|
}
|
|
|
|
func (actionArtifactBeforeV331) TableName() string {
|
|
return "action_artifact"
|
|
}
|
|
|
|
func Test_AddActionRunAttemptModel(t *testing.T) {
|
|
x, deferable := migrationtest.PrepareTestEnv(t, 0,
|
|
new(actionRunBeforeV331),
|
|
new(actionRunJobBeforeV331),
|
|
new(actionArtifactBeforeV331),
|
|
)
|
|
defer deferable()
|
|
if x == nil || t.Failed() {
|
|
return
|
|
}
|
|
|
|
_, err := x.Insert(&actionArtifactBeforeV331{
|
|
RunID: 1,
|
|
RepoID: 1,
|
|
ArtifactPath: "artifact/path",
|
|
ArtifactName: "artifact-name",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, AddActionRunAttemptModel(x))
|
|
|
|
tableMap := migrationtest.LoadTableSchemasMap(t, x)
|
|
|
|
attemptTable := tableMap["action_run_attempt"]
|
|
require.NotNil(t, attemptTable)
|
|
attemptTablCols := []string{"id", "repo_id", "run_id", "attempt", "trigger_user_id", "status", "started", "stopped", "concurrency_group", "concurrency_cancel", "created", "updated"}
|
|
require.ElementsMatch(t, attemptTable.ColumnsSeq(), attemptTablCols)
|
|
|
|
runTable := tableMap["action_run"]
|
|
require.NotNil(t, runTable)
|
|
require.Contains(t, runTable.ColumnsSeq(), "latest_attempt_id")
|
|
require.NotContains(t, runTable.ColumnsSeq(), "concurrency_group")
|
|
require.NotContains(t, runTable.ColumnsSeq(), "concurrency_cancel")
|
|
|
|
jobTable := tableMap["action_run_job"]
|
|
require.NotNil(t, jobTable)
|
|
require.Contains(t, jobTable.ColumnsSeq(), "run_attempt_id")
|
|
require.Contains(t, jobTable.ColumnsSeq(), "attempt_job_id")
|
|
require.Contains(t, jobTable.ColumnsSeq(), "source_task_id")
|
|
|
|
attemptIndexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "action_run_attempt")
|
|
require.NoError(t, err)
|
|
assert.True(t, hasIndexWithColumns(attemptIndexes, []string{"run_id", "attempt"}, true))
|
|
assert.True(t, hasIndexWithColumns(attemptIndexes, []string{"repo_id", "concurrency_group", "status"}, false))
|
|
|
|
runIndexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "action_run")
|
|
require.NoError(t, err)
|
|
assert.True(t, hasIndexWithColumns(runIndexes, []string{"latest_attempt_id"}, false))
|
|
assert.False(t, hasIndexWithColumns(runIndexes, []string{"repo_id", "concurrency_group"}, false))
|
|
|
|
jobIndexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "action_run_job")
|
|
require.NoError(t, err)
|
|
assert.True(t, hasIndexWithColumns(jobIndexes, []string{"run_attempt_id"}, false))
|
|
assert.True(t, hasIndexWithColumns(jobIndexes, []string{"attempt_job_id"}, false))
|
|
|
|
indexes, err := x.Dialect().GetIndexes(x.DB(), context.Background(), "action_artifact")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasIndexWithColumns(indexes, []string{"run_id", "artifact_path", "artifact_name"}, true))
|
|
assert.True(t, hasIndexWithColumns(indexes, []string{"run_id", "run_attempt_id", "artifact_path", "artifact_name"}, true))
|
|
|
|
_, err = x.Insert(&actionArtifact{
|
|
RunID: 1,
|
|
RunAttemptID: 2,
|
|
RepoID: 1,
|
|
ArtifactPath: "artifact/path",
|
|
ArtifactName: "artifact-name",
|
|
})
|
|
require.NoError(t, err)
|
|
_, err = x.Insert(&actionArtifact{
|
|
RunID: 1,
|
|
RunAttemptID: 2,
|
|
RepoID: 1,
|
|
ArtifactPath: "artifact/path",
|
|
ArtifactName: "artifact-name",
|
|
})
|
|
require.Error(t, err)
|
|
|
|
_, err = x.Insert(&actionRunAttempt{
|
|
RepoID: 1,
|
|
RunID: 1,
|
|
Attempt: 2,
|
|
TriggerUserID: 1,
|
|
Status: 1,
|
|
})
|
|
require.NoError(t, err)
|
|
_, err = x.Insert(&actionRunAttempt{
|
|
RepoID: 1,
|
|
RunID: 1,
|
|
Attempt: 2,
|
|
TriggerUserID: 2,
|
|
Status: 1,
|
|
})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func hasIndexWithColumns(indexes map[string]*schemas.Index, cols []string, isUnique bool) bool {
|
|
for _, index := range indexes {
|
|
if isUnique && index.Type != schemas.UniqueType {
|
|
continue
|
|
}
|
|
if slices.Equal(index.Cols, cols) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|