mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 00:11:04 +00:00 
			
		
		
		
	Adds the ability to selectively choose which branches are pushed to a mirror. This change adds an additional text box on the repository settings for each push mirror. Existing behavior is preserved when the field is left blank. When the repository is being pushed, only branches matching the comma separated branch filter are pushed. Resolves forgejo/forgejo#7242 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7823 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Paul Campbell <pcampbell@kemitix.net> Co-committed-by: Paul Campbell <pcampbell@kemitix.net>
		
			
				
	
	
		
			445 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			445 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright The Forgejo Authors
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package integration
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"net"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"path/filepath"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	asymkey_model "forgejo.org/models/asymkey"
 | 
						|
	auth_model "forgejo.org/models/auth"
 | 
						|
	"forgejo.org/models/db"
 | 
						|
	repo_model "forgejo.org/models/repo"
 | 
						|
	"forgejo.org/models/unit"
 | 
						|
	"forgejo.org/models/unittest"
 | 
						|
	user_model "forgejo.org/models/user"
 | 
						|
	"forgejo.org/modules/git"
 | 
						|
	"forgejo.org/modules/optional"
 | 
						|
	"forgejo.org/modules/setting"
 | 
						|
	api "forgejo.org/modules/structs"
 | 
						|
	"forgejo.org/modules/test"
 | 
						|
	"forgejo.org/services/migrations"
 | 
						|
	mirror_service "forgejo.org/services/mirror"
 | 
						|
	repo_service "forgejo.org/services/repository"
 | 
						|
	"forgejo.org/tests"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
	"github.com/stretchr/testify/require"
 | 
						|
)
 | 
						|
 | 
						|
func TestAPIPushMirror(t *testing.T) {
 | 
						|
	onGiteaRun(t, testAPIPushMirror)
 | 
						|
}
 | 
						|
 | 
						|
