github.com/argoproj/argo-cd/v2@v2.10.5/test/e2e/helm_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"net/http"
     8  	"os"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/argoproj/gitops-engine/pkg/health"
    13  	. "github.com/argoproj/gitops-engine/pkg/sync/common"
    14  	"github.com/stretchr/testify/assert"
    15  	v1 "k8s.io/api/core/v1"
    16  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    17  	"k8s.io/apimachinery/pkg/types"
    18  
    19  	. "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    20  	"github.com/argoproj/argo-cd/v2/test/e2e/fixture"
    21  	. "github.com/argoproj/argo-cd/v2/test/e2e/fixture"
    22  	. "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app"
    23  	projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project"
    24  	"github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos"
    25  	. "github.com/argoproj/argo-cd/v2/util/errors"
    26  	"github.com/argoproj/argo-cd/v2/util/settings"
    27  )
    28  
    29  func TestHelmHooksAreCreated(t *testing.T) {
    30  	Given(t).
    31  		Path("hook").
    32  		When().
    33  		PatchFile("hook.yaml", `[{"op": "replace", "path": "/metadata/annotations", "value": {"helm.sh/hook": "pre-install"}}]`).
    34  		CreateApp().
    35  		Sync().
    36  		Then().
    37  		Expect(OperationPhaseIs(OperationSucceeded)).
    38  		Expect(HealthIs(health.HealthStatusHealthy)).
    39  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
    40  		Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "hook", Message: "pod/hook created", HookType: HookTypePreSync, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync}))
    41  }
    42  
    43  // make sure we treat Helm weights as a sync wave
    44  func TestHelmHookWeight(t *testing.T) {
    45  	Given(t).
    46  		Path("hook").
    47  		When().
    48  		// this create a weird hook, that runs during sync - but before the pod, and because it'll fail - the pod will never be created
    49  		PatchFile("hook.yaml", `[
    50  	{"op": "replace", "path": "/metadata/annotations", "value": {"argocd.argoproj.io/hook": "Sync", "helm.sh/hook-weight": "-1"}},
    51  	{"op": "replace", "path": "/spec/containers/0/command/0", "value": "false"}
    52  ]`).
    53  		CreateApp().
    54  		IgnoreErrors().
    55  		Sync().
    56  		Then().
    57  		Expect(OperationPhaseIs(OperationFailed)).
    58  		Expect(ResourceResultNumbering(1))
    59  }
    60  
    61  // make sure that execute the delete policy
    62  func TestHelmHookDeletePolicy(t *testing.T) {
    63  	Given(t).
    64  		Path("hook").
    65  		When().
    66  		PatchFile("hook.yaml", `[{"op": "add", "path": "/metadata/annotations/helm.sh~1hook-delete-policy", "value": "hook-succeeded"}]`).
    67  		CreateApp().
    68  		Sync().
    69  		Then().
    70  		Expect(OperationPhaseIs(OperationSucceeded)).
    71  		Expect(ResourceResultNumbering(2)).
    72  		Expect(NotPod(func(p v1.Pod) bool { return p.Name == "hook" }))
    73  }
    74  
    75  func TestDeclarativeHelm(t *testing.T) {
    76  	Given(t).
    77  		Path("helm").
    78  		When().
    79  		Declarative("declarative-apps/app.yaml").
    80  		Sync().
    81  		Then().
    82  		Expect(OperationPhaseIs(OperationSucceeded)).
    83  		Expect(HealthIs(health.HealthStatusHealthy)).
    84  		Expect(SyncStatusIs(SyncStatusCodeSynced))
    85  }
    86  
    87  func TestDeclarativeHelmInvalidValuesFile(t *testing.T) {
    88  	Given(t).
    89  		Path("helm").
    90  		When().
    91  		Declarative("declarative-apps/invalid-helm.yaml").
    92  		Then().
    93  		Expect(HealthIs(health.HealthStatusHealthy)).
    94  		Expect(SyncStatusIs(SyncStatusCodeUnknown)).
    95  		Expect(Condition(ApplicationConditionComparisonError, "does-not-exist-values.yaml: no such file or directory"))
    96  }
    97  
    98  func TestHelmRepo(t *testing.T) {
    99  	SkipOnEnv(t, "HELM")
   100  	Given(t).
   101  		CustomCACertAdded().
   102  		HelmRepoAdded("custom-repo").
   103  		RepoURLType(RepoURLTypeHelm).
   104  		Chart("helm").
   105  		Revision("1.0.0").
   106  		When().
   107  		CreateApp().
   108  		Then().
   109  		When().
   110  		Sync().
   111  		Then().
   112  		Expect(OperationPhaseIs(OperationSucceeded)).
   113  		Expect(HealthIs(health.HealthStatusHealthy)).
   114  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   115  }
   116  
   117  func TestHelmValues(t *testing.T) {
   118  	Given(t).
   119  		Path("helm").
   120  		When().
   121  		AddFile("foo.yml", "").
   122  		CreateApp().
   123  		AppSet("--values", "foo.yml").
   124  		Then().
   125  		And(func(app *Application) {
   126  			assert.Equal(t, []string{"foo.yml"}, app.Spec.GetSource().Helm.ValueFiles)
   127  		})
   128  }
   129  
   130  func TestHelmIgnoreMissingValueFiles(t *testing.T) {
   131  	Given(t).
   132  		Path("helm").
   133  		When().
   134  		Declarative("declarative-apps/invalid-helm.yaml").
   135  		Then().
   136  		And(func(app *Application) {
   137  			assert.Equal(t, []string{"does-not-exist-values.yaml"}, app.Spec.GetSource().Helm.ValueFiles)
   138  			assert.Equal(t, false, app.Spec.GetSource().Helm.IgnoreMissingValueFiles)
   139  		}).
   140  		When().
   141  		AppSet("--ignore-missing-value-files").
   142  		Then().
   143  		And(func(app *Application) {
   144  			assert.Equal(t, true, app.Spec.GetSource().Helm.IgnoreMissingValueFiles)
   145  		}).
   146  		When().
   147  		Sync().
   148  		Then().
   149  		Expect(OperationPhaseIs(OperationSucceeded)).
   150  		Expect(HealthIs(health.HealthStatusHealthy)).
   151  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   152  		When().
   153  		AppUnSet("--ignore-missing-value-files").
   154  		Then().
   155  		And(func(app *Application) {
   156  			assert.Equal(t, false, app.Spec.GetSource().Helm.IgnoreMissingValueFiles)
   157  		}).
   158  		When().
   159  		IgnoreErrors().
   160  		Sync().
   161  		Then().
   162  		Expect(ErrorRegex("Error: open .*does-not-exist-values.yaml: no such file or directory", ""))
   163  }
   164  
   165  func TestHelmValuesMultipleUnset(t *testing.T) {
   166  	Given(t).
   167  		Path("helm").
   168  		When().
   169  		AddFile("foo.yml", "").
   170  		AddFile("baz.yml", "").
   171  		CreateApp().
   172  		AppSet("--values", "foo.yml", "--values", "baz.yml").
   173  		Then().
   174  		And(func(app *Application) {
   175  			assert.NotNil(t, app.Spec.GetSource().Helm)
   176  			assert.Equal(t, []string{"foo.yml", "baz.yml"}, app.Spec.GetSource().Helm.ValueFiles)
   177  		}).
   178  		When().
   179  		AppUnSet("--values", "foo.yml").
   180  		Then().
   181  		And(func(app *Application) {
   182  			assert.NotNil(t, app.Spec.GetSource().Helm)
   183  			assert.Equal(t, []string{"baz.yml"}, app.Spec.GetSource().Helm.ValueFiles)
   184  		}).
   185  		When().
   186  		AppUnSet("--values", "baz.yml").
   187  		Then().
   188  		And(func(app *Application) {
   189  			assert.Nil(t, app.Spec.GetSource().Helm)
   190  		})
   191  }
   192  
   193  func TestHelmValuesLiteralFileLocal(t *testing.T) {
   194  	Given(t).
   195  		Path("helm").
   196  		When().
   197  		CreateApp().
   198  		AppSet("--values-literal-file", "testdata/helm/baz.yaml").
   199  		Then().
   200  		And(func(app *Application) {
   201  			data, err := os.ReadFile("testdata/helm/baz.yaml")
   202  			if err != nil {
   203  				panic(err)
   204  			}
   205  			assert.Equal(t, strings.TrimSuffix(string(data), "\n"), app.Spec.GetSource().Helm.ValuesString())
   206  		}).
   207  		When().
   208  		AppUnSet("--values-literal").
   209  		Then().
   210  		And(func(app *Application) {
   211  			assert.Nil(t, app.Spec.GetSource().Helm)
   212  		})
   213  }
   214  
   215  func TestHelmValuesLiteralFileRemote(t *testing.T) {
   216  	sentinel := "a: b"
   217  	serve := func(c chan<- string) {
   218  		// listen on first available dynamic (unprivileged) port
   219  		listener, err := net.Listen("tcp", ":0")
   220  		if err != nil {
   221  			panic(err)
   222  		}
   223  
   224  		// send back the address so that it can be used
   225  		c <- listener.Addr().String()
   226  		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
   227  			// return the sentinel text at root URL
   228  			fmt.Fprint(w, sentinel)
   229  		})
   230  
   231  		panic(http.Serve(listener, nil))
   232  	}
   233  	c := make(chan string, 1)
   234  
   235  	// run a local webserver to test data retrieval
   236  	go serve(c)
   237  	address := <-c
   238  	t.Logf("Listening at address: %s", address)
   239  
   240  	Given(t).
   241  		Path("helm").
   242  		When().
   243  		CreateApp().
   244  		AppSet("--values-literal-file", "http://"+address).
   245  		Then().
   246  		And(func(app *Application) {
   247  			assert.Equal(t, "a: b", app.Spec.GetSource().Helm.ValuesString())
   248  		}).
   249  		When().
   250  		AppUnSet("--values-literal").
   251  		Then().
   252  		And(func(app *Application) {
   253  			assert.Nil(t, app.Spec.GetSource().Helm)
   254  		})
   255  }
   256  
   257  func TestHelmCrdHook(t *testing.T) {
   258  	SkipOnEnv(t, "HELM")
   259  	Given(t).
   260  		Path("helm-crd").
   261  		When().
   262  		CreateApp().
   263  		Sync().
   264  		Then().
   265  		Expect(OperationPhaseIs(OperationSucceeded)).
   266  		Expect(HealthIs(health.HealthStatusHealthy)).
   267  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   268  		Expect(ResourceResultNumbering(2))
   269  }
   270  
   271  func TestHelmReleaseName(t *testing.T) {
   272  	Given(t).
   273  		Path("helm").
   274  		When().
   275  		CreateApp().
   276  		AppSet("--release-name", "foo").
   277  		Then().
   278  		And(func(app *Application) {
   279  			assert.Equal(t, "foo", app.Spec.GetSource().Helm.ReleaseName)
   280  		})
   281  }
   282  
   283  func TestHelmSet(t *testing.T) {
   284  	Given(t).
   285  		Path("helm").
   286  		When().
   287  		CreateApp().
   288  		AppSet("--helm-set", "foo=bar", "--helm-set", "foo=baz", "--helm-set", "app=$ARGOCD_APP_NAME").
   289  		Then().
   290  		And(func(app *Application) {
   291  			assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz"}, {Name: "app", Value: "$ARGOCD_APP_NAME"}}, app.Spec.GetSource().Helm.Parameters)
   292  		})
   293  }
   294  
   295  func TestHelmSetString(t *testing.T) {
   296  	Given(t).
   297  		Path("helm").
   298  		When().
   299  		CreateApp().
   300  		AppSet("--helm-set-string", "foo=bar", "--helm-set-string", "foo=baz", "--helm-set-string", "app=$ARGOCD_APP_NAME").
   301  		Then().
   302  		And(func(app *Application) {
   303  			assert.Equal(t, []HelmParameter{{Name: "foo", Value: "baz", ForceString: true}, {Name: "app", Value: "$ARGOCD_APP_NAME", ForceString: true}}, app.Spec.GetSource().Helm.Parameters)
   304  		})
   305  }
   306  
   307  func TestHelmSetFile(t *testing.T) {
   308  	Given(t).
   309  		Path("helm").
   310  		When().
   311  		CreateApp().
   312  		AppSet("--helm-set-file", "foo=bar.yaml", "--helm-set-file", "foo=baz.yaml").
   313  		Then().
   314  		And(func(app *Application) {
   315  			assert.Equal(t, []HelmFileParameter{{Name: "foo", Path: "baz.yaml"}}, app.Spec.GetSource().Helm.FileParameters)
   316  		})
   317  }
   318  
   319  // ensure we can use envsubst in "set" variables
   320  func TestHelmSetEnv(t *testing.T) {
   321  	Given(t).
   322  		Path("helm-values").
   323  		When().
   324  		CreateApp().
   325  		AppSet("--helm-set", "foo=$ARGOCD_APP_NAME").
   326  		Sync().
   327  		Then().
   328  		Expect(OperationPhaseIs(OperationSucceeded)).
   329  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   330  		And(func(app *Application) {
   331  			assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
   332  		})
   333  }
   334  
   335  func TestHelmSetStringEnv(t *testing.T) {
   336  	Given(t).
   337  		Path("helm-values").
   338  		When().
   339  		CreateApp().
   340  		AppSet("--helm-set-string", "foo=$ARGOCD_APP_NAME").
   341  		Sync().
   342  		Then().
   343  		Expect(OperationPhaseIs(OperationSucceeded)).
   344  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   345  		And(func(app *Application) {
   346  			assert.Equal(t, Name(), FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map", "-o", "jsonpath={.data.foo}")).(string))
   347  		})
   348  }
   349  
   350  // make sure kube-version gets passed down to resources
   351  func TestKubeVersion(t *testing.T) {
   352  	SkipOnEnv(t, "HELM")
   353  	Given(t).
   354  		Path("helm-kube-version").
   355  		When().
   356  		CreateApp().
   357  		Sync().
   358  		Then().
   359  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   360  		And(func(app *Application) {
   361  			kubeVersion := FailOnErr(Run(".", "kubectl", "-n", DeploymentNamespace(), "get", "cm", "my-map",
   362  				"-o", "jsonpath={.data.kubeVersion}")).(string)
   363  			// Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version
   364  			assert.LessOrEqual(t, GetVersions().ServerVersion.Format("v%s.%s.0"), kubeVersion)
   365  		})
   366  }
   367  
   368  func TestHelmValuesHiddenDirectory(t *testing.T) {
   369  	SkipOnEnv(t, "HELM")
   370  	Given(t).
   371  		Path(".hidden-helm").
   372  		When().
   373  		AddFile("foo.yaml", "").
   374  		CreateApp().
   375  		AppSet("--values", "foo.yaml").
   376  		Sync().
   377  		Then().
   378  		Expect(OperationPhaseIs(OperationSucceeded)).
   379  		Expect(HealthIs(health.HealthStatusHealthy)).
   380  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   381  }
   382  
   383  func TestHelmWithDependencies(t *testing.T) {
   384  	SkipOnEnv(t, "HELM")
   385  	testHelmWithDependencies(t, "helm-with-dependencies", false)
   386  }
   387  
   388  func TestHelmWithMultipleDependencies(t *testing.T) {
   389  	SkipOnEnv(t, "HELM")
   390  
   391  	Given(t).Path("helm-with-multiple-dependencies").
   392  		CustomCACertAdded().
   393  		// these are slow tests
   394  		Timeout(30).
   395  		HelmHTTPSCredentialsUserPassAdded().
   396  		HelmPassCredentials().
   397  		When().
   398  		CreateApp().
   399  		Sync().
   400  		Then().
   401  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   402  }
   403  
   404  func TestHelmDependenciesPermissionDenied(t *testing.T) {
   405  	SkipOnEnv(t, "HELM")
   406  
   407  	projName := "argo-helm-project-denied"
   408  	projectFixture.
   409  		Given(t).
   410  		Name(projName).
   411  		Destination("*,*").
   412  		When().
   413  		Create().
   414  		AddSource(RepoURL(RepoURLTypeFile))
   415  
   416  	expectedErr := fmt.Sprintf("helm repos localhost:5000/myrepo are not permitted in project '%s'", projName)
   417  	GivenWithSameState(t).
   418  		Project(projName).
   419  		Path("helm-oci-with-dependencies").
   420  		CustomCACertAdded().
   421  		HelmHTTPSCredentialsUserPassAdded().
   422  		HelmPassCredentials().
   423  		When().
   424  		IgnoreErrors().
   425  		CreateApp().
   426  		Then().
   427  		Expect(Error("", expectedErr))
   428  
   429  	expectedErr = fmt.Sprintf("helm repos https://localhost:9443/argo-e2e/testdata.git/helm-repo/local, https://localhost:9443/argo-e2e/testdata.git/helm-repo/local2 are not permitted in project '%s'", projName)
   430  	GivenWithSameState(t).
   431  		Project(projName).
   432  		Path("helm-with-multiple-dependencies-permission-denied").
   433  		CustomCACertAdded().
   434  		HelmHTTPSCredentialsUserPassAdded().
   435  		HelmPassCredentials().
   436  		When().
   437  		IgnoreErrors().
   438  		CreateApp().
   439  		Then().
   440  		Expect(Error("", expectedErr))
   441  }
   442  
   443  func TestHelmWithDependenciesLegacyRepo(t *testing.T) {
   444  	SkipOnEnv(t, "HELM")
   445  	testHelmWithDependencies(t, "helm-with-dependencies", true)
   446  }
   447  
   448  func testHelmWithDependencies(t *testing.T, chartPath string, legacyRepo bool) {
   449  	ctx := Given(t).
   450  		CustomCACertAdded().
   451  		// these are slow tests
   452  		Timeout(30).
   453  		HelmPassCredentials()
   454  	if legacyRepo {
   455  		ctx.And(func() {
   456  			FailOnErr(fixture.Run("", "kubectl", "create", "secret", "generic", "helm-repo",
   457  				"-n", fixture.TestNamespace(),
   458  				fmt.Sprintf("--from-file=certSecret=%s", repos.CertPath),
   459  				fmt.Sprintf("--from-file=keySecret=%s", repos.CertKeyPath),
   460  				fmt.Sprintf("--from-literal=username=%s", GitUsername),
   461  				fmt.Sprintf("--from-literal=password=%s", GitPassword),
   462  			))
   463  			FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Patch(context.Background(),
   464  				"helm-repo", types.MergePatchType, []byte(`{"metadata": { "labels": {"e2e.argoproj.io": "true"} }}`), metav1.PatchOptions{}))
   465  
   466  			fixture.SetHelmRepos(settings.HelmRepoCredentials{
   467  				URL:            RepoURL(RepoURLTypeHelm),
   468  				Name:           "custom-repo",
   469  				KeySecret:      &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "keySecret"},
   470  				CertSecret:     &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "certSecret"},
   471  				UsernameSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "username"},
   472  				PasswordSecret: &v1.SecretKeySelector{LocalObjectReference: v1.LocalObjectReference{Name: "helm-repo"}, Key: "password"},
   473  			})
   474  		})
   475  	} else {
   476  		ctx = ctx.HelmRepoAdded("custom-repo")
   477  	}
   478  
   479  	helmVer := ""
   480  
   481  	ctx.Path(chartPath).
   482  		When().
   483  		CreateApp("--helm-version", helmVer).
   484  		Sync().
   485  		Then().
   486  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   487  }
   488  
   489  func TestHelm3CRD(t *testing.T) {
   490  	SkipOnEnv(t, "HELM")
   491  	Given(t).
   492  		Path("helm3-crd").
   493  		When().
   494  		CreateApp().
   495  		Sync().
   496  		Then().
   497  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   498  		Expect(ResourceSyncStatusIs("CustomResourceDefinition", "crontabs.stable.example.com", SyncStatusCodeSynced))
   499  }
   500  
   501  func TestHelmRepoDiffLocal(t *testing.T) {
   502  	SkipOnEnv(t, "HELM")
   503  	helmTmp := t.TempDir()
   504  	Given(t).
   505  		CustomCACertAdded().
   506  		HelmRepoAdded("custom-repo").
   507  		RepoURLType(RepoURLTypeHelm).
   508  		Chart("helm").
   509  		Revision("1.0.0").
   510  		When().
   511  		CreateApp().
   512  		Then().
   513  		When().
   514  		Sync().
   515  		Then().
   516  		Expect(OperationPhaseIs(OperationSucceeded)).
   517  		Expect(HealthIs(health.HealthStatusHealthy)).
   518  		Expect(SyncStatusIs(SyncStatusCodeSynced)).
   519  		And(func(app *Application) {
   520  			_ = os.Setenv("XDG_CONFIG_HOME", helmTmp)
   521  			FailOnErr(Run("", "helm", "repo", "add", "custom-repo", GetEnvWithDefault("ARGOCD_E2E_HELM_SERVICE", RepoURL(RepoURLTypeHelm)),
   522  				"--username", GitUsername,
   523  				"--password", GitPassword,
   524  				"--cert-file", "../fixture/certs/argocd-test-client.crt",
   525  				"--key-file", "../fixture/certs/argocd-test-client.key",
   526  				"--ca-file", "../fixture/certs/argocd-test-ca.crt",
   527  			))
   528  			diffOutput := FailOnErr(RunCli("app", "diff", app.Name, "--local", "testdata/helm")).(string)
   529  			assert.Empty(t, diffOutput)
   530  		})
   531  }
   532  
   533  func TestHelmOCIRegistry(t *testing.T) {
   534  	Given(t).
   535  		PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0").
   536  		HelmOCIRepoAdded("myrepo").
   537  		RepoURLType(RepoURLTypeHelmOCI).
   538  		Chart("helm-values").
   539  		Revision("1.0.0").
   540  		When().
   541  		CreateApp().
   542  		Then().
   543  		When().
   544  		Sync().
   545  		Then().
   546  		Expect(OperationPhaseIs(OperationSucceeded)).
   547  		Expect(HealthIs(health.HealthStatusHealthy)).
   548  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   549  }
   550  
   551  func TestGitWithHelmOCIRegistryDependencies(t *testing.T) {
   552  	Given(t).
   553  		PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0").
   554  		HelmOCIRepoAdded("myrepo").
   555  		Path("helm-oci-with-dependencies").
   556  		When().
   557  		CreateApp().
   558  		Then().
   559  		When().
   560  		Sync().
   561  		Then().
   562  		Expect(OperationPhaseIs(OperationSucceeded)).
   563  		Expect(HealthIs(health.HealthStatusHealthy)).
   564  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   565  }
   566  
   567  func TestHelmOCIRegistryWithDependencies(t *testing.T) {
   568  	Given(t).
   569  		PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0").
   570  		PushChartToOCIRegistry("helm-oci-with-dependencies", "helm-oci-with-dependencies", "1.0.0").
   571  		HelmOCIRepoAdded("myrepo").
   572  		RepoURLType(RepoURLTypeHelmOCI).
   573  		Chart("helm-oci-with-dependencies").
   574  		Revision("1.0.0").
   575  		When().
   576  		CreateApp().
   577  		Then().
   578  		When().
   579  		Sync().
   580  		Then().
   581  		Expect(OperationPhaseIs(OperationSucceeded)).
   582  		Expect(HealthIs(health.HealthStatusHealthy)).
   583  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   584  }
   585  
   586  func TestTemplatesGitWithHelmOCIDependencies(t *testing.T) {
   587  	Given(t).
   588  		PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0").
   589  		HelmoOCICredentialsWithoutUserPassAdded().
   590  		Path("helm-oci-with-dependencies").
   591  		When().
   592  		CreateApp().
   593  		Then().
   594  		When().
   595  		Sync().
   596  		Then().
   597  		Expect(OperationPhaseIs(OperationSucceeded)).
   598  		Expect(HealthIs(health.HealthStatusHealthy)).
   599  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   600  }
   601  
   602  func TestTemplatesHelmOCIWithDependencies(t *testing.T) {
   603  	Given(t).
   604  		PushChartToOCIRegistry("helm-values", "helm-values", "1.0.0").
   605  		PushChartToOCIRegistry("helm-oci-with-dependencies", "helm-oci-with-dependencies", "1.0.0").
   606  		HelmoOCICredentialsWithoutUserPassAdded().
   607  		RepoURLType(RepoURLTypeHelmOCI).
   608  		Chart("helm-oci-with-dependencies").
   609  		Revision("1.0.0").
   610  		When().
   611  		CreateApp().
   612  		Then().
   613  		When().
   614  		Sync().
   615  		Then().
   616  		Expect(OperationPhaseIs(OperationSucceeded)).
   617  		Expect(HealthIs(health.HealthStatusHealthy)).
   618  		Expect(SyncStatusIs(SyncStatusCodeSynced))
   619  }