@@ -13,37 +13,136 @@ import (
1313 "testing"
1414 "time"
1515
16+ "github.com/github/spokes-receive-pack/internal/objectformat"
1617 "github.com/stretchr/testify/assert"
1718 "github.com/stretchr/testify/require"
1819)
1920
2021func TestMissingObjects (t * testing.T ) {
21- var info struct {
22+
23+ x := setUpMissingObjectsTestRepo (t )
24+ testRepo := x .TestRepo
25+ info := x .Info
26+
27+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
28+ defer cancel ()
29+
30+ srp := startSpokesReceivePack (ctx , t , testRepo )
31+
32+ refs , _ , err := readAdv (srp .Out )
33+ require .NoError (t , err )
34+ assert .Equal (t , refs , map [string ]string {
35+ info .Ref : info .OldOID ,
36+ info .DelRef : info .OldOID ,
37+ })
38+
39+ // Send the pack that's missing a commit.
40+ pack , err := os .Open ("testdata/missing-objects/bad.pack" )
41+ require .NoError (t , err )
42+ defer pack .Close ()
43+
44+ writePushData (
45+ t , srp ,
46+ []refUpdate {
47+ // Try to update the ref that's already there to commit C (but we won't
48+ // push its parent and the remote doesn't have the parent either).
49+ {info .OldOID , info .NewOID , info .Ref },
50+ },
51+ pack ,
52+ )
53+
54+ refStatus , unpackRes , _ , err := readResult (t , srp .Out )
55+ require .NoError (t , err )
56+ assert .Equal (t , map [string ]string {
57+ info .Ref : "ng error processing packfiles: exit status 128" ,
58+ }, refStatus )
59+ assert .Equal (t , "unpack index-pack failed\n " , unpackRes )
60+ }
61+
62+ func TestDeleteAndUpdate (t * testing.T ) {
63+ const refToCreate = "refs/heads/new-branch"
64+
65+ x := setUpMissingObjectsTestRepo (t )
66+ testRepo := x .TestRepo
67+ info := x .Info
68+
69+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
70+ defer cancel ()
71+
72+ srp := startSpokesReceivePack (ctx , t , testRepo )
73+
74+ refs , _ , err := readAdv (srp .Out )
75+ require .NoError (t , err )
76+ assert .Equal (t , refs , map [string ]string {
77+ info .Ref : info .OldOID ,
78+ info .DelRef : info .OldOID ,
79+ })
80+
81+ // Send the pack that's missing a commit.
82+ pack , err := os .Open ("testdata/missing-objects/empty.pack" )
83+ require .NoError (t , err )
84+ defer pack .Close ()
85+
86+ writePushData (
87+ t , srp ,
88+ []refUpdate {
89+ // Try to create another ref with a commit that the remote already has.
90+ {objectformat .NullOIDSHA1 , info .OldOID , refToCreate },
91+ // Try to delete a ref.
92+ {info .OldOID , objectformat .NullOIDSHA1 , info .DelRef },
93+ },
94+ pack ,
95+ )
96+
97+ refStatus , unpackRes , _ , err := readResult (t , srp .Out )
98+ require .NoError (t , err )
99+ assert .Equal (t , map [string ]string {
100+ refToCreate : "ok" ,
101+ info .DelRef : "ok" ,
102+ }, refStatus )
103+ assert .Equal (t , "unpack ok\n " , unpackRes )
104+ }
105+
106+ type missingObjectsTestInfo struct {
107+ TestRepo string
108+ Info struct {
22109 OldOID string `json:"push_from"`
23110 NewOID string `json:"push_to"`
24111 Ref string `json:"ref"`
25112 DelRef string `json:"extra_ref"`
26113 }
114+ }
115+
116+ func setUpMissingObjectsTestRepo (t * testing.T ) missingObjectsTestInfo {
27117 const (
28- remote = "testdata/missing-objects/remote.git"
29- badPack = "testdata/missing-objects/bad.pack"
30- infoFile = "testdata/missing-objects/info.json"
31- refToCreate = "refs/heads/new-branch"
118+ remote = "testdata/missing-objects/remote.git"
119+ badPack = "testdata/missing-objects/bad.pack"
120+ infoFile = "testdata/missing-objects/info.json"
32121 )
33122
123+ var res missingObjectsTestInfo
124+
34125 infoJSON , err := os .ReadFile (infoFile )
35126 require .NoError (t , err )
36- require .NoError (t , json .Unmarshal (infoJSON , & info ))
127+ require .NoError (t , json .Unmarshal (infoJSON , & res . Info ))
37128
38129 origin , err := filepath .Abs (remote )
39130 require .NoError (t , err )
40131
41- testRepo : = t .TempDir ()
42- requireRun (t , "git" , "clone" , "--mirror" , origin , testRepo )
132+ res . TestRepo = t .TempDir ()
133+ requireRun (t , "git" , "clone" , "--mirror" , origin , res . TestRepo )
43134
44- ctx , cancel := context . WithTimeout ( context . Background (), time . Second )
45- defer cancel ()
135+ return res
136+ }
46137
138+ type spokesReceivePackProcess struct {
139+ Cmd * exec.Cmd
140+ In io.WriteCloser
141+ Out io.Reader
142+ Err chan error
143+ }
144+
145+ func startSpokesReceivePack (ctx context.Context , t * testing.T , testRepo string ) spokesReceivePackProcess {
47146 srp := exec .CommandContext (ctx , "spokes-receive-pack" , "." )
48147 srp .Dir = testRepo
49148 srp .Env = append (os .Environ (),
@@ -59,47 +158,34 @@ func TestMissingObjects(t *testing.T) {
59158
60159 bufSRPOut := bufio .NewReader (srpOut )
61160
62- refs , _ , err := readAdv (bufSRPOut )
63- require .NoError (t , err )
64- assert .Equal (t , refs , map [string ]string {
65- info .Ref : info .OldOID ,
66- info .DelRef : info .OldOID ,
67- })
68-
69- // Try to update the ref that's already there to commit C (but we won't
70- // push its parent and the remote doesn't have the parent either).
71- require .NoError (t , writePktlinef (srpIn ,
72- "%s %s %s\x00 report-status report-status-v2 side-band-64k object-format=sha1\n " ,
73- info .OldOID , info .NewOID , info .Ref ))
161+ return spokesReceivePackProcess {
162+ Cmd : srp ,
163+ In : srpIn ,
164+ Out : bufSRPOut ,
165+ Err : srpErr ,
166+ }
167+ }
74168
75- // Try to create another ref with a commit that the remote already has.
76- require .NoError (t , writePktlinef (srpIn ,
77- "%040d %s %s" ,
78- 0 , info .OldOID , refToCreate ))
169+ type refUpdate struct {
170+ OldOID , NewOID , Ref string
171+ }
79172
80- // Try to delete another ref.
81- require .NoError (t , writePktlinef (srpIn ,
82- "%s %040d %s" ,
83- info .OldOID , 0 , info .DelRef ))
173+ func writePushData (t * testing.T , srp spokesReceivePackProcess , updates []refUpdate , pack io.Reader ) {
174+ caps := "\x00 report-status report-status-v2 side-band-64k object-format=sha1\n "
175+ for _ , up := range updates {
176+ require .NoError (t , writePktlinef (srp .In ,
177+ "%s %s %s%s" ,
178+ up .OldOID , up .NewOID , up .Ref ,
179+ caps ))
180+ caps = ""
181+ }
84182
85- _ , err = srpIn .Write ([]byte ("0000" ))
183+ _ , err := srp . In .Write ([]byte ("0000" ))
86184 require .NoError (t , err )
87185
88- // Send the pack that's missing a commit.
89- pack , err := os .Open ("testdata/missing-objects/bad.pack" )
90- require .NoError (t , err )
91- if _ , err := io .Copy (srpIn , pack ); err != nil {
186+ if _ , err := io .Copy (srp .In , pack ); err != nil {
92187 t .Logf ("error writing pack to spokes-receive-pack input: %v" , err )
93188 }
94189
95- require .NoError (t , srpIn .Close ())
96-
97- refStatus , unpackRes , _ , err := readResult (t , bufSRPOut )
98- require .NoError (t , err )
99- assert .Equal (t , map [string ]string {
100- info .Ref : "ng missing necessary objects" ,
101- info .DelRef : "ok" ,
102- refToCreate : "ok" ,
103- }, refStatus )
104- assert .Equal (t , "unpack ok\n " , unpackRes )
190+ require .NoError (t , srp .In .Close ())
105191}
0 commit comments