func testAPIPushMirror(t *testing.T, u *url.URL) {
 | 
						|
	defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)()
 | 
						|
	defer test.MockVariableValue(&setting.Mirror.Enabled, true)()
 | 
						|
	defer test.MockProtect(&mirror_service.AddPushMirrorRemote)()
 | 
						|
	defer test.MockProtect(&repo_model.DeletePushMirrors)()
 | 
						|
 | 
						|
	require.NoError(t, migrations.Init())
 | 
						|
 | 
						|
	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
 | 
						|
	srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
						|
	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: srcRepo.OwnerID})
 | 
						|
	session := loginUser(t, user.Name)
 | 
						|
	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
 | 
						|
	urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/push_mirrors", owner.Name, srcRepo.Name)
 | 
						|
 | 
						|
	mirrorRepo, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user, user, repo_service.CreateRepoOptions{
 | 
						|
		Name: "test-push-mirror",
 | 
						|
	})
 | 
						|
	require.NoError(t, err)
 | 
						|
	remoteAddress := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo.Name))
 | 
						|
 | 
						|
	deletePushMirrors := repo_model.DeletePushMirrors
 | 
						|
	deletePushMirrorsError := errors.New("deletePushMirrorsError")
 | 
						|
	deletePushMirrorsFail := func(ctx context.Context, opts repo_model.PushMirrorOptions) error {
 | 
						|
		return deletePushMirrorsError
 | 
						|
	}
 | 
						|
 | 
						|
	addPushMirrorRemote := mirror_service.AddPushMirrorRemote
 | 
						|
	addPushMirrorRemoteError := errors.New("addPushMirrorRemoteError")
 | 
						|
	addPushMirrorRemoteFail := func(ctx context.Context, m *repo_model.PushMirror, addr string) error {
 | 
						|
		return addPushMirrorRemoteError
 | 
						|
	}
 | 
						|
 | 
						|
	for _, testCase := range []struct {
 | 
						|
		name        string
 | 
						|
		message     string
 | 
						|
		status      int
 | 
						|
		mirrorCount int
 | 
						|
		setup       func()
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:        "success",
 | 
						|
			status:      http.StatusOK,
 | 
						|
			mirrorCount: 1,
 | 
						|
			setup: func() {
 | 
						|
				mirror_service.AddPushMirrorRemote = addPushMirrorRemote
 | 
						|
				repo_model.DeletePushMirrors = deletePushMirrors
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "fail to add and delete",
 | 
						|
			message:     deletePushMirrorsError.Error(),
 | 
						|
			status:      http.StatusInternalServerError,
 | 
						|
			mirrorCount: 1,
 | 
						|
			setup: func() {
 | 
						|
				mirror_service.AddPushMirrorRemote = addPushMirrorRemoteFail
 | 
						|
				repo_model.DeletePushMirrors = deletePushMirrorsFail
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "fail to add",
 | 
						|
			message:     addPushMirrorRemoteError.Error(),
 | 
						|
			status:      http.StatusInternalServerError,
 | 
						|
			mirrorCount: 0,
 | 
						|
			setup: func() {
 | 
						|
				mirror_service.AddPushMirrorRemote = addPushMirrorRemoteFail
 | 
						|
				repo_model.DeletePushMirrors = deletePushMirrors
 | 
						|
			},
 | 
						|
		},
 | 
						|
	} {
 | 
						|
		t.Run(testCase.name, func(t *testing.T) {
 | 
						|
			testCase.setup()
 | 
						|
			req := NewRequestWithJSON(t, "POST", urlStr, &api.CreatePushMirrorOption{
 | 
						|
				RemoteAddress: remoteAddress,
 | 
						|
				Interval:      "8h",
 | 
						|
			}).AddTokenAuth(token)
 | 
						|
 | 
						|
			resp := MakeRequest(t, req, testCase.status)
 | 
						|
			if testCase.message != "" {
 | 
						|
				err := api.APIError{}
 | 
						|
				DecodeJSON(t, resp, &err)
 | 
						|
				assert.Equal(t, testCase.message, err.Message)
 | 
						|
			}
 | 
						|
 | 
						|
			req = NewRequest(t, "GET", urlStr).AddTokenAuth(token)
 | 
						|
			resp = MakeRequest(t, req, http.StatusOK)
 | 
						|
			var pushMirrors []*api.PushMirror
 | 
						|
			DecodeJSON(t, resp, &pushMirrors)
 | 
						|
			if assert.Len(t, pushMirrors, testCase.mirrorCount) && testCase.mirrorCount > 0 {
 | 
						|
				pushMirror := pushMirrors[0]
 | 
						|
				assert.Equal(t, remoteAddress, pushMirror.RemoteAddress)
 | 
						|
 | 
						|
				repo_model.DeletePushMirrors = deletePushMirrors
 | 
						|
				req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", urlStr, pushMirror.RemoteName)).AddTokenAuth(token)
 | 
						|
				MakeRequest(t, req, http.StatusNoContent)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestAPIPushMirrorBranchFilter(t *testing.T) {
 | 
						|
	onGiteaRun(t, testAPIPushMirrorBranchFilter)
 | 
						|
}
 | 
						|
 | 
						|
func testAPIPushMirrorBranchFilter(t *testing.T, u *url.URL) {
 | 
						|
	defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)()
 | 
						|
	defer test.MockVariableValue(&setting.Mirror.Enabled, true)()
 | 
						|
	defer test.MockProtect(&mirror_service.AddPushMirrorRemote)()
 | 
						|
	defer test.MockProtect(&repo_model.DeletePushMirrors)()
 | 
						|
 | 
						|
	require.NoError(t, migrations.Init())
 | 
						|
 | 
						|
	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
 | 
						|
	srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
						|
	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: srcRepo.OwnerID})
 | 
						|
	session := loginUser(t, user.Name)
 | 
						|
	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
 | 
						|
	urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/push_mirrors", owner.Name, srcRepo.Name)
 | 
						|
 | 
						|
	mirrorRepo, _, f := tests.CreateDeclarativeRepo(t, user, "", []unit.Type{unit.TypeCode}, nil, nil)
 | 
						|
	defer f()
 | 
						|
	remoteAddress := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo.Name))
 | 
						|
 | 
						|
	t.Run("Create push mirror with branch filter", func(t *testing.T) {
 | 
						|
		req := NewRequestWithJSON(t, "POST", urlStr, &api.CreatePushMirrorOption{
 | 
						|
			RemoteAddress: remoteAddress,
 | 
						|
			Interval:      "8h",
 | 
						|
			BranchFilter:  "main,develop",
 | 
						|
		}).AddTokenAuth(token)
 | 
						|
 | 
						|
		MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
		// Verify the push mirror was created with branch filter
 | 
						|
		req = NewRequest(t, "GET", urlStr).AddTokenAuth(token)
 | 
						|
		resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
		var pushMirrors []*api.PushMirror
 | 
						|
		DecodeJSON(t, resp, &pushMirrors)
 | 
						|
		require.Len(t, pushMirrors, 1)
 | 
						|
		assert.Equal(t, "main,develop", pushMirrors[0].BranchFilter)
 | 
						|
 | 
						|
		// Cleanup
 | 
						|
		req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", urlStr, pushMirrors[0].RemoteName)).AddTokenAuth(token)
 | 
						|
		MakeRequest(t, req, http.StatusNoContent)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Create push mirror with empty branch filter", func(t *testing.T) {
 | 
						|
		req := NewRequestWithJSON(t, "POST", urlStr, &api.CreatePushMirrorOption{
 | 
						|
			RemoteAddress: remoteAddress,
 | 
						|
			Interval:      "8h",
 | 
						|
			BranchFilter:  "",
 | 
						|
		}).AddTokenAuth(token)
 | 
						|
 | 
						|
		MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
		// Verify the push mirror was created with empty branch filter
 | 
						|
		req = NewRequest(t, "GET", urlStr).AddTokenAuth(token)
 | 
						|
		resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
		var pushMirrors []*api.PushMirror
 | 
						|
		DecodeJSON(t, resp, &pushMirrors)
 | 
						|
		require.Len(t, pushMirrors, 1)
 | 
						|
		assert.Empty(t, pushMirrors[0].BranchFilter)
 | 
						|
 | 
						|
		// Cleanup
 | 
						|
		req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", urlStr, pushMirrors[0].RemoteName)).AddTokenAuth(token)
 | 
						|
		MakeRequest(t, req, http.StatusNoContent)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Create push mirror without branch filter parameter", func(t *testing.T) {
 | 
						|
		req := NewRequestWithJSON(t, "POST", urlStr, &api.CreatePushMirrorOption{
 | 
						|
			RemoteAddress: remoteAddress,
 | 
						|
			Interval:      "8h",
 | 
						|
			// BranchFilter: ""
 | 
						|
		}).AddTokenAuth(token)
 | 
						|
 | 
						|
		MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
		// Verify the push mirror defaults to empty branch filter
 | 
						|
		req = NewRequest(t, "GET", urlStr).AddTokenAuth(token)
 | 
						|
		resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
		var pushMirrors []*api.PushMirror
 | 
						|
		DecodeJSON(t, resp, &pushMirrors)
 | 
						|
		require.Len(t, pushMirrors, 1)
 | 
						|
		assert.Empty(t, pushMirrors[0].BranchFilter)
 | 
						|
 | 
						|
		// Cleanup
 | 
						|
		req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", urlStr, pushMirrors[0].RemoteName)).AddTokenAuth(token)
 | 
						|
		MakeRequest(t, req, http.StatusNoContent)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("Retrieve multiple push mirrors with different branch filters", func(t *testing.T) {
 | 
						|
		// Create multiple push mirrors with different branch filters
 | 
						|
		testCases := []struct {
 | 
						|
			name         string
 | 
						|
			branchFilter string
 | 
						|
		}{
 | 
						|
			{"mirror-1", "main"},
 | 
						|
			{"mirror-2", "develop,feature-*"},
 | 
						|
			{"mirror-3", ""},
 | 
						|
		}
 | 
						|
 | 
						|
		// Create mirrors
 | 
						|
		mirrorCleanups := []func(){}
 | 
						|
		defer func() {
 | 
						|
			for _, mirror := range mirrorCleanups {
 | 
						|
				mirror()
 | 
						|
			}
 | 
						|
		}()
 | 
						|
		for _, tc := range testCases {
 | 
						|
			mirrorRepo, _, f := tests.CreateDeclarativeRepo(t, user, tc.name, []unit.Type{unit.TypeCode}, nil, nil)
 | 
						|
			mirrorCleanups = append(mirrorCleanups, f)
 | 
						|
 | 
						|
			remoteAddr := fmt.Sprintf("%s%s/%s", u.String(), url.PathEscape(user.Name), url.PathEscape(mirrorRepo.Name))
 | 
						|
			req := NewRequestWithJSON(t, "POST", urlStr, &api.CreatePushMirrorOption{
 | 
						|
				RemoteAddress: remoteAddr,
 | 
						|
				Interval:      "8h",
 | 
						|
				BranchFilter:  tc.branchFilter,
 | 
						|
			}).AddTokenAuth(token)
 | 
						|
 | 
						|
			MakeRequest(t, req, http.StatusOK)
 | 
						|
		}
 | 
						|
 | 
						|
		// Retrieve all mirrors and verify branch filters
 | 
						|
		req := NewRequest(t, "GET", urlStr).AddTokenAuth(token)
 | 
						|
		resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
		var pushMirrors []*api.PushMirror
 | 
						|
		DecodeJSON(t, resp, &pushMirrors)
 | 
						|
		require.Len(t, pushMirrors, 3)
 | 
						|
 | 
						|
		// Create a map for easier verification
 | 
						|
		filterMap := make(map[string]string)
 | 
						|
		var createdMirrors []*api.PushMirror
 | 
						|
		for _, mirror := range pushMirrors {
 | 
						|
			for _, tc := range testCases {
 | 
						|
				if strings.Contains(mirror.RemoteAddress, tc.name) {
 | 
						|
					filterMap[tc.name] = mirror.BranchFilter
 | 
						|
					createdMirrors = append(createdMirrors, mirror)
 | 
						|
					break
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		assert.Equal(t, "main", filterMap["mirror-1"])
 | 
						|
		assert.Equal(t, "develop,feature-*", filterMap["mirror-2"])
 | 
						|
		assert.Empty(t, filterMap["mirror-3"])
 | 
						|
 | 
						|
		// Cleanup
 | 
						|
		for _, mirror := range createdMirrors {
 | 
						|
			req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", urlStr, mirror.RemoteName)).AddTokenAuth(token)
 | 
						|
			MakeRequest(t, req, http.StatusNoContent)
 | 
						|
		}
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func TestAPIPushMirrorSSH(t *testing.T) {
 | 
						|
	_, err := exec.LookPath("ssh")
 | 
						|
	if err != nil {
 | 
						|
		t.Skip("SSH executable not present")
 | 
						|
	}
 | 
						|
 | 
						|
	onGiteaRun(t, func(t *testing.T, _ *url.URL) {
 | 
						|
		defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)()
 | 
						|
		defer test.MockVariableValue(&setting.Mirror.Enabled, true)()
 | 
						|
		defer test.MockVariableValue(&setting.SSH.RootPath, t.TempDir())()
 | 
						|
		require.NoError(t, migrations.Init())
 | 
						|
 | 
						|
		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 | 
						|
		srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
 | 
						|
		assert.False(t, srcRepo.HasWiki())
 | 
						|
		session := loginUser(t, user.Name)
 | 
						|
		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
 | 
						|
		pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
 | 
						|
			Name:         optional.Some("push-mirror-test"),
 | 
						|
			AutoInit:     optional.Some(false),
 | 
						|
			EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}),
 | 
						|
		})
 | 
						|
		defer f()
 | 
						|
 | 
						|
		sshURL := fmt.Sprintf("ssh://%s@%s/%s.git", setting.SSH.User, net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)), pushToRepo.FullName())
 | 
						|
 | 
						|
		t.Run("Mutual exclusive", func(t *testing.T) {
 | 
						|
			defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
			req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/push_mirrors", srcRepo.FullName()), &api.CreatePushMirrorOption{
 | 
						|
				RemoteAddress:  sshURL,
 | 
						|
				Interval:       "8h",
 | 
						|
				UseSSH:         true,
 | 
						|
				RemoteUsername: "user",
 | 
						|
				RemotePassword: "password",
 | 
						|
			}).AddTokenAuth(token)
 | 
						|
			resp := MakeRequest(t, req, http.StatusBadRequest)
 | 
						|
 | 
						|
			var apiError api.APIError
 | 
						|
			DecodeJSON(t, resp, &apiError)
 | 
						|
			assert.Equal(t, "'use_ssh' is mutually exclusive with 'remote_username' and 'remote_passoword'", apiError.Message)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("SSH not available", func(t *testing.T) {
 | 
						|
			defer tests.PrintCurrentTest(t)()
 | 
						|
			defer test.MockVariableValue(&git.HasSSHExecutable, false)()
 | 
						|
 | 
						|
			req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/push_mirrors", srcRepo.FullName()), &api.CreatePushMirrorOption{
 | 
						|
				RemoteAddress: sshURL,
 | 
						|
				Interval:      "8h",
 | 
						|
				UseSSH:        true,
 | 
						|
			}).AddTokenAuth(token)
 | 
						|
			resp := MakeRequest(t, req, http.StatusBadRequest)
 | 
						|
 | 
						|
			var apiError api.APIError
 | 
						|
			DecodeJSON(t, resp, &apiError)
 | 
						|
			assert.Equal(t, "SSH authentication not available.", apiError.Message)
 | 
						|
		})
 | 
						|
 | 
						|
		t.Run("Normal", func(t *testing.T) {
 | 
						|
			var pushMirror *repo_model.PushMirror
 | 
						|
			t.Run("Adding", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
				req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/push_mirrors", srcRepo.FullName()), &api.CreatePushMirrorOption{
 | 
						|
					RemoteAddress: sshURL,
 | 
						|
					Interval:      "8h",
 | 
						|
					UseSSH:        true,
 | 
						|
				}).AddTokenAuth(token)
 | 
						|
				MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
				pushMirror = unittest.AssertExistsAndLoadBean(t, &repo_model.PushMirror{RepoID: srcRepo.ID})
 | 
						|
				assert.NotEmpty(t, pushMirror.PrivateKey)
 | 
						|
				assert.NotEmpty(t, pushMirror.PublicKey)
 | 
						|
			})
 | 
						|
 | 
						|
			publickey := pushMirror.GetPublicKey()
 | 
						|
			t.Run("Publickey", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
				req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/push_mirrors", srcRepo.FullName())).AddTokenAuth(token)
 | 
						|
				resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
				var pushMirrors []*api.PushMirror
 | 
						|
				DecodeJSON(t, resp, &pushMirrors)
 | 
						|
				assert.Len(t, pushMirrors, 1)
 | 
						|
				assert.Equal(t, publickey, pushMirrors[0].PublicKey)
 | 
						|
			})
 | 
						|
 | 
						|
			t.Run("Add deploy key", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
				req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/keys", pushToRepo.FullName()), &api.CreateKeyOption{
 | 
						|
					Title:    "push mirror key",
 | 
						|
					Key:      publickey,
 | 
						|
					ReadOnly: false,
 | 
						|
				}).AddTokenAuth(token)
 | 
						|
				MakeRequest(t, req, http.StatusCreated)
 | 
						|
 | 
						|
				unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{Name: "push mirror key", RepoID: pushToRepo.ID})
 | 
						|
			})
 | 
						|
 | 
						|
			t.Run("Synchronize", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
				req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/push_mirrors-sync", srcRepo.FullName())).AddTokenAuth(token)
 | 
						|
				MakeRequest(t, req, http.StatusOK)
 | 
						|
			})
 | 
						|
 | 
						|
			t.Run("Check mirrored content", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
				sha := "1032bbf17fbc0d9c95bb5418dabe8f8c99278700"
 | 
						|
 | 
						|
				req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/commits?limit=1", srcRepo.FullName())).AddTokenAuth(token)
 | 
						|
				resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
				var commitList []*api.Commit
 | 
						|
				DecodeJSON(t, resp, &commitList)
 | 
						|
 | 
						|
				assert.Len(t, commitList, 1)
 | 
						|
				assert.Equal(t, sha, commitList[0].SHA)
 | 
						|
 | 
						|
				assert.Eventually(t, func() bool {
 | 
						|
					req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/commits?limit=1", srcRepo.FullName())).AddTokenAuth(token)
 | 
						|
					resp := MakeRequest(t, req, http.StatusOK)
 | 
						|
 | 
						|
					var commitList []*api.Commit
 | 
						|
					DecodeJSON(t, resp, &commitList)
 | 
						|
 | 
						|
					return len(commitList) != 0 && commitList[0].SHA == sha
 | 
						|
				}, time.Second*30, time.Second)
 | 
						|
			})
 | 
						|
 | 
						|
			t.Run("Check known host keys", func(t *testing.T) {
 | 
						|
				defer tests.PrintCurrentTest(t)()
 | 
						|
 | 
						|
				knownHosts, err := os.ReadFile(filepath.Join(setting.SSH.RootPath, "known_hosts"))
 | 
						|
				require.NoError(t, err)
 | 
						|
 | 
						|
				publicKey, err := os.ReadFile(setting.SSH.ServerHostKeys[0] + ".pub")
 | 
						|
				require.NoError(t, err)
 | 
						|
 | 
						|
				assert.Contains(t, string(knownHosts), string(publicKey))
 | 
						|
			})
 | 
						|
		})
 | 
						|
	})
 | 
						|
}
 |