@@ -10,6 +10,8 @@ import (
1010
1111 "github.com/go-logr/logr"
1212 libgit2 "github.com/libgit2/git2go/v33"
13+ . "github.com/onsi/gomega"
14+ "k8s.io/apimachinery/pkg/types"
1315
1416 "github.com/fluxcd/pkg/gittestserver"
1517)
@@ -127,22 +129,32 @@ func TestPushRejected(t *testing.T) {
127129 t .Fatal (err )
128130 }
129131
130- // this is currently defined in update_test.go, but handy right here ..
131- if err = initGitRepo (gitServer , "testdata/appconfig" , "main" , "/appconfig.git" ); err != nil {
132+ // We use "test" as the branch to init repo, to avoid potential conflicts
133+ // with the default branch(main/master) of the system this test is running
134+ // on. If, for e.g., we used main as the branch and the default branch is
135+ // supposed to be main, this will fail as this would try to create a branch
136+ // named main explicitly.
137+ if err = initGitRepo (gitServer , "testdata/appconfig" , "test" , "/appconfig.git" ); err != nil {
132138 t .Fatal (err )
133139 }
134140
135141 repoURL := gitServer .HTTPAddressWithCredentials () + "/appconfig.git"
136- repo , err := clone (repoURL , "origin" , "main" )
142+ cloneCtx , cancel := context .WithTimeout (ctx , time .Second * 10 )
143+ defer cancel ()
144+ repo , err := clone (cloneCtx , repoURL , "test" )
137145 if err != nil {
138146 t .Fatal (err )
139147 }
148+ defer repo .Free ()
149+
150+ cleanup , err := configureTransportOptsForRepo (repo )
151+ if err != nil {
152+ t .Fatal (err )
153+ }
154+ defer cleanup ()
140155
141156 // This is here to guard against push in general being broken
142- err = push (context .TODO (), repo .Workdir (), "main" , repoAccess {
143- url : repoURL ,
144- auth : nil ,
145- })
157+ err = push (context .TODO (), repo .Workdir (), "test" , repoAccess {})
146158 if err != nil {
147159 t .Fatal (err )
148160 }
@@ -154,11 +166,104 @@ func TestPushRejected(t *testing.T) {
154166
155167 // This is supposed to fail, because the hook rejects the branch
156168 // pushed to.
157- err = push (context .TODO (), repo .Workdir (), branch , repoAccess {
158- url : repoURL ,
159- auth : nil ,
160- })
169+ err = push (context .TODO (), repo .Workdir (), branch , repoAccess {})
161170 if err == nil {
162171 t .Error ("push to a forbidden branch is expected to fail, but succeeded" )
163172 }
164173}
174+
175+ func Test_switchToBranch (t * testing.T ) {
176+ g := NewWithT (t )
177+ gitServer , err := gittestserver .NewTempGitServer ()
178+ g .Expect (err ).ToNot (HaveOccurred ())
179+ gitServer .AutoCreate ()
180+ g .Expect (gitServer .StartHTTP ()).To (Succeed ())
181+
182+ // We use "test" as the branch to init repo, to avoid potential conflicts
183+ // with the default branch(main/master) of the system this test is running
184+ // on. If, for e.g., we used main as the branch and the default branch is
185+ // supposed to be main, this will fail as this would try to create a branch
186+ // named main explicitly.
187+ branch := "test"
188+ g .Expect (initGitRepo (gitServer , "testdata/appconfig" , branch , "/appconfig.git" )).To (Succeed ())
189+
190+ repoURL := gitServer .HTTPAddressWithCredentials () + "/appconfig.git"
191+ cloneCtx , cancel := context .WithTimeout (ctx , time .Second * 10 )
192+ defer cancel ()
193+ repo , err := clone (cloneCtx , repoURL , branch )
194+ g .Expect (err ).ToNot (HaveOccurred ())
195+ defer repo .Free ()
196+
197+ head , err := repo .Head ()
198+ g .Expect (err ).ToNot (HaveOccurred ())
199+ defer head .Free ()
200+ target := head .Target ()
201+
202+ // register transport options and update remote to transport url
203+ cleanup , err := configureTransportOptsForRepo (repo )
204+ if err != nil {
205+ t .Fatal (err )
206+ }
207+ defer cleanup ()
208+
209+ // calling switchToBranch with a branch that doesn't exist on origin
210+ // should result in the branch being created and switched to.
211+ branch = "not-on-origin"
212+ switchToBranch (repo , context .TODO (), branch , repoAccess {})
213+
214+ head , err = repo .Head ()
215+ g .Expect (err ).ToNot (HaveOccurred ())
216+ name , err := head .Branch ().Name ()
217+ g .Expect (err ).ToNot (HaveOccurred ())
218+ g .Expect (name ).To (Equal (branch ))
219+
220+ cc , err := repo .LookupCommit (head .Target ())
221+ g .Expect (err ).ToNot (HaveOccurred ())
222+ defer cc .Free ()
223+ g .Expect (cc .Id ().String ()).To (Equal (target .String ()))
224+
225+ // create a branch with the HEAD commit and push it to origin
226+ branch = "exists-on-origin"
227+ _ , err = repo .CreateBranch (branch , cc , false )
228+ g .Expect (err ).ToNot (HaveOccurred ())
229+ origin , err := repo .Remotes .Lookup (originRemote )
230+ g .Expect (err ).ToNot (HaveOccurred ())
231+ defer origin .Free ()
232+
233+ g .Expect (origin .Push (
234+ []string {fmt .Sprintf ("refs/heads/%s:refs/heads/%s" , branch , branch )}, & libgit2.PushOptions {},
235+ )).To (Succeed ())
236+
237+ // push a new commit to the branch. this is done to test whether we properly
238+ // sync our local branch with the remote branch, before switching.
239+ policyKey := types.NamespacedName {
240+ Name : "policy" ,
241+ Namespace : "ns" ,
242+ }
243+ commitID := commitInRepo (g , repoURL , branch , "Install setter marker" , func (tmp string ) {
244+ g .Expect (replaceMarker (tmp , policyKey )).To (Succeed ())
245+ })
246+
247+ // calling switchToBranch with a branch that exists should make sure to fetch latest
248+ // for that branch from origin, and then switch to it.
249+ switchToBranch (repo , context .TODO (), branch , repoAccess {})
250+ head , err = repo .Head ()
251+ g .Expect (err ).ToNot (HaveOccurred ())
252+ name , err = head .Branch ().Name ()
253+
254+ g .Expect (err ).ToNot (HaveOccurred ())
255+ g .Expect (name ).To (Equal (branch ))
256+ g .Expect (head .Target ().String ()).To (Equal (commitID .String ()))
257+
258+ // push a commit after switching to the branch, to check if the local
259+ // branch is synced with origin.
260+ replaceMarker (repo .Workdir (), policyKey )
261+ sig := & libgit2.Signature {
262+ Name : "Testbot" ,
263+ 264+ When : time .Now (),
265+ }
266+ _ , err = commitWorkDir (repo , branch , "update policy" , sig )
267+ g .Expect (err ).ToNot (HaveOccurred ())
268+ g .Expect (push (context .TODO (), repo .Workdir (), branch , repoAccess {})).To (Succeed ())
269+ }
0 commit comments