package loader_test import ( "context" "path/filepath" "testing" "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/config" "github.com/databricks/cli/bundle/config/loader" "github.com/databricks/cli/libs/diag" "github.com/databricks/cli/libs/dyn" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestProcessInclude(t *testing.T) { b := &bundle.Bundle{ BundleRootPath: "testdata/basic", Config: config.Root{ Workspace: config.Workspace{ Host: "foo", }, }, } m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, "host.yml"), "host.yml") assert.Equal(t, "ProcessInclude(host.yml)", m.Name()) // Assert the host value prior to applying the mutator assert.Equal(t, "foo", b.Config.Workspace.Host) // Apply the mutator and assert that the host value has been updated diags := bundle.Apply(context.Background(), b, m) require.NoError(t, diags.Error()) assert.Equal(t, "bar", b.Config.Workspace.Host) } func TestProcessIncludeFormatMatch(t *testing.T) { for _, fileName := range []string{ "one_job.job.yml", "one_pipeline.pipeline.yaml", "two_job.yml", "job_and_pipeline.yml", "multiple_resources.yml", } { t.Run(fileName, func(t *testing.T) { b := &bundle.Bundle{ BundleRootPath: "testdata/format_match", Config: config.Root{ Bundle: config.Bundle{ Name: "format_test", }, }, } m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, fileName), fileName) diags := bundle.Apply(context.Background(), b, m) assert.Empty(t, diags) }) } } func TestProcessIncludeFormatNotMatch(t *testing.T) { for fileName, expectedDiags := range map[string]diag.Diagnostics{ "single_job.pipeline.yaml": { { Severity: diag.Recommendation, Summary: "define a single pipeline in a file with the .pipeline.yaml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/single_job.pipeline.yaml"), Line: 11, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/single_job.pipeline.yaml"), Line: 4, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.jobs.job1"), dyn.MustPathFromString("targets.target1.resources.jobs.job1"), }, }, }, "job_and_pipeline.job.yml": { { Severity: diag.Recommendation, Summary: "define a single job in a file with the .job.yml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.job.yml"), Line: 11, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.job.yml"), Line: 4, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.pipelines.pipeline1"), dyn.MustPathFromString("targets.target1.resources.jobs.job1"), }, }, }, "job_and_pipeline.experiment.yml": { { Severity: diag.Recommendation, Summary: "define a single experiment in a file with the .experiment.yml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.experiment.yml"), Line: 11, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/job_and_pipeline.experiment.yml"), Line: 4, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.pipelines.pipeline1"), dyn.MustPathFromString("targets.target1.resources.jobs.job1"), }, }, }, "two_jobs.job.yml": { { Severity: diag.Recommendation, Summary: "define a single job in a file with the .job.yml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/two_jobs.job.yml"), Line: 4, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/two_jobs.job.yml"), Line: 7, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.jobs.job1"), dyn.MustPathFromString("resources.jobs.job2"), }, }, }, "second_job_in_target.job.yml": { { Severity: diag.Recommendation, Summary: "define a single job in a file with the .job.yml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/second_job_in_target.job.yml"), Line: 11, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/second_job_in_target.job.yml"), Line: 4, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.jobs.job1"), dyn.MustPathFromString("targets.target1.resources.jobs.job2"), }, }, }, "two_jobs_in_target.job.yml": { { Severity: diag.Recommendation, Summary: "define a single job in a file with the .job.yml extension.", Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/two_jobs_in_target.job.yml"), Line: 6, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/two_jobs_in_target.job.yml"), Line: 8, Column: 11}, }, Paths: []dyn.Path{ dyn.MustPathFromString("targets.target1.resources.jobs.job1"), dyn.MustPathFromString("targets.target1.resources.jobs.job2"), }, }, }, "multiple_resources.model_serving_endpoint.yml": { { Severity: diag.Recommendation, Summary: "define a single model serving endpoint in a file with the .model_serving_endpoint.yml extension.", Detail: `The following resources are defined or configured in this file: - experiment1 (experiment) - job1 (job) - job2 (job) - job3 (job) - model1 (model) - model_serving_endpoint1 (model_serving_endpoint) - pipeline1 (pipeline) - pipeline2 (pipeline) - quality_monitor1 (quality_monitor) - registered_model1 (registered_model) - schema1 (schema) `, Locations: []dyn.Location{ {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 12, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 14, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 18, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 22, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 24, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 28, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 35, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 39, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 43, Column: 11}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 4, Column: 7}, {File: filepath.FromSlash("testdata/format_not_match/multiple_resources.model_serving_endpoint.yml"), Line: 8, Column: 7}, }, Paths: []dyn.Path{ dyn.MustPathFromString("resources.experiments.experiment1"), dyn.MustPathFromString("resources.jobs.job1"), dyn.MustPathFromString("resources.jobs.job2"), dyn.MustPathFromString("resources.model_serving_endpoints.model_serving_endpoint1"), dyn.MustPathFromString("resources.models.model1"), dyn.MustPathFromString("resources.pipelines.pipeline1"), dyn.MustPathFromString("resources.pipelines.pipeline2"), dyn.MustPathFromString("resources.schemas.schema1"), dyn.MustPathFromString("targets.target1.resources.jobs.job3"), dyn.MustPathFromString("targets.target1.resources.quality_monitors.quality_monitor1"), dyn.MustPathFromString("targets.target1.resources.registered_models.registered_model1"), }, }, }, } { t.Run(fileName, func(t *testing.T) { b := &bundle.Bundle{ BundleRootPath: "testdata/format_not_match", Config: config.Root{ Bundle: config.Bundle{ Name: "format_test", }, }, } m := loader.ProcessInclude(filepath.Join(b.BundleRootPath, fileName), fileName) diags := bundle.Apply(context.Background(), b, m) require.Len(t, diags, 1) assert.Equal(t, expectedDiags, diags) }) } }