mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-25 18:21:54 +00:00
Fixes #38494 `DeleteRepositoryDirectly` left rows behind in seven registered tables carrying a repo-scoped key: `action_variable`, `action_run_attempt`, `action_tasks_version`, `renamed_branch`, `commit_status_summary`, `commit_status_index` and `repo_transfer`. Repository IDs are `pk autoincr` and never reissued, so the orphaned rows were unreachable, but they accumulated forever (unbounded table growth, referential inconsistency; not a security issue, see the issue discussion). This adds all seven to the `deleteBeans` cascade, each placed next to its sibling bean (`CommitStatus`/`CommitStatusIndex`/`CommitStatusSummary`, `Branch`/`RenamedBranch`, `Secret`/`ActionVariable`, `ActionRun`/`ActionRunAttempt`). `repo_transfer` goes through the same cascade rather than `DeleteRepositoryTransfer` so teardown stays one mechanism; the existing reaper remains for the transfer flows. The test inserts one row per previously-orphaned table (the fixture files ask test cases to prepare their own data), deletes the repository, and asserts each table is purged. Without the fix it fails on all seven tables. --------- Signed-off-by: wxiaoguang <wxiaoguang@gmail.com> Signed-off-by: Luc <luuuc@users.noreply.github.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
83 lines
3.0 KiB
Go
83 lines
3.0 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repository_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
actions_model "gitea.dev/models/actions"
|
|
"gitea.dev/models/db"
|
|
git_model "gitea.dev/models/git"
|
|
"gitea.dev/models/organization"
|
|
repo_model "gitea.dev/models/repo"
|
|
"gitea.dev/models/unittest"
|
|
user_model "gitea.dev/models/user"
|
|
repo_service "gitea.dev/services/repository"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestTeam_HasRepository(t *testing.T) {
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
|
|
|
test := func(teamID, repoID int64, expected bool) {
|
|
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
|
|
assert.Equal(t, expected, repo_service.HasRepository(t.Context(), team, repoID))
|
|
}
|
|
test(1, 1, false)
|
|
test(1, 3, true)
|
|
test(1, 5, true)
|
|
test(1, unittest.NonexistentID, false)
|
|
|
|
test(2, 3, true)
|
|
test(2, 5, false)
|
|
}
|
|
|
|
func TestTeam_RemoveRepository(t *testing.T) {
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
|
|
|
testSuccess := func(teamID, repoID int64) {
|
|
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
|
|
assert.NoError(t, repo_service.RemoveRepositoryFromTeam(t.Context(), team, repoID))
|
|
unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID})
|
|
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID})
|
|
}
|
|
testSuccess(2, 3)
|
|
testSuccess(2, 5)
|
|
testSuccess(1, unittest.NonexistentID)
|
|
}
|
|
|
|
func TestDeleteOwnerRepositoriesDirectly(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
|
|
|
assert.NoError(t, repo_service.DeleteOwnerRepositoriesDirectly(t.Context(), user))
|
|
}
|
|
|
|
func TestDeleteRepositoryDirectlyPurgesRepoScopedRows(t *testing.T) {
|
|
unittest.PrepareTestEnv(t)
|
|
|
|
// One row per table that repository deletion used to leave behind (#38494).
|
|
assert.NoError(t, db.Insert(t.Context(),
|
|
&actions_model.ActionVariable{RepoID: 1, Name: "to_purge", Data: "value"},
|
|
&actions_model.ActionRunAttempt{RepoID: 1, RunID: unittest.NonexistentID, Attempt: 1},
|
|
&actions_model.ActionTasksVersion{RepoID: 1, Version: 1},
|
|
&git_model.RenamedBranch{RepoID: 1, From: "old-name", To: "new-name"},
|
|
&git_model.CommitStatusSummary{RepoID: 1, SHA: "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", State: "success"},
|
|
&repo_model.RepoTransfer{RepoID: 1, DoerID: 2, RecipientID: 3},
|
|
))
|
|
unittest.AssertExistsAndLoadBean(t, &git_model.CommitStatusIndex{RepoID: 1})
|
|
|
|
assert.NoError(t, repo_service.DeleteRepositoryDirectly(t.Context(), 1))
|
|
|
|
unittest.AssertNotExistsBean(t, &actions_model.ActionVariable{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &actions_model.ActionRunAttempt{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &actions_model.ActionTasksVersion{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &git_model.RenamedBranch{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &git_model.CommitStatusSummary{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &git_model.CommitStatusIndex{RepoID: 1})
|
|
unittest.AssertNotExistsBean(t, &repo_model.RepoTransfer{RepoID: 1})
|
|
}
|