From bf5564c09f94b4056fab1b6360ee39351e1d1f0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Dachary?= <loic@dachary.org>
Date: Wed, 29 Dec 2021 17:01:53 +0100
Subject: [PATCH 1/3] integrations: basic test for Gitea {dump,restore}-repo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is a first step for integration testing of DumpRepository and
RestoreRepository. It:

* runs a Gitea server,
* dumps a repo via DumpRepository to the filesystem,
* restores the repo via RestoreRepository from the filesystem,
* dumps the restored repository to the filesystem,
* compares the first and second dump and expects them to be identical

The verification is trivial and the goal is to add more tests for each
topic of the dump.

Signed-off-by: Loïc Dachary <loic@dachary.org>
---
 integrations/dump_restore_test.go | 106 ++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100644 integrations/dump_restore_test.go

diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go
new file mode 100644
index 0000000000000..9b5dce2ed63b2
--- /dev/null
+++ b/integrations/dump_restore_test.go
@@ -0,0 +1,106 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package integrations
+
+import (
+	"context"
+	"io/ioutil"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	repo_model "code.gitea.io/gitea/models/repo"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/util"
+	"code.gitea.io/gitea/services/migrations"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDumpRestore(t *testing.T) {
+	onGiteaRun(t, func(t *testing.T, u *url.URL) {
+		AllowLocalNetworks := setting.Migrations.AllowLocalNetworks
+		setting.Migrations.AllowLocalNetworks = true
+		AppVer := setting.AppVer
+		// TODO: Gitea SDK need to parse the AppVer from server response, so we must set it to a valid version string now.
+		// See also https://github.com/go-gitea/gitea/pull/18146
+		setting.AppVer = "1.16.0"
+		defer func() {
+			setting.Migrations.AllowLocalNetworks = AllowLocalNetworks
+			setting.AppVer = AppVer
+		}()
+
+		assert.NoError(t, migrations.Init())
+
+		reponame := "repo1"
+
+		basePath, err := os.MkdirTemp("", reponame)
+		assert.NoError(t, err)
+		defer util.RemoveAll(basePath)
+
+		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
+		repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+		session := loginUser(t, repoOwner.Name)
+		token := getTokenForLoggedInUser(t, session)
+
+		//
+		// Phase 1: dump repo1 from the Gitea instance to the filesystem
+		//
+
+		ctx := context.Background()
+		var opts = migrations.MigrateOptions{
+			GitServiceType: structs.GiteaService,
+			Issues:         true,
+			Comments:       true,
+			AuthToken:      token,
+			CloneAddr:      repo.CloneLink().HTTPS,
+			RepoName:       reponame,
+		}
+		err = migrations.DumpRepository(ctx, basePath, repoOwner.Name, opts)
+		assert.NoError(t, err)
+
+		//
+		// Verify desired side effects of the dump
+		//
+		d := filepath.Join(basePath, repo.OwnerName, repo.Name)
+		for _, f := range []string{"repo.yml", "topic.yml", "issue.yml"} {
+			assert.FileExists(t, filepath.Join(d, f))
+		}
+
+		//
+		// Phase 2: restore from the filesystem to the Gitea instance in restoredrepo
+		//
+
+		newreponame := "restoredrepo"
+		err = migrations.RestoreRepository(ctx, d, repo.OwnerName, newreponame, []string{"issues", "comments"})
+		assert.NoError(t, err)
+
+		newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame}).(*repo_model.Repository)
+
+		//
+		// Phase 3: dump restoredrepo from the Gitea instance to the filesystem
+		//
+		opts.RepoName = newreponame
+		opts.CloneAddr = newrepo.CloneLink().HTTPS
+		err = migrations.DumpRepository(ctx, basePath, repoOwner.Name, opts)
+		assert.NoError(t, err)
+
+		//
+		// Verify the dump of restoredrepo is the same as the dump of repo1
+		//
+		newd := filepath.Join(basePath, newrepo.OwnerName, newrepo.Name)
+		beforeBytes, err := ioutil.ReadFile(filepath.Join(d, "repo.yml"))
+		assert.NoError(t, err)
+		before := strings.ReplaceAll(string(beforeBytes), reponame, newreponame)
+		after, err := ioutil.ReadFile(filepath.Join(newd, "repo.yml"))
+		assert.NoError(t, err)
+		assert.EqualValues(t, before, string(after))
+	})
+}

From d0272ec89f01b1a6d95ce5b264f829f065c223fe Mon Sep 17 00:00:00 2001
From: wxiaoguang <wxiaoguang@gmail.com>
Date: Wed, 5 Jan 2022 01:51:33 +0800
Subject: [PATCH 2/3] document `setting.AppVer` behavior for go-sdk

---
 integrations/dump_restore_test.go | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go
index 9b5dce2ed63b2..b83b7c2c5303a 100644
--- a/integrations/dump_restore_test.go
+++ b/integrations/dump_restore_test.go
@@ -29,8 +29,7 @@ func TestDumpRestore(t *testing.T) {
 		AllowLocalNetworks := setting.Migrations.AllowLocalNetworks
 		setting.Migrations.AllowLocalNetworks = true
 		AppVer := setting.AppVer
-		// TODO: Gitea SDK need to parse the AppVer from server response, so we must set it to a valid version string now.
-		// See also https://github.com/go-gitea/gitea/pull/18146
+		// Gitea SDK (go-sdk) need to parse the AppVer from server response, so we must set it to a valid version string.
 		setting.AppVer = "1.16.0"
 		defer func() {
 			setting.Migrations.AllowLocalNetworks = AllowLocalNetworks

From 598c39dd74d2b46c0588171a66a74ddce44d4d88 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 4 Jan 2022 19:07:22 +0100
Subject: [PATCH 3/3] nit

Co-authored-by: Gusted <williamzijl7@hotmail.com>
---
 integrations/dump_restore_test.go | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go
index b83b7c2c5303a..6fe5d8fe6a86c 100644
--- a/integrations/dump_restore_test.go
+++ b/integrations/dump_restore_test.go
@@ -6,7 +6,6 @@ package integrations
 
 import (
 	"context"
-	"io/ioutil"
 	"net/url"
 	"os"
 	"path/filepath"
@@ -95,10 +94,10 @@ func TestDumpRestore(t *testing.T) {
 		// Verify the dump of restoredrepo is the same as the dump of repo1
 		//
 		newd := filepath.Join(basePath, newrepo.OwnerName, newrepo.Name)
-		beforeBytes, err := ioutil.ReadFile(filepath.Join(d, "repo.yml"))
+		beforeBytes, err := os.ReadFile(filepath.Join(d, "repo.yml"))
 		assert.NoError(t, err)
 		before := strings.ReplaceAll(string(beforeBytes), reponame, newreponame)
-		after, err := ioutil.ReadFile(filepath.Join(newd, "repo.yml"))
+		after, err := os.ReadFile(filepath.Join(newd, "repo.yml"))
 		assert.NoError(t, err)
 		assert.EqualValues(t, before, string(after))
 	})