Skip to content

Commit b32a2de

Browse files
committed
Add integration test for default Python bundle initialization
1 parent a1fc119 commit b32a2de

File tree

10 files changed

+669
-2
lines changed

10 files changed

+669
-2
lines changed

go.mod

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
module github.com/databricks/cli
22

3-
go 1.23
3+
go 1.23.0
44

5-
toolchain go1.23.2
5+
toolchain go1.23.3
66

77
require (
88
github.com/Masterminds/semver/v3 v3.3.1 // MIT
99
github.com/briandowns/spinner v1.23.1 // Apache 2.0
1010
github.com/databricks/databricks-sdk-go v0.54.0 // Apache 2.0
11+
github.com/elliotchance/orderedmap/v3 v3.0.0 // MIT
1112
github.com/fatih/color v1.18.0 // MIT
1213
github.com/ghodss/yaml v1.0.0 // MIT + NOTICE
1314
github.com/google/uuid v1.6.0 // BSD-3-Clause
1415
github.com/hashicorp/go-version v1.7.0 // MPL 2.0
1516
github.com/hashicorp/hc-install v0.9.0 // MPL 2.0
1617
github.com/hashicorp/terraform-exec v0.21.0 // MPL 2.0
1718
github.com/hashicorp/terraform-json v0.23.0 // MPL 2.0
19+
github.com/hexops/gotextdiff v1.0.3 // BSD 3-Clause "New" or "Revised" License
1820
github.com/manifoldco/promptui v0.9.0 // BSD-3-Clause
1921
github.com/mattn/go-isatty v0.0.20 // MIT
2022
github.com/nwidger/jsoncolor v0.3.2 // MIT
@@ -23,6 +25,7 @@ require (
2325
github.com/spf13/cobra v1.8.1 // Apache 2.0
2426
github.com/spf13/pflag v1.0.5 // BSD-3-Clause
2527
github.com/stretchr/testify v1.10.0 // MIT
28+
github.com/wI2L/jsondiff v0.6.1 // MIT
2629
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
2730
golang.org/x/mod v0.22.0
2831
golang.org/x/oauth2 v0.24.0
@@ -56,6 +59,10 @@ require (
5659
github.com/mattn/go-colorable v0.1.13 // indirect
5760
github.com/pmezard/go-difflib v1.0.0 // indirect
5861
github.com/stretchr/objx v0.5.2 // indirect
62+
github.com/tidwall/gjson v1.18.0 // indirect
63+
github.com/tidwall/match v1.1.1 // indirect
64+
github.com/tidwall/pretty v1.2.1 // indirect
65+
github.com/tidwall/sjson v1.2.5 // indirect
5966
github.com/zclconf/go-cty v1.15.0 // indirect
6067
go.opencensus.io v0.24.0 // indirect
6168
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package bundle_test
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"os"
7+
"os/exec"
8+
"path/filepath"
9+
"strings"
10+
"testing"
11+
12+
"github.com/databricks/cli/integration/internal/acc"
13+
"github.com/databricks/cli/internal/testcli"
14+
"github.com/databricks/cli/internal/testutil"
15+
"github.com/databricks/cli/libs/python"
16+
"github.com/stretchr/testify/require"
17+
)
18+
19+
var pythonVersions = []string{
20+
"3.8",
21+
"3.9",
22+
"3.10",
23+
"3.11",
24+
"3.12",
25+
"3.13",
26+
}
27+
28+
var pythonVersionsShort = []string{
29+
"3.9",
30+
"3.12",
31+
}
32+
33+
var extraInstalls = map[string][]string{
34+
"3.12": {"setuptools"},
35+
"3.13": {"setuptools"},
36+
}
37+
38+
func TestDefaultPython(t *testing.T) {
39+
versions := pythonVersions
40+
if testing.Short() {
41+
versions = pythonVersionsShort
42+
}
43+
44+
for _, pythonVersion := range versions {
45+
t.Run("Python "+pythonVersion, func(t *testing.T) {
46+
testDefaultPython(t, pythonVersion)
47+
})
48+
}
49+
}
50+
51+
func setupPython(t testutil.TestingT, ctx context.Context, directory, pythonVersion string) {
52+
testutil.RunCommand(t, "uv", "venv", ".myenv", "--python", pythonVersion, "--seed")
53+
54+
testutil.InsertVirtualenvInPath(t, filepath.Join(directory, ".myenv"))
55+
56+
pythonExe, err := python.DetectExecutable(ctx)
57+
require.NoError(t, err)
58+
59+
t.Logf("pythonExe=%s", pythonExe)
60+
61+
p, err := exec.LookPath("python3")
62+
t.Logf("python3 lookup=%s %s", p, err)
63+
64+
p, err = exec.LookPath("python")
65+
t.Logf("python lookup=%s %s", p, err)
66+
67+
p, err = exec.LookPath("python.exe")
68+
t.Logf("python.exe lookup=%s %s", p, err)
69+
70+
actualVersion := testutil.CaptureCommandOutput(t, pythonExe, "--version")
71+
expectVersion := "Python " + pythonVersion
72+
require.True(t, strings.HasPrefix(actualVersion, expectVersion), "Running %s --version: Expected %v, got %v", pythonExe, expectVersion, actualVersion)
73+
74+
extras, ok := extraInstalls[pythonVersion]
75+
if ok {
76+
args := append([]string{"pip", "install"}, extras...)
77+
testutil.RunCommand(t, "uv", args...)
78+
}
79+
}
80+
81+
func testDefaultPython(t *testing.T, pythonVersion string) {
82+
ctx, wt := acc.WorkspaceTest(t)
83+
84+
uniqueProjectId := testutil.RandomName("")
85+
ctx, replacements := testcli.WithReplacementsMap(ctx)
86+
replacements.Set(uniqueProjectId, "$UNIQUE_PRJ")
87+
88+
testcli.PrepareReplacements(t, replacements, wt.W)
89+
90+
user, err := wt.W.CurrentUser.Me(ctx)
91+
require.NoError(t, err)
92+
if user != nil {
93+
testcli.PrepareReplacementsUser(t, replacements, *user)
94+
}
95+
96+
tmpDir1 := t.TempDir()
97+
testutil.Chdir(t, tmpDir1)
98+
99+
setupPython(t, ctx, tmpDir1, pythonVersion)
100+
101+
projectName := "project_name_" + uniqueProjectId
102+
103+
initConfig := map[string]string{
104+
"project_name": projectName,
105+
"include_notebook": "yes",
106+
"include_python": "yes",
107+
"include_dlt": "yes",
108+
}
109+
b, err := json.Marshal(initConfig)
110+
require.NoError(t, err)
111+
err = os.WriteFile(filepath.Join(tmpDir1, "config.json"), b, 0o644)
112+
require.NoError(t, err)
113+
114+
testcli.RequireOutput(t, ctx, []string{"bundle", "init", "default-python", "--config-file", "config.json"}, "testdata/default_python/bundle_init.txt")
115+
testutil.Chdir(t, projectName)
116+
117+
testcli.RequireOutput(t, ctx, []string{"bundle", "validate"}, "testdata/default_python/bundle_validate.txt")
118+
119+
testcli.RequireOutput(t, ctx, []string{"bundle", "deploy"}, "testdata/default_python/bundle_deploy.txt")
120+
t.Cleanup(func() {
121+
// Delete the stack
122+
testcli.RequireSuccessfulRun(t, ctx, "bundle", "destroy", "--auto-approve")
123+
})
124+
125+
ignoredFields := []string{
126+
"/resources/jobs/project_name_$UNIQUE_PRJ_job/email_notifications",
127+
"/resources/jobs/project_name_$UNIQUE_PRJ_job/job_clusters/0/new_cluster/node_type_id",
128+
"/resources/jobs/project_name_$UNIQUE_PRJ_job/url",
129+
"/resources/pipelines/project_name_$UNIQUE_PRJ_pipeline/catalog",
130+
"/resources/pipelines/project_name_$UNIQUE_PRJ_pipeline/url",
131+
"/workspace/current_user/externalId",
132+
"/workspace/current_user/groups",
133+
"/workspace/current_user/name/familyName",
134+
}
135+
136+
testcli.RequireOutputJQ(t, ctx, []string{"bundle", "summary", "--output", "json"}, "testdata/default_python/bundle_summary.txt", ignoredFields)
137+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Building project_name_$UNIQUE_PRJ...
2+
Uploading project_name_$UNIQUE_PRJ-0.0.1+<NUMID>.<NUMID>-py3-none-any.whl...
3+
Uploading bundle files to /Workspace/Users/$USERNAME/.bundle/project_name_$UNIQUE_PRJ/dev/files...
4+
Deploying resources...
5+
Updating deployment state...
6+
Deployment complete!
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
Welcome to the default Python template for Databricks Asset Bundles!
3+
Workspace to use (auto-detected, edit in 'project_name_$UNIQUE_PRJ/databricks.yml'): https://$DATABRICKS_HOST
4+
5+
✨ Your new project has been created in the 'project_name_$UNIQUE_PRJ' directory!
6+
7+
Please refer to the README.md file for "getting started" instructions.
8+
See also the documentation at https://docs.databricks.com/dev-tools/bundles/index.html.

0 commit comments

Comments
 (0)