@@ -48,6 +48,7 @@ import (
48
48
ctrl "sigs.k8s.io/controller-runtime"
49
49
"sigs.k8s.io/controller-runtime/pkg/client"
50
50
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
51
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
51
52
"sigs.k8s.io/controller-runtime/pkg/log"
52
53
53
54
"github.com/fluxcd/pkg/apis/meta"
@@ -591,7 +592,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
591
592
},
592
593
want : ctrl.Result {RequeueAfter : mockInterval },
593
594
assertConditions : []metav1.Condition {
594
- * conditions .TrueCondition (sourcev1 .ArtifactAvailableCondition , "ArchivedArtifact" , "Archived artifact revision main/revision" ),
595
+ * conditions .TrueCondition (sourcev1 .ArtifactAvailableCondition , "ArchivedArtifact" , "Artifact revision main/revision" ),
595
596
},
596
597
},
597
598
{
@@ -662,6 +663,251 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
662
663
}
663
664
}
664
665
666
+ func TestGitRepositoryReconciler_reconcileInclude (t * testing.T ) {
667
+ g := NewWithT (t )
668
+
669
+ storage , err := newTestStorage ()
670
+ g .Expect (err ).NotTo (HaveOccurred ())
671
+ defer os .RemoveAll (storage .BasePath )
672
+
673
+ dependencyInterval := 5 * time .Second
674
+
675
+ type dependency struct {
676
+ name string
677
+ withArtifact bool
678
+ conditions []metav1.Condition
679
+ }
680
+
681
+ type include struct {
682
+ name string
683
+ fromPath string
684
+ toPath string
685
+ shouldExist bool
686
+ }
687
+
688
+ tests := []struct {
689
+ name string
690
+ dependencies []dependency
691
+ includes []include
692
+ want ctrl.Result
693
+ wantErr bool
694
+ assertConditions []metav1.Condition
695
+ }{
696
+ {
697
+ name : "Includes artifacts" ,
698
+ dependencies : []dependency {
699
+ {
700
+ name : "a" ,
701
+ withArtifact : true ,
702
+ conditions : []metav1.Condition {
703
+ * conditions .TrueCondition (meta .ReadyCondition , "Foo" , "foo ready" ),
704
+ },
705
+ },
706
+ {
707
+ name : "b" ,
708
+ withArtifact : true ,
709
+ conditions : []metav1.Condition {
710
+ * conditions .TrueCondition (meta .ReadyCondition , "Bar" , "bar ready" ),
711
+ },
712
+ },
713
+ },
714
+ includes : []include {
715
+ {name : "a" , toPath : "a/" },
716
+ {name : "b" , toPath : "b/" },
717
+ },
718
+ want : ctrl.Result {RequeueAfter : mockInterval },
719
+ assertConditions : []metav1.Condition {
720
+ * conditions .TrueCondition (sourcev1 .SourceAvailableCondition , "Foo" , "2 of 2 Ready" ),
721
+ },
722
+ },
723
+ {
724
+ name : "Non existing artifact" ,
725
+ includes : []include {
726
+ {name : "a" , toPath : "a/" },
727
+ },
728
+ want : ctrl.Result {RequeueAfter : mockInterval },
729
+ wantErr : false ,
730
+ assertConditions : []metav1.Condition {
731
+ * conditions .FalseCondition (sourcev1 .SourceAvailableCondition , "IncludeNotFound" , "Could not find resource for include \" a\" : gitrepositories.source.toolkit.fluxcd.io \" a\" not found" ),
732
+ },
733
+ },
734
+ {
735
+ name : "Missing artifact" ,
736
+ dependencies : []dependency {
737
+ {
738
+ name : "a" ,
739
+ withArtifact : false ,
740
+ conditions : []metav1.Condition {
741
+ * conditions .FalseCondition (sourcev1 .SourceAvailableCondition , "Foo" , "foo unavailable" ),
742
+ },
743
+ },
744
+ },
745
+ includes : []include {
746
+ {name : "a" , toPath : "a/" },
747
+ },
748
+ want : ctrl.Result {RequeueAfter : dependencyInterval },
749
+ assertConditions : []metav1.Condition {
750
+ * conditions .FalseCondition (sourcev1 .SourceAvailableCondition , "IncludeUnavailable" , "No artifact available for include \" a\" " ),
751
+ },
752
+ },
753
+ {
754
+ name : "Invalid FromPath" ,
755
+ dependencies : []dependency {
756
+ {
757
+ name : "a" ,
758
+ withArtifact : true ,
759
+ },
760
+ },
761
+ includes : []include {
762
+ {name : "a" , fromPath : "../../../path" , shouldExist : false },
763
+ },
764
+ wantErr : true ,
765
+ assertConditions : []metav1.Condition {
766
+ * conditions .FalseCondition (sourcev1 .SourceAvailableCondition , "IncludeCopyFailure" , "Failed to copy \" a\" include from ../../../path to a" ),
767
+ },
768
+ },
769
+ {
770
+ name : "Stalled include" ,
771
+ dependencies : []dependency {
772
+ {
773
+ name : "a" ,
774
+ withArtifact : true ,
775
+ conditions : []metav1.Condition {
776
+ * conditions .TrueCondition (meta .ReadyCondition , "Foo" , "foo ready" ),
777
+ },
778
+ },
779
+ {
780
+ name : "b" ,
781
+ withArtifact : true ,
782
+ conditions : []metav1.Condition {
783
+ * conditions .TrueCondition (meta .StalledCondition , "Bar" , "bar stalled" ),
784
+ },
785
+ },
786
+ },
787
+ includes : []include {
788
+ {name : "a" , toPath : "a/" },
789
+ {name : "b" , toPath : "b/" },
790
+ },
791
+ want : ctrl.Result {RequeueAfter : mockInterval },
792
+ assertConditions : []metav1.Condition {
793
+ * conditions .FalseCondition (sourcev1 .SourceAvailableCondition , "Bar @ GitRepository/a" , "bar stalled" ),
794
+ },
795
+ },
796
+ }
797
+ for _ , tt := range tests {
798
+ t .Run (tt .name , func (t * testing.T ) {
799
+ g := NewWithT (t )
800
+
801
+ var depObjs []client.Object
802
+ for _ , d := range tt .dependencies {
803
+ obj := & sourcev1.GitRepository {
804
+ ObjectMeta : metav1.ObjectMeta {
805
+ Name : d .name ,
806
+ },
807
+ Status : sourcev1.GitRepositoryStatus {
808
+ Conditions : d .conditions ,
809
+ },
810
+ }
811
+ if d .withArtifact {
812
+ obj .Status .Artifact = & sourcev1.Artifact {
813
+ Path : d .name + ".tar.gz" ,
814
+ Revision : d .name ,
815
+ LastUpdateTime : metav1 .Now (),
816
+ }
817
+ g .Expect (storage .Archive (obj .GetArtifact (), "testdata/git/repository" , nil )).To (Succeed ())
818
+ }
819
+ depObjs = append (depObjs , obj )
820
+ }
821
+
822
+ s := runtime .NewScheme ()
823
+ utilruntime .Must (sourcev1 .AddToScheme (s ))
824
+ builder := fakeclient .NewClientBuilder ().WithScheme (s )
825
+ if len (tt .dependencies ) > 0 {
826
+ builder .WithObjects (depObjs ... )
827
+ }
828
+
829
+ r := & GitRepositoryReconciler {
830
+ Client : builder .Build (),
831
+ Storage : storage ,
832
+ requeueDependency : dependencyInterval ,
833
+ }
834
+
835
+ obj := & sourcev1.GitRepository {
836
+ ObjectMeta : metav1.ObjectMeta {
837
+ Name : "reconcile-include" ,
838
+ },
839
+ Spec : sourcev1.GitRepositorySpec {
840
+ Interval : metav1.Duration {Duration : mockInterval },
841
+ },
842
+ }
843
+
844
+ for i , incl := range tt .includes {
845
+ incl := sourcev1.GitRepositoryInclude {
846
+ GitRepositoryRef : meta.LocalObjectReference {Name : incl .name },
847
+ FromPath : incl .fromPath ,
848
+ ToPath : incl .toPath ,
849
+ }
850
+ tt .includes [i ].fromPath = incl .GetFromPath ()
851
+ tt .includes [i ].toPath = incl .GetToPath ()
852
+ obj .Spec .Include = append (obj .Spec .Include , incl )
853
+ }
854
+
855
+ tmpDir , err := ioutil .TempDir ("" , "include-" )
856
+ g .Expect (err ).NotTo (HaveOccurred ())
857
+
858
+ var artifacts artifactSet
859
+ got , err := r .reconcileInclude (ctx , obj , artifacts , tmpDir )
860
+ g .Expect (obj .GetConditions ()).To (conditions .MatchConditions (tt .assertConditions ))
861
+ g .Expect (err != nil ).To (Equal (tt .wantErr ))
862
+ g .Expect (got ).To (Equal (tt .want ))
863
+ for _ , i := range tt .includes {
864
+ if i .toPath != "" {
865
+ expect := g .Expect (filepath .Join (storage .BasePath , i .toPath ))
866
+ if i .shouldExist {
867
+ expect .To (BeADirectory ())
868
+ } else {
869
+ expect .NotTo (BeADirectory ())
870
+ }
871
+ }
872
+ if i .shouldExist {
873
+ g .Expect (filepath .Join (storage .BasePath , i .toPath )).Should (BeADirectory ())
874
+ } else {
875
+ g .Expect (filepath .Join (storage .BasePath , i .toPath )).ShouldNot (BeADirectory ())
876
+ }
877
+ }
878
+ })
879
+ }
880
+ }
881
+
882
+ func TestGitRepositoryReconciler_reconcileDelete (t * testing.T ) {
883
+ g := NewWithT (t )
884
+
885
+ r := & GitRepositoryReconciler {
886
+ Storage : storage ,
887
+ }
888
+
889
+ obj := & sourcev1.GitRepository {
890
+ ObjectMeta : metav1.ObjectMeta {
891
+ Name : "reconcile-delete-" ,
892
+ DeletionTimestamp : & metav1.Time {Time : time .Now ()},
893
+ Finalizers : []string {
894
+ sourcev1 .SourceFinalizer ,
895
+ },
896
+ },
897
+ Status : sourcev1.GitRepositoryStatus {},
898
+ }
899
+
900
+ artifact := storage .NewArtifactFor (sourcev1 .GitRepositoryKind , obj .GetObjectMeta (), "revision" , "foo.txt" )
901
+ obj .Status .Artifact = & artifact
902
+
903
+ got , err := r .reconcileDelete (ctx , obj )
904
+ g .Expect (err ).NotTo (HaveOccurred ())
905
+ g .Expect (got ).To (Equal (ctrl.Result {}))
906
+ g .Expect (controllerutil .ContainsFinalizer (obj , sourcev1 .SourceFinalizer )).To (BeFalse ())
907
+ g .Expect (obj .Status .Artifact ).To (BeNil ())
908
+
909
+ }
910
+
665
911
func TestGitRepositoryReconciler_verifyCommitSignature (t * testing.T ) {
666
912
tests := []struct {
667
913
name string
0 commit comments