@@ -12,20 +12,21 @@ import (
12
12
"os"
13
13
"path/filepath"
14
14
"reflect"
15
- "strings"
16
15
"testing"
17
16
18
17
repo_model "code.gitea.io/gitea/models/repo"
19
18
"code.gitea.io/gitea/models/unittest"
20
19
user_model "code.gitea.io/gitea/models/user"
20
+ "code.gitea.io/gitea/modules/json"
21
21
base "code.gitea.io/gitea/modules/migration"
22
22
"code.gitea.io/gitea/modules/setting"
23
23
"code.gitea.io/gitea/modules/structs"
24
- "code.gitea.io/gitea/modules/util"
25
24
"code.gitea.io/gitea/services/migrations"
26
25
27
26
"github.com/stretchr/testify/assert"
28
- "gopkg.in/yaml.v2"
27
+ "lab.forgefriends.org/friendlyforgeformat/gofff"
28
+ "lab.forgefriends.org/friendlyforgeformat/gofff/forges/file"
29
+ "lab.forgefriends.org/friendlyforgeformat/gofff/format"
29
30
)
30
31
31
32
func TestDumpRestore (t * testing.T ) {
@@ -40,83 +41,91 @@ func TestDumpRestore(t *testing.T) {
40
41
setting .AppVer = AppVer
41
42
}()
42
43
43
- assert .NoError (t , migrations .Init ())
44
-
45
- reponame := "repo1"
46
-
47
- basePath , err := os .MkdirTemp ("" , reponame )
48
- assert .NoError (t , err )
49
- defer util .RemoveAll (basePath )
50
-
51
- repo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {Name : reponame }).(* repo_model.Repository )
52
- repoOwner := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : repo .OwnerID }).(* user_model.User )
44
+ repoOwner := unittest .AssertExistsAndLoadBean (t , & user_model.User {ID : 1 }).(* user_model.User )
53
45
session := loginUser (t , repoOwner .Name )
54
46
token := getTokenForLoggedInUser (t , session )
55
47
56
- //
57
- // Phase 1: dump repo1 from the Gitea instance to the filesystem
58
- //
48
+ fixture := file .NewFixture (t , gofff .AllFeatures )
49
+ fixture .CreateEverything (file.User {
50
+ ID : repoOwner .ID ,
51
+ Name : repoOwner .Name ,
52
+ Email : repoOwner .Email ,
53
+ })
59
54
60
- ctx := context .Background ()
61
- opts := migrations.MigrateOptions {
62
- GitServiceType : structs .GiteaService ,
63
- Issues : true ,
64
- PullRequests : true ,
65
- Labels : true ,
66
- Milestones : true ,
67
- Comments : true ,
68
- AuthToken : token ,
69
- CloneAddr : repo .CloneLink ().HTTPS ,
70
- RepoName : reponame ,
71
- }
72
- err = migrations .DumpRepository (ctx , basePath , repoOwner .Name , opts )
73
- assert .NoError (t , err )
74
-
75
- //
76
- // Verify desired side effects of the dump
77
- //
78
- d := filepath .Join (basePath , repo .OwnerName , repo .Name )
79
- for _ , f := range []string {"repo.yml" , "topic.yml" , "label.yml" , "milestone.yml" , "issue.yml" } {
80
- assert .FileExists (t , filepath .Join (d , f ))
81
- }
55
+ assert .NoError (t , migrations .Init ())
82
56
57
+ ctx := context .Background ()
83
58
//
84
- // Phase 2 : restore from the filesystem to the Gitea instance in restoredrepo
59
+ // Phase 1 : restore from the filesystem to the Gitea instance in restoredrepo
85
60
//
86
61
87
- newreponame := "restored"
88
- err = migrations .RestoreRepository (ctx , d , repo .OwnerName , newreponame , []string {
89
- "labels" , "issues" , "comments" , "milestones" , "pull_requests" ,
62
+ restoredRepoName := "restored"
63
+ restoredRepoDirectory := fixture .GetDirectory ()
64
+ err := migrations .RestoreRepository (ctx , restoredRepoDirectory , repoOwner .Name , restoredRepoName , []string {
65
+ "issues" , "milestones" , "labels" , "releases" , "release_assets" , "comments" , "pull_requests" ,
66
+ // wiki",
90
67
}, false )
91
68
assert .NoError (t , err )
92
69
93
- newrepo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {Name : newreponame }).(* repo_model.Repository )
70
+ restoredRepo := unittest .AssertExistsAndLoadBean (t , & repo_model.Repository {Name : restoredRepoName }).(* repo_model.Repository )
71
+ unittest .AssertExistsAndLoadBean (t , & repo_model.Attachment {Name : file .Asset1 })
94
72
95
73
//
96
- // Phase 3 : dump restored from the Gitea instance to the filesystem
74
+ // Phase 2 : dump restoredRepo from the Gitea instance to the filesystem
97
75
//
98
- opts .RepoName = newreponame
99
- opts .CloneAddr = newrepo .CloneLink ().HTTPS
100
- err = migrations .DumpRepository (ctx , basePath , repoOwner .Name , opts )
76
+
77
+ opts := base.MigrateOptions {
78
+ GitServiceType : structs .GiteaService ,
79
+
80
+ Wiki : true ,
81
+ Issues : true ,
82
+ Milestones : true ,
83
+ Labels : true ,
84
+ Releases : true ,
85
+ Comments : true ,
86
+ PullRequests : true ,
87
+ ReleaseAssets : true ,
88
+
89
+ AuthToken : token ,
90
+ CloneAddr : restoredRepo .CloneLink ().HTTPS ,
91
+ RepoName : restoredRepoName ,
92
+ }
93
+ dumpedRepoDirectory := t .TempDir ()
94
+ err = migrations .DumpRepository (ctx , dumpedRepoDirectory , repoOwner .Name , opts )
101
95
assert .NoError (t , err )
102
96
103
97
//
104
98
// Verify the dump of restored is the same as the dump of repo1
105
99
//
100
+ //fixture.AssertEquals(restoredRepoDirectory, dumpedRepoDirectory)
101
+ //
102
+ // Verify the fixture files are the same as the restored files
103
+ //
104
+ project := fixture .GetFile ().GetProject ()
106
105
comparator := & compareDump {
107
- t : t ,
108
- basePath : basePath ,
106
+ t : t ,
107
+
108
+ repoBefore : project .Name ,
109
+ ownerBefore : project .Owner ,
110
+ dirBefore : restoredRepoDirectory ,
111
+
112
+ repoAfter : restoredRepoName ,
113
+ ownerAfter : repoOwner .Name ,
114
+ dirAfter : dumpedRepoDirectory ,
109
115
}
110
- comparator .assertEquals (repo , newrepo )
116
+ comparator .assertEquals ()
111
117
})
112
118
}
113
119
114
120
type compareDump struct {
115
- t * testing.T
116
- basePath string
117
- repoBefore * repo_model.Repository
118
- dirBefore string
119
- repoAfter * repo_model.Repository
121
+ t * testing.T
122
+
123
+ repoBefore string
124
+ ownerBefore string
125
+ dirBefore string
126
+
127
+ repoAfter string
128
+ ownerAfter string
120
129
dirAfter string
121
130
}
122
131
@@ -130,92 +139,99 @@ type compareField struct {
130
139
131
140
type compareFields map [string ]compareField
132
141
133
- func (c * compareDump ) replaceRepoName (original string ) string {
134
- return strings .ReplaceAll (original , c .repoBefore .Name , c .repoAfter .Name )
135
- }
136
-
137
- func (c * compareDump ) assertEquals (repoBefore , repoAfter * repo_model.Repository ) {
138
- c .repoBefore = repoBefore
139
- c .dirBefore = filepath .Join (c .basePath , repoBefore .OwnerName , repoBefore .Name )
140
- c .repoAfter = repoAfter
141
- c .dirAfter = filepath .Join (c .basePath , repoAfter .OwnerName , repoAfter .Name )
142
-
142
+ func (c * compareDump ) assertEquals () {
143
143
//
144
144
// base.Repository
145
145
//
146
- _ = c .assertEqual ("repo.yml " , base. Repository {}, compareFields {
146
+ _ = c .assertEqual ("project.json " , format. Project {}, compareFields {
147
147
"Name" : {
148
- before : c .repoBefore .Name ,
149
- after : c .repoAfter .Name ,
148
+ before : c .repoBefore ,
149
+ after : c .repoAfter ,
150
+ },
151
+ "Owner" : {
152
+ before : c .ownerBefore ,
153
+ after : c .ownerAfter ,
150
154
},
151
- "CloneURL " : {transform : c . replaceRepoName },
152
- "OriginalURL " : {transform : c . replaceRepoName },
155
+ "Index " : {ignore : true },
156
+ "CloneURL " : {ignore : true },
153
157
})
154
158
155
159
//
156
160
// base.Label
157
161
//
158
- labels , ok := c .assertEqual ("label.yml" , []base.Label {}, compareFields {}).([]* base.Label )
162
+ compareLabels := compareFields {
163
+ "Index" : {ignore : true },
164
+ }
165
+ labels , ok := c .assertEqual ("label.json" , []format.Label {}, compareLabels ).([]* format.Label )
159
166
assert .True (c .t , ok )
160
167
assert .GreaterOrEqual (c .t , len (labels ), 1 )
161
168
162
169
//
163
170
// base.Milestone
164
171
//
165
- milestones , ok := c .assertEqual ("milestone.yml" , []base.Milestone {}, compareFields {
172
+ milestones , ok := c .assertEqual ("milestone.json" , []format.Milestone {}, compareFields {
173
+ "Index" : {ignore : true },
166
174
"Updated" : {ignore : true }, // the database updates that field independently
167
- }).([]* base .Milestone )
175
+ }).([]* format .Milestone )
168
176
assert .True (c .t , ok )
169
177
assert .GreaterOrEqual (c .t , len (milestones ), 1 )
170
178
171
179
//
172
- // base .Issue and the associated comments
180
+ // format .Issue and the associated comments
173
181
//
174
- issues , ok := c .assertEqual ("issue.yml" , []base.Issue {}, compareFields {
182
+ issues , ok := c .assertEqual ("issue.json" , []format.Issue {}, compareFields {
183
+ "Index" : {ignore : true },
175
184
"Assignees" : {ignore : true }, // not implemented yet
176
- }).([]* base.Issue )
185
+ "Labels" : {nested : & compareLabels },
186
+ }).([]* format.Issue )
177
187
assert .True (c .t , ok )
178
188
assert .GreaterOrEqual (c .t , len (issues ), 1 )
179
189
for _ , issue := range issues {
180
- filename := filepath .Join ("comments" , fmt .Sprintf ("%d.yml " , issue .Number ))
181
- comments , ok := c .assertEqual (filename , []base .Comment {}, compareFields {
190
+ filename := filepath .Join ("comments" , fmt .Sprintf ("%d.json " , issue .Number ))
191
+ comments , ok := c .assertEqual (filename , []format .Comment {}, compareFields {
182
192
"Index" : {ignore : true },
183
- }).([]* base .Comment )
193
+ }).([]* format .Comment )
184
194
assert .True (c .t , ok )
185
195
for _ , comment := range comments {
186
196
assert .EqualValues (c .t , issue .Number , comment .IssueIndex )
187
197
}
188
198
}
189
199
190
200
//
191
- // base .PullRequest and the associated comments
201
+ // format .PullRequest and the associated comments
192
202
//
193
203
comparePullRequestBranch := & compareFields {
194
204
"RepoName" : {
195
- before : c .repoBefore .Name ,
196
- after : c .repoAfter .Name ,
205
+ before : c .repoBefore ,
206
+ after : c .repoAfter ,
207
+ },
208
+ "OwnerName" : {
209
+ before : c .ownerBefore ,
210
+ after : c .ownerAfter ,
197
211
},
198
- "CloneURL" : {transform : c . replaceRepoName },
212
+ "CloneURL" : {ignore : true },
199
213
}
200
- prs , ok := c .assertEqual ("pull_request.yml " , []base .PullRequest {}, compareFields {
214
+ prs , ok := c .assertEqual ("pull_request.json " , []format .PullRequest {}, compareFields {
201
215
"Assignees" : {ignore : true }, // not implemented yet
202
216
"Head" : {nested : comparePullRequestBranch },
203
217
"Base" : {nested : comparePullRequestBranch },
218
+ "PatchURL" : {ignore : true },
219
+ "CloneURL" : {ignore : true },
204
220
"Labels" : {ignore : true }, // because org labels are not handled properly
205
- }).([]* base .PullRequest )
221
+ }).([]* format .PullRequest )
206
222
assert .True (c .t , ok )
207
223
assert .GreaterOrEqual (c .t , len (prs ), 1 )
208
224
for _ , pr := range prs {
209
- filename := filepath .Join ("comments" , fmt .Sprintf ("%d.yml " , pr .Number ))
210
- comments , ok := c .assertEqual (filename , []base .Comment {}, compareFields {}).([]* base .Comment )
225
+ filename := filepath .Join ("comments" , fmt .Sprintf ("%d.json " , pr .Number ))
226
+ comments , ok := c .assertEqual (filename , []format .Comment {}, compareFields {}).([]* format .Comment )
211
227
assert .True (c .t , ok )
212
228
for _ , comment := range comments {
213
229
assert .EqualValues (c .t , pr .Number , comment .IssueIndex )
214
230
}
215
231
}
216
232
}
217
233
218
- func (c * compareDump ) assertLoadYAMLFiles (beforeFilename , afterFilename string , before , after interface {}) {
234
+ func (c * compareDump ) assertLoadJSONFiles (beforeFilename , afterFilename string , before , after interface {}) {
219
235
_ , beforeErr := os .Stat (beforeFilename )
220
236
_ , afterErr := os .Stat (afterFilename )
221
237
assert .EqualValues (c .t , errors .Is (beforeErr , os .ErrNotExist ), errors .Is (afterErr , os .ErrNotExist ))
@@ -225,10 +241,10 @@ func (c *compareDump) assertLoadYAMLFiles(beforeFilename, afterFilename string,
225
241
226
242
beforeBytes , err := os .ReadFile (beforeFilename )
227
243
assert .NoError (c .t , err )
228
- assert .NoError (c .t , yaml .Unmarshal (beforeBytes , before ))
244
+ assert .NoError (c .t , json .Unmarshal (beforeBytes , before ))
229
245
afterBytes , err := os .ReadFile (afterFilename )
230
246
assert .NoError (c .t , err )
231
- assert .NoError (c .t , yaml .Unmarshal (afterBytes , after ))
247
+ assert .NoError (c .t , json .Unmarshal (afterBytes , after ))
232
248
}
233
249
234
250
func (c * compareDump ) assertLoadFiles (beforeFilename , afterFilename string , t reflect.Type ) (before , after reflect.Value ) {
@@ -251,13 +267,14 @@ func (c *compareDump) assertLoadFiles(beforeFilename, afterFilename string, t re
251
267
beforePtr = reflect .New (t )
252
268
afterPtr = reflect .New (t )
253
269
}
254
- c .assertLoadYAMLFiles (beforeFilename , afterFilename , beforePtr .Interface (), afterPtr .Interface ())
270
+ c .assertLoadJSONFiles (beforeFilename , afterFilename , beforePtr .Interface (), afterPtr .Interface ())
255
271
return beforePtr .Elem (), afterPtr .Elem ()
256
272
}
257
273
258
274
func (c * compareDump ) assertEqual (filename string , kind interface {}, fields compareFields ) (i interface {}) {
259
275
beforeFilename := filepath .Join (c .dirBefore , filename )
260
276
afterFilename := filepath .Join (c .dirAfter , filename )
277
+ fmt .Println ("assertEqual " , beforeFilename , afterFilename )
261
278
262
279
typeOf := reflect .TypeOf (kind )
263
280
before , after := c .assertLoadFiles (beforeFilename , afterFilename , typeOf )
@@ -300,29 +317,34 @@ func (c *compareDump) assertEqualValues(before, after reflect.Value, fields comp
300
317
// Transform these strings before comparing them
301
318
//
302
319
bs , ok := bi .(string )
303
- assert .True (c .t , ok )
320
+ assert .True (c .t , ok , field . Name )
304
321
as , ok := ai .(string )
305
- assert .True (c .t , ok )
306
- assert .EqualValues (c .t , compare .transform (bs ), compare .transform (as ))
322
+ assert .True (c .t , ok , field . Name )
323
+ assert .EqualValues (c .t , compare .transform (bs ), compare .transform (as ), field . Name )
307
324
continue
308
325
}
309
326
if compare .before != nil && compare .after != nil {
310
327
//
311
328
// The fields are expected to have different values
312
329
//
313
- assert .EqualValues (c .t , compare .before , bi )
314
- assert .EqualValues (c .t , compare .after , ai )
330
+ assert .EqualValues (c .t , compare .before , bi , field . Name )
331
+ assert .EqualValues (c .t , compare .after , ai , field . Name )
315
332
continue
316
333
}
317
334
if compare .nested != nil {
318
335
//
319
- // The fields are a struct, recurse
336
+ // The fields are a struct/slice , recurse
320
337
//
321
- c .assertEqualValues (bf , af , * compare .nested )
338
+ fmt .Println ("nested " , field .Name )
339
+ if reflect .TypeOf (bi ).Kind () == reflect .Slice {
340
+ c .assertEqualSlices (bf , af , * compare .nested )
341
+ } else {
342
+ c .assertEqualValues (bf , af , * compare .nested )
343
+ }
322
344
continue
323
345
}
324
346
}
325
- assert .EqualValues (c .t , bi , ai )
347
+ assert .EqualValues (c .t , bi , ai , field . Name )
326
348
}
327
349
return after .Interface ()
328
350
}
0 commit comments