From 0268dc0755d81aca866449b8369c8b50e168750c Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 9 Jul 2025 14:37:46 +0200 Subject: [PATCH 1/5] Sort job tasks by key --- .../artifacts/whl_dynamic/out.test.toml | 2 +- .../bundle/artifacts/whl_dynamic/test.toml | 2 - .../out.test.toml | 2 +- .../whl_prebuilt_outside_dynamic/test.toml | 1 - .../bundle/paths/fallback/output.job.json | 40 +++++------ .../bundle/paths/nominal/output.job.json | 72 +++++++++---------- .../integration_classic/out.validate.dev.json | 36 +++++----- .../integration_classic/output.txt | 4 +- .../experimental-jobs-as-code/output.txt | 14 ++-- libs/dyn/merge/elements_by_key.go | 12 +++- 10 files changed, 96 insertions(+), 89 deletions(-) diff --git a/acceptance/bundle/artifacts/whl_dynamic/out.test.toml b/acceptance/bundle/artifacts/whl_dynamic/out.test.toml index 387f29e8bb3..8f3575be7b5 100644 --- a/acceptance/bundle/artifacts/whl_dynamic/out.test.toml +++ b/acceptance/bundle/artifacts/whl_dynamic/out.test.toml @@ -2,4 +2,4 @@ Local = true Cloud = false [EnvMatrix] - DATABRICKS_CLI_DEPLOYMENT = ["terraform"] + DATABRICKS_CLI_DEPLOYMENT = ["terraform", "direct-exp"] diff --git a/acceptance/bundle/artifacts/whl_dynamic/test.toml b/acceptance/bundle/artifacts/whl_dynamic/test.toml index 9ba61b97a8c..571512c6ab6 100644 --- a/acceptance/bundle/artifacts/whl_dynamic/test.toml +++ b/acceptance/bundle/artifacts/whl_dynamic/test.toml @@ -1,5 +1,3 @@ -EnvMatrix.DATABRICKS_CLI_DEPLOYMENT = ["terraform"] # need to sort tasks by key like terraform does - [[Repls]] Old = '\\\\' New = '/' diff --git a/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/out.test.toml b/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/out.test.toml index 387f29e8bb3..8f3575be7b5 100644 --- a/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/out.test.toml +++ b/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/out.test.toml @@ -2,4 +2,4 @@ Local = true Cloud = false [EnvMatrix] - DATABRICKS_CLI_DEPLOYMENT = ["terraform"] + DATABRICKS_CLI_DEPLOYMENT = ["terraform", "direct-exp"] diff --git a/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/test.toml b/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/test.toml index 9bbeae78241..0724077f7ef 100644 --- a/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/test.toml +++ b/acceptance/bundle/artifacts/whl_prebuilt_outside_dynamic/test.toml @@ -1,2 +1 @@ BundleConfig.default_name = "" -EnvMatrix.DATABRICKS_CLI_DEPLOYMENT = ["terraform"] # need to sort tasks by key diff --git a/acceptance/bundle/paths/fallback/output.job.json b/acceptance/bundle/paths/fallback/output.job.json index ac79e0cf6d8..5d8eb978bef 100644 --- a/acceptance/bundle/paths/fallback/output.job.json +++ b/acceptance/bundle/paths/fallback/output.job.json @@ -1,18 +1,4 @@ [ - { - "job_cluster_key": "default", - "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/notebook" - }, - "task_key": "notebook_example" - }, - { - "job_cluster_key": "default", - "spark_python_task": { - "python_file": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/file.py" - }, - "task_key": "spark_python_example" - }, { "dbt_task": { "commands": [ @@ -26,13 +12,10 @@ }, { "job_cluster_key": "default", - "sql_task": { - "file": { - "path": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/sql.sql" - }, - "warehouse_id": "cafef00d" + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/notebook" }, - "task_key": "sql_example" + "task_key": "notebook_example" }, { "job_cluster_key": "default", @@ -63,5 +46,22 @@ "main_class_name": "com.example.Main" }, "task_key": "spark_jar_example" + }, + { + "job_cluster_key": "default", + "spark_python_task": { + "python_file": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/file.py" + }, + "task_key": "spark_python_example" + }, + { + "job_cluster_key": "default", + "sql_task": { + "file": { + "path": "/Workspace/Users/[USERNAME]/.bundle/fallback/development/files/src/sql.sql" + }, + "warehouse_id": "cafef00d" + }, + "task_key": "sql_example" } ] diff --git a/acceptance/bundle/paths/nominal/output.job.json b/acceptance/bundle/paths/nominal/output.job.json index 26d19d77c57..b34dbcfa8eb 100644 --- a/acceptance/bundle/paths/nominal/output.job.json +++ b/acceptance/bundle/paths/nominal/output.job.json @@ -1,18 +1,4 @@ [ - { - "job_cluster_key": "default", - "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/notebook" - }, - "task_key": "notebook_example" - }, - { - "job_cluster_key": "default", - "spark_python_task": { - "python_file": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/file.py" - }, - "task_key": "spark_python_example" - }, { "dbt_task": { "commands": [ @@ -25,14 +11,33 @@ "task_key": "dbt_example" }, { + "for_each_task": { + "task": { + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/notebook" + } + } + }, "job_cluster_key": "default", - "sql_task": { - "file": { - "path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/sql.sql" - }, - "warehouse_id": "cafef00d" + "task_key": "for_each_notebook_example" + }, + { + "for_each_task": { + "task": { + "job_cluster_key": "default", + "spark_python_task": { + "python_file": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/file.py" + } + } }, - "task_key": "sql_example" + "task_key": "for_each_spark_python_example" + }, + { + "job_cluster_key": "default", + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/notebook" + }, + "task_key": "notebook_example" }, { "job_cluster_key": "default", @@ -65,25 +70,20 @@ "task_key": "spark_jar_example" }, { - "for_each_task": { - "task": { - "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/notebook" - } - } - }, "job_cluster_key": "default", - "task_key": "for_each_notebook_example" + "spark_python_task": { + "python_file": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/file.py" + }, + "task_key": "spark_python_example" }, { - "for_each_task": { - "task": { - "job_cluster_key": "default", - "spark_python_task": { - "python_file": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/file.py" - } - } + "job_cluster_key": "default", + "sql_task": { + "file": { + "path": "/Workspace/Users/[USERNAME]/.bundle/nominal/development/files/src/sql.sql" + }, + "warehouse_id": "cafef00d" }, - "task_key": "for_each_spark_python_example" + "task_key": "sql_example" } ] diff --git a/acceptance/bundle/templates/default-python/integration_classic/out.validate.dev.json b/acceptance/bundle/templates/default-python/integration_classic/out.validate.dev.json index 0e40f4e36bf..982420eb1f2 100644 --- a/acceptance/bundle/templates/default-python/integration_classic/out.validate.dev.json +++ b/acceptance/bundle/templates/default-python/integration_classic/out.validate.dev.json @@ -75,24 +75,6 @@ "dev": "[USERNAME]" }, "tasks": [ - { - "job_cluster_key": "job_cluster", - "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev/files/src/notebook" - }, - "task_key": "notebook_task" - }, - { - "depends_on": [ - { - "task_key": "notebook_task" - } - ], - "pipeline_task": { - "pipeline_id": "${resources.pipelines.project_name_[UNIQUE_NAME]_pipeline.id}" - }, - "task_key": "refresh_pipeline" - }, { "depends_on": [ { @@ -110,6 +92,24 @@ "package_name": "project_name_[UNIQUE_NAME]" }, "task_key": "main_task" + }, + { + "job_cluster_key": "job_cluster", + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev/files/src/notebook" + }, + "task_key": "notebook_task" + }, + { + "depends_on": [ + { + "task_key": "notebook_task" + } + ], + "pipeline_task": { + "pipeline_id": "${resources.pipelines.project_name_[UNIQUE_NAME]_pipeline.id}" + }, + "task_key": "refresh_pipeline" } ], "trigger": { diff --git a/acceptance/bundle/templates/default-python/integration_classic/output.txt b/acceptance/bundle/templates/default-python/integration_classic/output.txt index 19c26420761..7b707167c23 100644 --- a/acceptance/bundle/templates/default-python/integration_classic/output.txt +++ b/acceptance/bundle/templates/default-python/integration_classic/output.txt @@ -177,7 +177,7 @@ Validation OK! - "dev": "[USERNAME]" }, "tasks": [ -@@ -79,5 +66,5 @@ +@@ -97,5 +84,5 @@ "job_cluster_key": "job_cluster", "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev/files/src/notebook" @@ -335,7 +335,7 @@ Resources: - "dev": "[USERNAME]" }, "tasks": [ -@@ -80,5 +67,5 @@ +@@ -98,5 +85,5 @@ "job_cluster_key": "job_cluster", "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/project_name_[UNIQUE_NAME]/dev/files/src/notebook" diff --git a/acceptance/bundle/templates/experimental-jobs-as-code/output.txt b/acceptance/bundle/templates/experimental-jobs-as-code/output.txt index 8b1694068c4..3f8e65f555d 100644 --- a/acceptance/bundle/templates/experimental-jobs-as-code/output.txt +++ b/acceptance/bundle/templates/experimental-jobs-as-code/output.txt @@ -46,13 +46,6 @@ Warning: Ignoring Databricks CLI version constraint for development build. Requi "dev": "[USERNAME]" }, "tasks": [ - { - "job_cluster_key": "job_cluster", - "notebook_task": { - "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/my_jobs_as_code/dev/files/src/notebook" - }, - "task_key": "notebook_task" - }, { "depends_on": [ { @@ -70,6 +63,13 @@ Warning: Ignoring Databricks CLI version constraint for development build. Requi "package_name": "my_jobs_as_code" }, "task_key": "main_task" + }, + { + "job_cluster_key": "job_cluster", + "notebook_task": { + "notebook_path": "/Workspace/Users/[USERNAME]/.bundle/my_jobs_as_code/dev/files/src/notebook" + }, + "task_key": "notebook_task" } ], "trigger": { diff --git a/libs/dyn/merge/elements_by_key.go b/libs/dyn/merge/elements_by_key.go index df393003ace..5297f815fd6 100644 --- a/libs/dyn/merge/elements_by_key.go +++ b/libs/dyn/merge/elements_by_key.go @@ -1,6 +1,10 @@ package merge -import "github.com/databricks/cli/libs/dyn" +import ( + "sort" + + "github.com/databricks/cli/libs/dyn" +) type elementsByKey struct { key string @@ -42,6 +46,12 @@ func (e elementsByKey) doMap(_ dyn.Path, v dyn.Value, mergeFunc func(a, b dyn.Va seen[key] = nv } + // Sorting since it'll be sorted by TF anyway + // https://github.com/databricks/terraform-provider-databricks/blob/0a932c2/jobs/resource_job.go#L343 + // However, if we don't sort we have a difference between direct and TF and between configs in + // "bundle validate" and configs sent to backend. + sort.Strings(keys) + // Gather resulting elements in natural order. out := make([]dyn.Value, 0, len(keys)) for _, key := range keys { From 4f8fa75627bd6e015820c94988fcbc5aaf8aa2a5 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 9 Jul 2025 14:54:55 +0200 Subject: [PATCH 2/5] fix unit test --- libs/dyn/merge/elements_by_key_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libs/dyn/merge/elements_by_key_test.go b/libs/dyn/merge/elements_by_key_test.go index 09efece0746..9befa7b07ca 100644 --- a/libs/dyn/merge/elements_by_key_test.go +++ b/libs/dyn/merge/elements_by_key_test.go @@ -11,14 +11,14 @@ import ( func TestElementByKey(t *testing.T) { vin := dyn.V([]dyn.Value{ - dyn.V(map[string]dyn.Value{ - "key": dyn.V("foo"), - "value": dyn.V(42), - }), dyn.V(map[string]dyn.Value{ "key": dyn.V("bar"), "value": dyn.V(43), }), + dyn.V(map[string]dyn.Value{ + "key": dyn.V("foo"), + "value": dyn.V(42), + }), dyn.V(map[string]dyn.Value{ // Use upper case key to test that the resulting element has its // key field assigned to the output of the key function. @@ -36,14 +36,14 @@ func TestElementByKey(t *testing.T) { require.NoError(t, err) assert.Len(t, vout.MustSequence(), 2) assert.Equal(t, - vout.Index(0).AsAny(), + vout.Index(1).AsAny(), map[string]any{ "key": "foo", "value": 44, }, ) assert.Equal(t, - vout.Index(1).AsAny(), + vout.Index(0).AsAny(), map[string]any{ "key": "bar", "value": 43, @@ -53,14 +53,14 @@ func TestElementByKey(t *testing.T) { func TestElementByKeyWithOverride(t *testing.T) { vin := dyn.V([]dyn.Value{ - dyn.V(map[string]dyn.Value{ - "key": dyn.V("foo"), - "value": dyn.V(42), - }), dyn.V(map[string]dyn.Value{ "key": dyn.V("bar"), "value": dyn.V(43), }), + dyn.V(map[string]dyn.Value{ + "key": dyn.V("foo"), + "value": dyn.V(42), + }), dyn.V(map[string]dyn.Value{ "key": dyn.V("foo"), "othervalue": dyn.V(44), @@ -75,14 +75,14 @@ func TestElementByKeyWithOverride(t *testing.T) { require.NoError(t, err) assert.Len(t, vout.MustSequence(), 2) assert.Equal(t, - vout.Index(0).AsAny(), + vout.Index(1).AsAny(), map[string]any{ "key": "foo", "othervalue": 44, }, ) assert.Equal(t, - vout.Index(1).AsAny(), + vout.Index(0).AsAny(), map[string]any{ "key": "bar", "value": 43, From 076cc7d5bee7de5242b515619e2f87f20d74ece4 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 9 Jul 2025 15:01:33 +0200 Subject: [PATCH 3/5] only sort job tasks --- .../resourcemutator/merge_job_tasks.go | 6 +++++- libs/dyn/merge/elements_by_key.go | 21 +++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/bundle/config/mutator/resourcemutator/merge_job_tasks.go b/bundle/config/mutator/resourcemutator/merge_job_tasks.go index f6a038fd835..b85a863d80f 100644 --- a/bundle/config/mutator/resourcemutator/merge_job_tasks.go +++ b/bundle/config/mutator/resourcemutator/merge_job_tasks.go @@ -37,7 +37,11 @@ func (m *mergeJobTasks) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagno } return dyn.Map(v, "resources.jobs", dyn.Foreach(func(_ dyn.Path, job dyn.Value) (dyn.Value, error) { - return dyn.Map(job, "tasks", merge.ElementsByKey("task_key", m.taskKeyString)) + // Sorting keys here since it'll be sorted by TF anyway + // https://github.com/databricks/terraform-provider-databricks/blob/0a932c2/jobs/resource_job.go#L343 + // However, if we don't sort we have a difference between direct and TF and between configs in + // "bundle validate" and configs sent to backend. + return dyn.Map(job, "tasks", merge.ElementsBySortedKey("task_key", m.taskKeyString)) })) }) diff --git a/libs/dyn/merge/elements_by_key.go b/libs/dyn/merge/elements_by_key.go index 5297f815fd6..da8cca6e010 100644 --- a/libs/dyn/merge/elements_by_key.go +++ b/libs/dyn/merge/elements_by_key.go @@ -7,8 +7,9 @@ import ( ) type elementsByKey struct { - key string - keyFunc func(dyn.Value) string + key string + keyFunc func(dyn.Value) string + sortKeys bool } func (e elementsByKey) doMap(_ dyn.Path, v dyn.Value, mergeFunc func(a, b dyn.Value) (dyn.Value, error)) (dyn.Value, error) { @@ -46,11 +47,9 @@ func (e elementsByKey) doMap(_ dyn.Path, v dyn.Value, mergeFunc func(a, b dyn.Va seen[key] = nv } - // Sorting since it'll be sorted by TF anyway - // https://github.com/databricks/terraform-provider-databricks/blob/0a932c2/jobs/resource_job.go#L343 - // However, if we don't sort we have a difference between direct and TF and between configs in - // "bundle validate" and configs sent to backend. - sort.Strings(keys) + if e.sortKeys { + sort.Strings(keys) + } // Gather resulting elements in natural order. out := make([]dyn.Value, 0, len(keys)) @@ -93,9 +92,13 @@ func (e elementsByKey) MapWithOverride(p dyn.Path, v dyn.Value) (dyn.Value, erro // a parameter. The resulting elements get their key field overwritten // with the value as returned by the key function. func ElementsByKey(key string, keyFunc func(dyn.Value) string) dyn.MapFunc { - return elementsByKey{key, keyFunc}.Map + return elementsByKey{key, keyFunc, false}.Map +} + +func ElementsBySortedKey(key string, keyFunc func(dyn.Value) string) dyn.MapFunc { + return elementsByKey{key, keyFunc, true}.Map } func ElementsByKeyWithOverride(key string, keyFunc func(dyn.Value) string) dyn.MapFunc { - return elementsByKey{key, keyFunc}.MapWithOverride + return elementsByKey{key, keyFunc, false}.MapWithOverride } From c3cd56e2d1984ed098a1655075d87ff6df66564e Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 9 Jul 2025 15:01:45 +0200 Subject: [PATCH 4/5] Revert "fix unit test" This reverts commit bac3c8b30f53bb66d42d7813ebd5c81cf9872a9d. --- libs/dyn/merge/elements_by_key_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libs/dyn/merge/elements_by_key_test.go b/libs/dyn/merge/elements_by_key_test.go index 9befa7b07ca..09efece0746 100644 --- a/libs/dyn/merge/elements_by_key_test.go +++ b/libs/dyn/merge/elements_by_key_test.go @@ -11,14 +11,14 @@ import ( func TestElementByKey(t *testing.T) { vin := dyn.V([]dyn.Value{ - dyn.V(map[string]dyn.Value{ - "key": dyn.V("bar"), - "value": dyn.V(43), - }), dyn.V(map[string]dyn.Value{ "key": dyn.V("foo"), "value": dyn.V(42), }), + dyn.V(map[string]dyn.Value{ + "key": dyn.V("bar"), + "value": dyn.V(43), + }), dyn.V(map[string]dyn.Value{ // Use upper case key to test that the resulting element has its // key field assigned to the output of the key function. @@ -36,14 +36,14 @@ func TestElementByKey(t *testing.T) { require.NoError(t, err) assert.Len(t, vout.MustSequence(), 2) assert.Equal(t, - vout.Index(1).AsAny(), + vout.Index(0).AsAny(), map[string]any{ "key": "foo", "value": 44, }, ) assert.Equal(t, - vout.Index(0).AsAny(), + vout.Index(1).AsAny(), map[string]any{ "key": "bar", "value": 43, @@ -53,14 +53,14 @@ func TestElementByKey(t *testing.T) { func TestElementByKeyWithOverride(t *testing.T) { vin := dyn.V([]dyn.Value{ - dyn.V(map[string]dyn.Value{ - "key": dyn.V("bar"), - "value": dyn.V(43), - }), dyn.V(map[string]dyn.Value{ "key": dyn.V("foo"), "value": dyn.V(42), }), + dyn.V(map[string]dyn.Value{ + "key": dyn.V("bar"), + "value": dyn.V(43), + }), dyn.V(map[string]dyn.Value{ "key": dyn.V("foo"), "othervalue": dyn.V(44), @@ -75,14 +75,14 @@ func TestElementByKeyWithOverride(t *testing.T) { require.NoError(t, err) assert.Len(t, vout.MustSequence(), 2) assert.Equal(t, - vout.Index(1).AsAny(), + vout.Index(0).AsAny(), map[string]any{ "key": "foo", "othervalue": 44, }, ) assert.Equal(t, - vout.Index(0).AsAny(), + vout.Index(1).AsAny(), map[string]any{ "key": "bar", "value": 43, From 7523673032e9589b696a90b561d0d3ae1e295fbe Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 9 Jul 2025 17:02:08 +0200 Subject: [PATCH 5/5] update changelog and tasks --- NEXT_CHANGELOG.md | 1 + .../mutator/resourcemutator/merge_job_tasks_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index fcb69af8ccc..47589522d5f 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -14,5 +14,6 @@ ### Bundles * Fix default search location for whl artifacts ([#3184](https://github.com/databricks/cli/pull/3184)). This was a regression introduced in 0.255.0. +* The job tasks are now sorted by task key in "bundle validate/summary" output ([#3212](https://github.com/databricks/cli/pull/3212)) ### API Changes diff --git a/bundle/config/mutator/resourcemutator/merge_job_tasks_test.go b/bundle/config/mutator/resourcemutator/merge_job_tasks_test.go index 6700d04d394..b52f927523d 100644 --- a/bundle/config/mutator/resourcemutator/merge_job_tasks_test.go +++ b/bundle/config/mutator/resourcemutator/merge_job_tasks_test.go @@ -65,11 +65,11 @@ func TestMergeJobTasks(t *testing.T) { j := b.Config.Resources.Jobs["foo"] assert.Len(t, j.Tasks, 2) - assert.Equal(t, "foo", j.Tasks[0].TaskKey) - assert.Equal(t, "bar", j.Tasks[1].TaskKey) + assert.Equal(t, "foo", j.Tasks[1].TaskKey) + assert.Equal(t, "bar", j.Tasks[0].TaskKey) // This task was merged with a subsequent one. - task0 := j.Tasks[0] + task0 := j.Tasks[1] cluster := task0.NewCluster assert.Equal(t, "13.3.x-scala2.12", cluster.SparkVersion) assert.Equal(t, "i3.2xlarge", cluster.NodeTypeId) @@ -79,7 +79,7 @@ func TestMergeJobTasks(t *testing.T) { assert.Equal(t, "package2", task0.Libraries[1].Pypi.Package) // This task was left untouched. - task1 := j.Tasks[1].NewCluster + task1 := j.Tasks[0].NewCluster assert.Equal(t, "10.4.x-scala2.12", task1.SparkVersion) }