@@ -515,6 +515,156 @@ func TestHelmChartReconciler_reconcileSource(t *testing.T) {
515515 }
516516}
517517
518+ func TestHelmChartReconciler_reconcileFromHelmRepository (t * testing.T ) {
519+ g := NewWithT (t )
520+
521+ const (
522+ chartName = "helmchart"
523+ chartVersion = "0.2.0"
524+ higherChartVersion = "0.3.0"
525+ chartPath = "testdata/charts/helmchart"
526+ )
527+
528+ serverFactory , err := helmtestserver .NewTempHelmServer ()
529+ g .Expect (err ).NotTo (HaveOccurred ())
530+ defer os .RemoveAll (serverFactory .Root ())
531+
532+ for _ , ver := range []string {chartVersion , higherChartVersion } {
533+ g .Expect (serverFactory .PackageChartWithVersion (chartPath , ver )).To (Succeed ())
534+ }
535+ g .Expect (serverFactory .GenerateIndex ()).To (Succeed ())
536+
537+ tests := []struct {
538+ name string
539+ beforeFunc func (repository * sourcev1.HelmRepository )
540+ assertFunc func (g * WithT , obj * sourcev1.HelmChart )
541+ }{
542+ {
543+ name : "Reconciles chart build" ,
544+ assertFunc : func (g * WithT , obj * sourcev1.HelmChart ) {
545+ key := client.ObjectKey {Name : obj .Name , Namespace : obj .Namespace }
546+ // Wait for HelmChart to be Ready
547+ g .Eventually (func () bool {
548+ if err := testEnv .Get (ctx , key , obj ); err != nil {
549+ return false
550+ }
551+ if ! conditions .IsReady (obj ) || obj .Status .Artifact == nil {
552+ return false
553+ }
554+ readyCondition := conditions .Get (obj , meta .ReadyCondition )
555+ return obj .Generation == readyCondition .ObservedGeneration &&
556+ obj .Generation == obj .Status .ObservedGeneration
557+ }, timeout ).Should (BeTrue ())
558+
559+ // Check if the object status is valid.
560+ condns := & status.Conditions {NegativePolarity : helmChartReadyCondition .NegativePolarity }
561+ checker := status .NewChecker (testEnv .Client , condns )
562+ checker .CheckErr (ctx , obj )
563+ },
564+ },
565+ {
566+ name : "Stalling on invalid repository URL" ,
567+ beforeFunc : func (repository * sourcev1.HelmRepository ) {
568+ repository .Spec .URL = "://unsupported" // Invalid URL
569+ },
570+ assertFunc : func (g * WithT , obj * sourcev1.HelmChart ) {
571+ key := client.ObjectKey {Name : obj .Name , Namespace : obj .Namespace }
572+ // Wait for HelmChart to be FetchFailed == true
573+ g .Eventually (func () bool {
574+ if err := testEnv .Get (ctx , key , obj ); err != nil {
575+ return false
576+ }
577+ if ! conditions .IsTrue (obj , sourcev1 .FetchFailedCondition ) {
578+ return false
579+ }
580+ // observedGeneration is -1 because we have no successful reconciliation
581+ return obj .Status .ObservedGeneration == - 1
582+ }, timeout ).Should (BeTrue ())
583+
584+ // Check if the object status is valid.
585+ condns := & status.Conditions {NegativePolarity : helmChartReadyCondition .NegativePolarity }
586+ checker := status .NewChecker (testEnv .Client , condns )
587+ checker .CheckErr (ctx , obj )
588+ },
589+ },
590+ {
591+ name : "Stalling on invalid oci repository URL" ,
592+ beforeFunc : func (repository * sourcev1.HelmRepository ) {
593+ repository .Spec .URL = strings .Replace (repository .Spec .URL , "http" , "oci" , 1 )
594+ },
595+ assertFunc : func (g * WithT , obj * sourcev1.HelmChart ) {
596+ key := client.ObjectKey {Name : obj .Name , Namespace : obj .Namespace }
597+ // Wait for HelmChart to be Ready
598+ g .Eventually (func () bool {
599+ if err := testEnv .Get (ctx , key , obj ); err != nil {
600+ return false
601+ }
602+ if ! conditions .IsTrue (obj , sourcev1 .FetchFailedCondition ) {
603+ return false
604+ }
605+ // observedGeneration is -1 because we have no successful reconciliation
606+ return obj .Status .ObservedGeneration == - 1
607+ }, timeout ).Should (BeTrue ())
608+
609+ // Check if the object status is valid.
610+ condns := & status.Conditions {NegativePolarity : helmChartReadyCondition .NegativePolarity }
611+ checker := status .NewChecker (testEnv .Client , condns )
612+ checker .CheckErr (ctx , obj )
613+ },
614+ },
615+ }
616+
617+ for _ , tt := range tests {
618+ t .Run (tt .name , func (t * testing.T ) {
619+ g := NewWithT (t )
620+
621+ server := testserver .NewHTTPServer (serverFactory .Root ())
622+ server .Start ()
623+ defer server .Stop ()
624+
625+ ns , err := testEnv .CreateNamespace (ctx , "helmchart" )
626+ g .Expect (err ).ToNot (HaveOccurred ())
627+ defer func () { g .Expect (testEnv .Delete (ctx , ns )).To (Succeed ()) }()
628+
629+ repository := sourcev1.HelmRepository {
630+ ObjectMeta : metav1.ObjectMeta {
631+ GenerateName : "helmrepository-" ,
632+ Namespace : ns .Name ,
633+ },
634+ Spec : sourcev1.HelmRepositorySpec {
635+ URL : server .URL (),
636+ },
637+ }
638+
639+ if tt .beforeFunc != nil {
640+ tt .beforeFunc (& repository )
641+ }
642+
643+ g .Expect (testEnv .CreateAndWait (ctx , & repository )).To (Succeed ())
644+
645+ obj := sourcev1.HelmChart {
646+ ObjectMeta : metav1.ObjectMeta {
647+ GenerateName : "helmrepository-reconcile-" ,
648+ Namespace : ns .Name ,
649+ },
650+ Spec : sourcev1.HelmChartSpec {
651+ Chart : chartName ,
652+ Version : chartVersion ,
653+ SourceRef : sourcev1.LocalHelmChartSourceReference {
654+ Kind : sourcev1 .HelmRepositoryKind ,
655+ Name : repository .Name ,
656+ },
657+ },
658+ }
659+ g .Expect (testEnv .Create (ctx , & obj )).To (Succeed ())
660+
661+ if tt .assertFunc != nil {
662+ tt .assertFunc (g , & obj )
663+ }
664+ })
665+ }
666+ }
667+
518668func TestHelmChartReconciler_buildFromHelmRepository (t * testing.T ) {
519669 g := NewWithT (t )
520670
0 commit comments