@@ -10,6 +10,9 @@ import (
1010
1111 "github.com/go-logr/logr"
1212 libgit2 "github.com/libgit2/git2go/v33"
13+ "k8s.io/apimachinery/pkg/types"
14+
15+ . "github.com/onsi/gomega"
1316
1417 "github.com/fluxcd/pkg/gittestserver"
1518 "github.com/fluxcd/source-controller/pkg/git/libgit2/managed"
@@ -129,12 +132,12 @@ func TestPushRejected(t *testing.T) {
129132 }
130133
131134 // this is currently defined in update_test.go, but handy right here ..
132- if err = initGitRepo (gitServer , "testdata/appconfig" , "master " , "/appconfig.git" ); err != nil {
135+ if err = initGitRepo (gitServer , "testdata/appconfig" , "test " , "/appconfig.git" ); err != nil {
133136 t .Fatal (err )
134137 }
135138
136139 repoURL := gitServer .HTTPAddressWithCredentials () + "/appconfig.git"
137- repo , err := clone (repoURL , "master " )
140+ repo , err := clone (repoURL , "test " )
138141 if err != nil {
139142 t .Fatal (err )
140143 }
@@ -148,7 +151,7 @@ func TestPushRejected(t *testing.T) {
148151 repo .Remotes .SetUrl ("origin" , transportOptsURL )
149152
150153 // This is here to guard against push in general being broken
151- err = push (context .TODO (), repo .Workdir (), "master " , repoAccess {})
154+ err = push (context .TODO (), repo .Workdir (), "test " , repoAccess {})
152155 if err != nil {
153156 t .Fatal (err )
154157 }
@@ -165,3 +168,93 @@ func TestPushRejected(t *testing.T) {
165168 t .Error ("push to a forbidden branch is expected to fail, but succeeded" )
166169 }
167170}
171+
172+ func Test_switchToBranch (t * testing.T ) {
173+ g := NewWithT (t )
174+ gitServer , err := gittestserver .NewTempGitServer ()
175+ g .Expect (err ).ToNot (HaveOccurred ())
176+ gitServer .AutoCreate ()
177+ g .Expect (gitServer .StartHTTP ()).To (Succeed ())
178+
179+ branch := "test"
180+ g .Expect (initGitRepo (gitServer , "testdata/appconfig" , branch , "/appconfig.git" )).To (Succeed ())
181+
182+ repoURL := gitServer .HTTPAddressWithCredentials () + "/appconfig.git"
183+ repo , err := clone (repoURL , branch )
184+ g .Expect (err ).ToNot (HaveOccurred ())
185+ defer repo .Free ()
186+
187+ head , err := repo .Head ()
188+ g .Expect (err ).ToNot (HaveOccurred ())
189+ defer head .Free ()
190+ target := head .Target ()
191+
192+ // register transport options and update remote to transport url
193+ transportOptsURL := "http://" + randStringRunes (5 )
194+ managed .AddTransportOptions (transportOptsURL , managed.TransportOptions {
195+ TargetURL : repoURL ,
196+ })
197+ defer managed .RemoveTransportOptions (transportOptsURL )
198+ repo .Remotes .SetUrl ("origin" , transportOptsURL )
199+
200+ // calling switchToBranch with a branch that doesn't exist on origin
201+ // should result in the branch being created and switched to.
202+ branch = "not-on-origin"
203+ switchToBranch (repo , context .TODO (), branch , repoAccess {})
204+
205+ head , err = repo .Head ()
206+ g .Expect (err ).ToNot (HaveOccurred ())
207+ name , err := head .Branch ().Name ()
208+ g .Expect (err ).ToNot (HaveOccurred ())
209+ g .Expect (name ).To (Equal (branch ))
210+
211+ cc , err := repo .LookupCommit (head .Target ())
212+ g .Expect (err ).ToNot (HaveOccurred ())
213+ defer cc .Free ()
214+ g .Expect (cc .Id ().String ()).To (Equal (target .String ()))
215+
216+ // create a branch with the HEAD commit and push it to origin
217+ branch = "exists-on-origin"
218+ _ , err = repo .CreateBranch (branch , cc , false )
219+ g .Expect (err ).ToNot (HaveOccurred ())
220+ origin , err := repo .Remotes .Lookup ("origin" )
221+ g .Expect (err ).ToNot (HaveOccurred ())
222+ defer origin .Free ()
223+
224+ g .Expect (origin .Push (
225+ []string {fmt .Sprintf ("refs/heads/%s:refs/heads/%s" , branch , branch )}, & libgit2.PushOptions {},
226+ )).To (Succeed ())
227+
228+ // push a new commit to the branch. this is done to test whether we properly
229+ // sync our local branch with the remote branch, before switching.
230+ policyKey := types.NamespacedName {
231+ Name : "policy" ,
232+ Namespace : "ns" ,
233+ }
234+ commitID := commitInRepo (g , repoURL , branch , "Install setter marker" , func (tmp string ) {
235+ g .Expect (replaceMarker (tmp , policyKey )).To (Succeed ())
236+ })
237+
238+ // calling switchToBranch with a branch that exists should make sure to fetch latest
239+ // for that branch from origin, and then switch to it.
240+ switchToBranch (repo , context .TODO (), branch , repoAccess {})
241+ head , err = repo .Head ()
242+ g .Expect (err ).ToNot (HaveOccurred ())
243+ name , err = head .Branch ().Name ()
244+
245+ g .Expect (err ).ToNot (HaveOccurred ())
246+ g .Expect (name ).To (Equal (branch ))
247+ g .Expect (head .Target ().String ()).To (Equal (commitID .String ()))
248+
249+ // push a commit after switching to the branch, to check if the local
250+ // branch is synced with origin.
251+ replaceMarker (repo .Workdir (), policyKey )
252+ sig := & libgit2.Signature {
253+ Name : "Testbot" ,
254+ 255+ When : time .Now (),
256+ }
257+ _ , err = commitWorkDir (repo , branch , "update policy" , sig )
258+ g .Expect (err ).ToNot (HaveOccurred ())
259+ g .Expect (push (context .TODO (), repo .Workdir (), branch , repoAccess {})).To (Succeed ())
260+ }
0 commit comments