2023-08-30 12:21:39 +00:00
|
|
|
package python
|
|
|
|
|
|
|
|
import (
|
2023-08-30 14:09:15 +00:00
|
|
|
"context"
|
2023-08-30 12:21:39 +00:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
2023-08-30 13:51:15 +00:00
|
|
|
"github.com/databricks/cli/bundle"
|
|
|
|
"github.com/databricks/cli/bundle/config"
|
2023-09-04 09:55:01 +00:00
|
|
|
"github.com/databricks/cli/bundle/config/paths"
|
2023-08-30 13:51:15 +00:00
|
|
|
"github.com/databricks/cli/bundle/config/resources"
|
2023-09-08 11:08:21 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/compute"
|
2023-08-30 12:21:39 +00:00
|
|
|
"github.com/databricks/databricks-sdk-go/service/jobs"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testCase struct {
|
|
|
|
Actual []string
|
|
|
|
Expected string
|
|
|
|
}
|
2023-08-30 13:51:15 +00:00
|
|
|
|
2023-08-30 12:21:39 +00:00
|
|
|
type testCaseNamed struct {
|
2023-08-30 13:51:15 +00:00
|
|
|
Actual map[string]string
|
2023-08-30 12:21:39 +00:00
|
|
|
Expected string
|
|
|
|
}
|
|
|
|
|
|
|
|
var paramsTestCases []testCase = []testCase{
|
2023-09-26 14:32:20 +00:00
|
|
|
{[]string{}, `"my_test_code"`},
|
|
|
|
{[]string{"a"}, `"my_test_code", "a"`},
|
|
|
|
{[]string{"a", "b"}, `"my_test_code", "a", "b"`},
|
|
|
|
{[]string{"123!@#$%^&*()-="}, `"my_test_code", "123!@#$%^&*()-="`},
|
|
|
|
{[]string{`{"a": 1}`}, `"my_test_code", "{\"a\": 1}"`},
|
2023-08-30 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var paramsTestCasesNamed []testCaseNamed = []testCaseNamed{
|
2023-09-26 14:32:20 +00:00
|
|
|
{map[string]string{}, `"my_test_code"`},
|
|
|
|
{map[string]string{"a": "1"}, `"my_test_code", "a=1"`},
|
|
|
|
{map[string]string{"a": "'1'"}, `"my_test_code", "a='1'"`},
|
|
|
|
{map[string]string{"a": `"1"`}, `"my_test_code", "a=\"1\""`},
|
|
|
|
{map[string]string{"a": "1", "b": "2"}, `"my_test_code", "a=1", "b=2"`},
|
|
|
|
{map[string]string{"data": `{"a": 1}`}, `"my_test_code", "data={\"a\": 1}"`},
|
2023-08-30 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGenerateParameters(t *testing.T) {
|
|
|
|
trampoline := pythonTrampoline{}
|
|
|
|
for _, c := range paramsTestCases {
|
2023-09-26 14:32:20 +00:00
|
|
|
task := &jobs.PythonWheelTask{PackageName: "my_test_code", Parameters: c.Actual}
|
2023-08-30 12:21:39 +00:00
|
|
|
result, err := trampoline.generateParameters(task)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, c.Expected, result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGenerateNamedParameters(t *testing.T) {
|
|
|
|
trampoline := pythonTrampoline{}
|
|
|
|
for _, c := range paramsTestCasesNamed {
|
2023-09-26 14:32:20 +00:00
|
|
|
task := &jobs.PythonWheelTask{PackageName: "my_test_code", NamedParameters: c.Actual}
|
2023-08-30 12:21:39 +00:00
|
|
|
result, err := trampoline.generateParameters(task)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// parameters order can be undetermenistic, so just check that they exist as expected
|
|
|
|
require.ElementsMatch(t, strings.Split(c.Expected, ","), strings.Split(result, ","))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGenerateBoth(t *testing.T) {
|
|
|
|
trampoline := pythonTrampoline{}
|
|
|
|
task := &jobs.PythonWheelTask{NamedParameters: map[string]string{"a": "1"}, Parameters: []string{"b"}}
|
|
|
|
_, err := trampoline.generateParameters(task)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.ErrorContains(t, err, "not allowed to pass both paramaters and named_parameters")
|
|
|
|
}
|
2023-08-30 13:51:15 +00:00
|
|
|
|
|
|
|
func TestTransformFiltersWheelTasksOnly(t *testing.T) {
|
|
|
|
trampoline := pythonTrampoline{}
|
2023-11-15 14:03:36 +00:00
|
|
|
b := &bundle.Bundle{
|
2023-08-30 13:51:15 +00:00
|
|
|
Config: config.Root{
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"job1": {
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Tasks: []jobs.Task{
|
|
|
|
{
|
|
|
|
TaskKey: "key1",
|
|
|
|
PythonWheelTask: &jobs.PythonWheelTask{},
|
2023-09-08 11:08:21 +00:00
|
|
|
Libraries: []compute.Library{
|
2023-09-08 13:45:21 +00:00
|
|
|
{Whl: "/Workspace/Users/test@test.com/bundle/dist/test.whl"},
|
2023-09-08 11:08:21 +00:00
|
|
|
},
|
2023-08-30 13:51:15 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
TaskKey: "key2",
|
|
|
|
NotebookTask: &jobs.NotebookTask{},
|
|
|
|
},
|
2023-09-08 11:08:21 +00:00
|
|
|
{
|
|
|
|
TaskKey: "key3",
|
|
|
|
PythonWheelTask: &jobs.PythonWheelTask{},
|
|
|
|
Libraries: []compute.Library{
|
|
|
|
{Whl: "dbfs:/FileStore/dist/test.whl"},
|
|
|
|
},
|
|
|
|
},
|
2023-08-30 13:51:15 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-11-15 14:03:36 +00:00
|
|
|
tasks := trampoline.GetTasks(b)
|
2023-08-30 13:51:15 +00:00
|
|
|
require.Len(t, tasks, 1)
|
|
|
|
require.Equal(t, "job1", tasks[0].JobKey)
|
|
|
|
require.Equal(t, "key1", tasks[0].Task.TaskKey)
|
|
|
|
require.NotNil(t, tasks[0].Task.PythonWheelTask)
|
|
|
|
}
|
2023-08-30 14:09:15 +00:00
|
|
|
|
|
|
|
func TestNoPanicWithNoPythonWheelTasks(t *testing.T) {
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
b := &bundle.Bundle{
|
|
|
|
Config: config.Root{
|
|
|
|
Path: tmpDir,
|
|
|
|
Bundle: config.Bundle{
|
|
|
|
Target: "development",
|
|
|
|
},
|
|
|
|
Resources: config.Resources{
|
|
|
|
Jobs: map[string]*resources.Job{
|
|
|
|
"test": {
|
2023-09-04 09:55:01 +00:00
|
|
|
Paths: paths.Paths{
|
2023-08-30 14:09:15 +00:00
|
|
|
ConfigFilePath: tmpDir,
|
|
|
|
},
|
|
|
|
JobSettings: &jobs.JobSettings{
|
|
|
|
Tasks: []jobs.Task{
|
|
|
|
{
|
|
|
|
TaskKey: "notebook_task",
|
|
|
|
NotebookTask: &jobs.NotebookTask{}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
trampoline := TransformWheelTask()
|
|
|
|
err := bundle.Apply(context.Background(), b, trampoline)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|