Compare commits

..

No commits in common. "e5b836a6ac182692386ea29c955168061cd73d57" and "daf0f48143ca227ba967926969c9532abb87fcc6" have entirely different histories.

55 changed files with 410 additions and 388 deletions

View File

@ -20,7 +20,7 @@ require (
github.com/cloudflare/circl v1.5.0 // indirect github.com/cloudflare/circl v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
golang.org/x/crypto v0.31.0 // indirect golang.org/x/crypto v0.30.0 // indirect
golang.org/x/mod v0.22.0 // indirect golang.org/x/mod v0.22.0 // indirect
golang.org/x/sys v0.28.0 // indirect golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect

View File

@ -60,8 +60,8 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/zclconf/go-cty v1.15.1 h1:RgQYm4j2EvoBRXOPxhUvxPzRrGDo1eCOhHXuGfrj5S0= github.com/zclconf/go-cty v1.15.1 h1:RgQYm4j2EvoBRXOPxhUvxPzRrGDo1eCOhHXuGfrj5S0=
github.com/zclconf/go-cty v1.15.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty v1.15.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0= golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0=
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=

View File

@ -160,7 +160,7 @@ func TestJobRunnerRestart(t *testing.T) {
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)
b.SetWorkpaceClient(m.WorkspaceClient) b.SetWorkpaceClient(m.WorkspaceClient)
ctx := context.Background() ctx := context.Background()
ctx = cmdio.InContext(ctx, cmdio.NewIO(ctx, flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "")) ctx = cmdio.InContext(ctx, cmdio.NewIO(flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", ""))
ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend)) ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend))
jobApi := m.GetMockJobsAPI() jobApi := m.GetMockJobsAPI()
@ -231,7 +231,7 @@ func TestJobRunnerRestartForContinuousUnpausedJobs(t *testing.T) {
m := mocks.NewMockWorkspaceClient(t) m := mocks.NewMockWorkspaceClient(t)
b.SetWorkpaceClient(m.WorkspaceClient) b.SetWorkpaceClient(m.WorkspaceClient)
ctx := context.Background() ctx := context.Background()
ctx = cmdio.InContext(ctx, cmdio.NewIO(ctx, flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "...")) ctx = cmdio.InContext(ctx, cmdio.NewIO(flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "..."))
ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend)) ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend))
jobApi := m.GetMockJobsAPI() jobApi := m.GetMockJobsAPI()

View File

@ -76,7 +76,7 @@ func TestPipelineRunnerRestart(t *testing.T) {
} }
b.SetWorkpaceClient(m.WorkspaceClient) b.SetWorkpaceClient(m.WorkspaceClient)
ctx := context.Background() ctx := context.Background()
ctx = cmdio.InContext(ctx, cmdio.NewIO(ctx, flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "...")) ctx = cmdio.InContext(ctx, cmdio.NewIO(flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "..."))
ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend)) ctx = cmdio.NewContext(ctx, cmdio.NewLogger(flags.ModeAppend))
mockWait := &pipelines.WaitGetPipelineIdle[struct{}]{ mockWait := &pipelines.WaitGetPipelineIdle[struct{}]{

View File

@ -11,7 +11,7 @@ import (
func TestListsInstalledProjects(t *testing.T) { func TestListsInstalledProjects(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = env.WithUserHomeDir(ctx, "project/testdata/installed-in-home") ctx = env.WithUserHomeDir(ctx, "project/testdata/installed-in-home")
r := testcli.NewRunner(t, ctx, "labs", "installed") r := testcli.NewRunnerWithContext(t, ctx, "labs", "installed")
r.RunAndExpectOutput(` r.RunAndExpectOutput(`
Name Description Version Name Description Version
blueprint Blueprint Project v0.3.15 blueprint Blueprint Project v0.3.15

View File

@ -12,7 +12,7 @@ import (
func TestListingWorks(t *testing.T) { func TestListingWorks(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = env.WithUserHomeDir(ctx, "project/testdata/installed-in-home") ctx = env.WithUserHomeDir(ctx, "project/testdata/installed-in-home")
c := testcli.NewRunner(t, ctx, "labs", "list") c := testcli.NewRunnerWithContext(t, ctx, "labs", "list")
stdout, _, err := c.Run() stdout, _, err := c.Run()
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, stdout.String(), "ucx") require.Contains(t, stdout.String(), "ucx")

View File

@ -30,7 +30,7 @@ func devEnvContext(t *testing.T) context.Context {
func TestRunningBlueprintEcho(t *testing.T) { func TestRunningBlueprintEcho(t *testing.T) {
ctx := devEnvContext(t) ctx := devEnvContext(t)
r := testcli.NewRunner(t, ctx, "labs", "blueprint", "echo") r := testcli.NewRunnerWithContext(t, ctx, "labs", "blueprint", "echo")
var out echoOut var out echoOut
r.RunAndParseJSON(&out) r.RunAndParseJSON(&out)
assert.Equal(t, "echo", out.Command) assert.Equal(t, "echo", out.Command)
@ -41,14 +41,14 @@ func TestRunningBlueprintEcho(t *testing.T) {
func TestRunningBlueprintEchoProfileWrongOverride(t *testing.T) { func TestRunningBlueprintEchoProfileWrongOverride(t *testing.T) {
ctx := devEnvContext(t) ctx := devEnvContext(t)
r := testcli.NewRunner(t, ctx, "labs", "blueprint", "echo", "--profile", "workspace-profile") r := testcli.NewRunnerWithContext(t, ctx, "labs", "blueprint", "echo", "--profile", "workspace-profile")
_, _, err := r.Run() _, _, err := r.Run()
assert.ErrorIs(t, err, databricks.ErrNotAccountClient) assert.ErrorIs(t, err, databricks.ErrNotAccountClient)
} }
func TestRunningCommand(t *testing.T) { func TestRunningCommand(t *testing.T) {
ctx := devEnvContext(t) ctx := devEnvContext(t)
r := testcli.NewRunner(t, ctx, "labs", "blueprint", "foo") r := testcli.NewRunnerWithContext(t, ctx, "labs", "blueprint", "foo")
r.WithStdin() r.WithStdin()
defer r.CloseStdin() defer r.CloseStdin()
@ -60,7 +60,7 @@ func TestRunningCommand(t *testing.T) {
func TestRenderingTable(t *testing.T) { func TestRenderingTable(t *testing.T) {
ctx := devEnvContext(t) ctx := devEnvContext(t)
r := testcli.NewRunner(t, ctx, "labs", "blueprint", "table") r := testcli.NewRunnerWithContext(t, ctx, "labs", "blueprint", "table")
r.RunAndExpectOutput(` r.RunAndExpectOutput(`
Key Value Key Value
First Second First Second

View File

@ -236,7 +236,7 @@ func TestInstallerWorksForReleases(t *testing.T) {
// │ │ │ └── site-packages // │ │ │ └── site-packages
// │ │ │ ├── ... // │ │ │ ├── ...
// │ │ │ ├── distutils-precedence.pth // │ │ │ ├── distutils-precedence.pth
r := testcli.NewRunner(t, ctx, "labs", "install", "blueprint", "--debug") r := testcli.NewRunnerWithContext(t, ctx, "labs", "install", "blueprint", "--debug")
r.RunAndExpectOutput("setting up important infrastructure") r.RunAndExpectOutput("setting up important infrastructure")
} }
@ -356,7 +356,7 @@ account_id = abc
// └── databrickslabs-blueprint-releases.json // └── databrickslabs-blueprint-releases.json
// `databricks labs install .` means "verify this installer i'm developing does work" // `databricks labs install .` means "verify this installer i'm developing does work"
r := testcli.NewRunner(t, ctx, "labs", "install", ".") r := testcli.NewRunnerWithContext(t, ctx, "labs", "install", ".")
r.WithStdin() r.WithStdin()
defer r.CloseStdin() defer r.CloseStdin()
@ -426,7 +426,7 @@ func TestUpgraderWorksForReleases(t *testing.T) {
ctx = env.Set(ctx, "DATABRICKS_CLUSTER_ID", "installer-cluster") ctx = env.Set(ctx, "DATABRICKS_CLUSTER_ID", "installer-cluster")
ctx = env.Set(ctx, "DATABRICKS_WAREHOUSE_ID", "installer-warehouse") ctx = env.Set(ctx, "DATABRICKS_WAREHOUSE_ID", "installer-warehouse")
r := testcli.NewRunner(t, ctx, "labs", "upgrade", "blueprint") r := testcli.NewRunnerWithContext(t, ctx, "labs", "upgrade", "blueprint")
r.RunAndExpectOutput("setting up important infrastructure") r.RunAndExpectOutput("setting up important infrastructure")
// Check if the stub was called with the 'python -m pip install' command // Check if the stub was called with the 'python -m pip install' command

View File

@ -45,9 +45,8 @@ func (f *outputFlag) initializeIO(cmd *cobra.Command) error {
headerTemplate = cmd.Annotations["headerTemplate"] headerTemplate = cmd.Annotations["headerTemplate"]
} }
ctx := cmd.Context() cmdIO := cmdio.NewIO(f.output, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), headerTemplate, template)
cmdIO := cmdio.NewIO(ctx, f.output, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), headerTemplate, template) ctx := cmdio.InContext(cmd.Context(), cmdIO)
ctx = cmdio.InContext(ctx, cmdIO)
cmd.SetContext(ctx) cmd.SetContext(ctx)
return nil return nil
} }

4
go.mod
View File

@ -28,7 +28,7 @@ require (
golang.org/x/oauth2 v0.24.0 golang.org/x/oauth2 v0.24.0
golang.org/x/sync v0.10.0 golang.org/x/sync v0.10.0
golang.org/x/term v0.27.0 golang.org/x/term v0.27.0
golang.org/x/text v0.21.0 golang.org/x/text v0.20.0
gopkg.in/ini.v1 v1.67.0 // Apache 2.0 gopkg.in/ini.v1 v1.67.0 // Apache 2.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@ -62,7 +62,7 @@ require (
go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/crypto v0.31.0 // indirect golang.org/x/crypto v0.24.0 // indirect
golang.org/x/net v0.26.0 // indirect golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.28.0 // indirect golang.org/x/sys v0.28.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect

8
go.sum generated
View File

@ -176,8 +176,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
@ -218,8 +218,8 @@ golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -15,7 +15,6 @@ import (
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/databricks-sdk-go/service/catalog" "github.com/databricks/databricks-sdk-go/service/catalog"
"github.com/databricks/databricks-sdk-go/service/compute" "github.com/databricks/databricks-sdk-go/service/compute"
"github.com/databricks/databricks-sdk-go/service/jobs" "github.com/databricks/databricks-sdk-go/service/jobs"
@ -247,14 +246,15 @@ func TestUploadArtifactFileToVolumeThatDoesNotExist(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
}) })
bundleRoot := initTestTemplate(t, ctx, "artifact_path_with_volume", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "artifact_path_with_volume", map[string]any{
"unique_id": uuid.New().String(), "unique_id": uuid.New().String(),
"schema_name": schemaName, "schema_name": schemaName,
"volume_name": "doesnotexist", "volume_name": "doesnotexist",
}) })
require.NoError(t, err)
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, ctx, "bundle", "deploy") stdout, stderr, err := testcli.RequireErrorRun(t, "bundle", "deploy")
assert.Error(t, err) assert.Error(t, err)
assert.Equal(t, fmt.Sprintf(`Error: volume /Volumes/main/%s/doesnotexist does not exist: Not Found assert.Equal(t, fmt.Sprintf(`Error: volume /Volumes/main/%s/doesnotexist does not exist: Not Found
@ -283,14 +283,15 @@ func TestUploadArtifactToVolumeNotYetDeployed(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
}) })
bundleRoot := initTestTemplate(t, ctx, "artifact_path_with_volume", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "artifact_path_with_volume", map[string]any{
"unique_id": uuid.New().String(), "unique_id": uuid.New().String(),
"schema_name": schemaName, "schema_name": schemaName,
"volume_name": "my_volume", "volume_name": "my_volume",
}) })
require.NoError(t, err)
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, ctx, "bundle", "deploy") stdout, stderr, err := testcli.RequireErrorRun(t, "bundle", "deploy")
assert.Error(t, err) assert.Error(t, err)
assert.Equal(t, fmt.Sprintf(`Error: volume /Volumes/main/%s/my_volume does not exist: Not Found assert.Equal(t, fmt.Sprintf(`Error: volume /Volumes/main/%s/my_volume does not exist: Not Found

View File

@ -16,22 +16,27 @@ func TestBasicBundleDeployWithFailOnActiveRuns(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "basic", map[string]any{ root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, root) err = destroyBundle(t, ctx, root)
require.NoError(t, err)
}) })
// deploy empty bundle // deploy empty bundle
deployBundleWithFlags(t, ctx, root, []string{"--fail-on-active-runs"}) err = deployBundleWithFlags(t, ctx, root, []string{"--fail-on-active-runs"})
require.NoError(t, err)
// Remove .databricks directory to simulate a fresh deployment // Remove .databricks directory to simulate a fresh deployment
require.NoError(t, os.RemoveAll(filepath.Join(root, ".databricks"))) err = os.RemoveAll(filepath.Join(root, ".databricks"))
require.NoError(t, err)
// deploy empty bundle again // deploy empty bundle again
deployBundleWithFlags(t, ctx, root, []string{"--fail-on-active-runs"}) err = deployBundleWithFlags(t, ctx, root, []string{"--fail-on-active-runs"})
require.NoError(t, err)
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/jobs" "github.com/databricks/databricks-sdk-go/service/jobs"
"github.com/google/uuid" "github.com/google/uuid"
@ -23,27 +22,30 @@ func TestBindJobToExistingJob(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12", "spark_version": "13.3.x-scala2.12",
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
}) })
require.NoError(t, err)
jobId := gt.createTestJob(ctx) jobId := gt.createTestJob(ctx)
t.Cleanup(func() { t.Cleanup(func() {
gt.destroyJob(ctx, jobId) gt.destroyJob(ctx, jobId)
require.NoError(t, err)
}) })
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId), "--auto-approve") c := testcli.NewRunner(t, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId), "--auto-approve")
_, _, err := c.Run() _, _, err = c.Run()
require.NoError(t, err) require.NoError(t, err)
// Remove .databricks directory to simulate a fresh deployment // Remove .databricks directory to simulate a fresh deployment
err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks")) err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks"))
require.NoError(t, err) require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
w, err := databricks.NewWorkspaceClient() w, err := databricks.NewWorkspaceClient()
require.NoError(t, err) require.NoError(t, err)
@ -56,7 +58,7 @@ func TestBindJobToExistingJob(t *testing.T) {
require.Equal(t, job.Settings.Name, fmt.Sprintf("test-job-basic-%s", uniqueId)) require.Equal(t, job.Settings.Name, fmt.Sprintf("test-job-basic-%s", uniqueId))
require.Contains(t, job.Settings.Tasks[0].SparkPythonTask.PythonFile, "hello_world.py") require.Contains(t, job.Settings.Tasks[0].SparkPythonTask.PythonFile, "hello_world.py")
c = testcli.NewRunner(t, ctx, "bundle", "deployment", "unbind", "foo") c = testcli.NewRunner(t, "bundle", "deployment", "unbind", "foo")
_, _, err = c.Run() _, _, err = c.Run()
require.NoError(t, err) require.NoError(t, err)
@ -64,7 +66,8 @@ func TestBindJobToExistingJob(t *testing.T) {
err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks")) err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks"))
require.NoError(t, err) require.NoError(t, err)
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Check that job is unbound and exists after bundle is destroyed // Check that job is unbound and exists after bundle is destroyed
job, err = w.Jobs.Get(ctx, jobs.GetJobRequest{ job, err = w.Jobs.Get(ctx, jobs.GetJobRequest{
@ -81,29 +84,32 @@ func TestAbortBind(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12", "spark_version": "13.3.x-scala2.12",
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
}) })
require.NoError(t, err)
jobId := gt.createTestJob(ctx) jobId := gt.createTestJob(ctx)
t.Cleanup(func() { t.Cleanup(func() {
gt.destroyJob(ctx, jobId) gt.destroyJob(ctx, jobId)
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
// Bind should fail because prompting is not possible. // Bind should fail because prompting is not possible.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId)) c := testcli.NewRunner(t, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId))
// Expect error suggesting to use --auto-approve // Expect error suggesting to use --auto-approve
_, _, err := c.Run() _, _, err = c.Run()
assert.ErrorContains(t, err, "failed to bind the resource") assert.ErrorContains(t, err, "failed to bind the resource")
assert.ErrorContains(t, err, "This bind operation requires user confirmation, but the current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed") assert.ErrorContains(t, err, "This bind operation requires user confirmation, but the current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed")
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
w, err := databricks.NewWorkspaceClient() w, err := databricks.NewWorkspaceClient()
require.NoError(t, err) require.NoError(t, err)
@ -123,9 +129,10 @@ func TestGenerateAndBind(t *testing.T) {
gt := &generateJobTest{T: wt, w: wt.W} gt := &generateJobTest{T: wt, w: wt.W}
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "with_includes", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "with_includes", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
w, err := databricks.NewWorkspaceClient() w, err := databricks.NewWorkspaceClient()
require.NoError(t, err) require.NoError(t, err)
@ -140,8 +147,8 @@ func TestGenerateAndBind(t *testing.T) {
} }
}) })
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "job", c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "job",
"--key", "test_job_key", "--key", "test_job_key",
"--existing-job-id", fmt.Sprint(jobId), "--existing-job-id", fmt.Sprint(jobId),
"--config-dir", filepath.Join(bundleRoot, "resources"), "--config-dir", filepath.Join(bundleRoot, "resources"),
@ -157,13 +164,15 @@ func TestGenerateAndBind(t *testing.T) {
require.Len(t, matches, 1) require.Len(t, matches, 1)
c = testcli.NewRunner(t, ctx, "bundle", "deployment", "bind", "test_job_key", fmt.Sprint(jobId), "--auto-approve") c = testcli.NewRunner(t, "bundle", "deployment", "bind", "test_job_key", fmt.Sprint(jobId), "--auto-approve")
_, _, err = c.Run() _, _, err = c.Run()
require.NoError(t, err) require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Check that job is bound and does not extsts after bundle is destroyed // Check that job is bound and does not extsts after bundle is destroyed
_, err = w.Jobs.Get(ctx, jobs.GetJobRequest{ _, err = w.Jobs.Get(ctx, jobs.GetJobRequest{

View File

@ -20,14 +20,16 @@ func TestDeployBundleWithCluster(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "clusters", map[string]any{ root, err := initTestTemplate(t, ctx, "clusters", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, root) err = destroyBundle(t, ctx, root)
require.NoError(t, err)
cluster, err := wt.W.Clusters.GetByClusterName(ctx, fmt.Sprintf("test-cluster-%s", uniqueId)) cluster, err := wt.W.Clusters.GetByClusterName(ctx, fmt.Sprintf("test-cluster-%s", uniqueId))
if err != nil { if err != nil {
@ -37,7 +39,8 @@ func TestDeployBundleWithCluster(t *testing.T) {
} }
}) })
deployBundle(t, ctx, root) err = deployBundle(t, ctx, root)
require.NoError(t, err)
// Cluster should exists after bundle deployment // Cluster should exists after bundle deployment
cluster, err := wt.W.Clusters.GetByClusterName(ctx, fmt.Sprintf("test-cluster-%s", uniqueId)) cluster, err := wt.W.Clusters.GetByClusterName(ctx, fmt.Sprintf("test-cluster-%s", uniqueId))

View File

@ -18,16 +18,19 @@ func TestDashboards(t *testing.T) {
warehouseID := testutil.GetEnvOrSkipTest(t, "TEST_DEFAULT_WAREHOUSE_ID") warehouseID := testutil.GetEnvOrSkipTest(t, "TEST_DEFAULT_WAREHOUSE_ID")
uniqueID := uuid.New().String() uniqueID := uuid.New().String()
root := initTestTemplate(t, ctx, "dashboards", map[string]any{ root, err := initTestTemplate(t, ctx, "dashboards", map[string]any{
"unique_id": uniqueID, "unique_id": uniqueID,
"warehouse_id": warehouseID, "warehouse_id": warehouseID,
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, root) err = destroyBundle(t, ctx, root)
require.NoError(t, err)
}) })
deployBundle(t, ctx, root) err = deployBundle(t, ctx, root)
require.NoError(t, err)
// Load bundle configuration by running the validate command. // Load bundle configuration by running the validate command.
b := unmarshalConfig(t, mustValidateBundle(t, ctx, root)) b := unmarshalConfig(t, mustValidateBundle(t, ctx, root))
@ -52,11 +55,12 @@ func TestDashboards(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Try to redeploy the bundle and confirm that the out of band modification is detected. // Try to redeploy the bundle and confirm that the out of band modification is detected.
stdout, _, err := deployBundleWithArgsErr(t, ctx, root) stdout, _, err := deployBundleWithArgs(t, ctx, root)
require.Error(t, err) require.Error(t, err)
assert.Contains(t, stdout, `Error: dashboard "file_reference" has been modified remotely`+"\n") assert.Contains(t, stdout, `Error: dashboard "file_reference" has been modified remotely`+"\n")
// Redeploy the bundle with the --force flag and confirm that the out of band modification is ignored. // Redeploy the bundle with the --force flag and confirm that the out of band modification is ignored.
_, stderr := deployBundleWithArgs(t, ctx, root, "--force") _, stderr, err := deployBundleWithArgs(t, ctx, root, "--force")
require.NoError(t, err)
assert.Contains(t, stderr, `Deployment complete!`+"\n") assert.Contains(t, stderr, `Deployment complete!`+"\n")
} }

View File

@ -14,7 +14,6 @@ import (
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/apierr" "github.com/databricks/databricks-sdk-go/apierr"
"github.com/databricks/databricks-sdk-go/service/catalog" "github.com/databricks/databricks-sdk-go/service/catalog"
@ -25,14 +24,17 @@ import (
) )
func setupUcSchemaBundle(t *testing.T, ctx context.Context, w *databricks.WorkspaceClient, uniqueId string) string { func setupUcSchemaBundle(t *testing.T, ctx context.Context, w *databricks.WorkspaceClient, uniqueId string) string {
bundleRoot := initTestTemplate(t, ctx, "uc_schema", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "uc_schema", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
// Assert the schema is created // Assert the schema is created
@ -94,7 +96,8 @@ func TestBundleDeployUcSchema(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Redeploy the bundle // Redeploy the bundle
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Assert the schema is deleted // Assert the schema is deleted
_, err = w.Schemas.GetByFullName(ctx, strings.Join([]string{catalogName, schemaName}, ".")) _, err = w.Schemas.GetByFullName(ctx, strings.Join([]string{catalogName, schemaName}, "."))
@ -115,9 +118,9 @@ func TestBundleDeployUcSchemaFailsWithoutAutoApprove(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Redeploy the bundle // Redeploy the bundle
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock")
stdout, stderr, err := c.Run() stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error()) assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -131,14 +134,16 @@ func TestBundlePipelineDeleteWithoutAutoApprove(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
// deploy pipeline // deploy pipeline
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is created // assert pipeline is created
pipelineName := "test-bundle-pipeline-" + uniqueId pipelineName := "test-bundle-pipeline-" + uniqueId
@ -157,9 +162,9 @@ func TestBundlePipelineDeleteWithoutAutoApprove(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Redeploy the bundle. Expect it to fail because deleting the pipeline requires --auto-approve. // Redeploy the bundle. Expect it to fail because deleting the pipeline requires --auto-approve.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock")
stdout, stderr, err := c.Run() stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error()) assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -176,14 +181,17 @@ func TestBundlePipelineRecreateWithoutAutoApprove(t *testing.T) {
w := wt.W w := wt.W
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "recreate_pipeline", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "recreate_pipeline", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
// Assert the pipeline is created // Assert the pipeline is created
@ -193,9 +201,9 @@ func TestBundlePipelineRecreateWithoutAutoApprove(t *testing.T) {
require.Equal(t, pipelineName, pipeline.Name) require.Equal(t, pipelineName, pipeline.Name)
// Redeploy the bundle, pointing the DLT pipeline to a different UC catalog. // Redeploy the bundle, pointing the DLT pipeline to a different UC catalog.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock", "--var=\"catalog=whatever\"") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock", "--var=\"catalog=whatever\"")
stdout, stderr, err := c.Run() stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error()) assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -212,20 +220,22 @@ func TestDeployBasicBundleLogs(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "basic", map[string]any{ root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, root) err = destroyBundle(t, ctx, root)
require.NoError(t, err)
}) })
currentUser, err := wt.W.CurrentUser.Me(ctx) currentUser, err := wt.W.CurrentUser.Me(ctx)
require.NoError(t, err) require.NoError(t, err)
stdout, stderr := blackBoxRun(t, ctx, root, "bundle", "deploy") stdout, stderr := blackBoxRun(t, root, "bundle", "deploy")
assert.Equal(t, strings.Join([]string{ assert.Equal(t, strings.Join([]string{
fmt.Sprintf("Uploading bundle files to /Workspace/Users/%s/.bundle/%s/files...", currentUser.UserName, uniqueId), fmt.Sprintf("Uploading bundle files to /Workspace/Users/%s/.bundle/%s/files...", currentUser.UserName, uniqueId),
"Deploying resources...", "Deploying resources...",
@ -240,14 +250,17 @@ func TestDeployUcVolume(t *testing.T) {
w := wt.W w := wt.W
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "volume", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "volume", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
// Assert the volume is created successfully // Assert the volume is created successfully
@ -269,9 +282,9 @@ func TestDeployUcVolume(t *testing.T) {
assert.Equal(t, []catalog.Privilege{catalog.PrivilegeWriteVolume}, grants.PrivilegeAssignments[0].Privileges) assert.Equal(t, []catalog.Privilege{catalog.PrivilegeWriteVolume}, grants.PrivilegeAssignments[0].Privileges)
// Recreation of the volume without --auto-approve should fail since prompting is not possible // Recreation of the volume without --auto-approve should fail since prompting is not possible
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("TERM", "dumb")
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.NewRunner(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}").Run() stdout, stderr, err := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}").Run()
assert.Error(t, err) assert.Error(t, err)
assert.Contains(t, stderr.String(), `This action will result in the deletion or recreation of the following volumes. assert.Contains(t, stderr.String(), `This action will result in the deletion or recreation of the following volumes.
For managed volumes, the files stored in the volume are also deleted from your For managed volumes, the files stored in the volume are also deleted from your
@ -281,9 +294,9 @@ is removed from the catalog, but the underlying files are not deleted:
assert.Contains(t, stdout.String(), "the deployment requires destructive actions, but current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed") assert.Contains(t, stdout.String(), "the deployment requires destructive actions, but current console does not support prompting. Please specify --auto-approve if you would like to skip prompts and proceed")
// Successfully recreate the volume with --auto-approve // Successfully recreate the volume with --auto-approve
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("TERM", "dumb")
ctx = env.Set(ctx, "TERM", "dumb") t.Setenv("BUNDLE_ROOT", bundleRoot)
_, _, err = testcli.NewRunner(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}", "--auto-approve").Run() _, _, err = testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}", "--auto-approve").Run()
assert.NoError(t, err) assert.NoError(t, err)
// Assert the volume is updated successfully // Assert the volume is updated successfully

View File

@ -18,14 +18,16 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
// deploy pipeline // deploy pipeline
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is created // assert pipeline is created
pipelineName := "test-bundle-pipeline-" + uniqueId pipelineName := "test-bundle-pipeline-" + uniqueId
@ -44,7 +46,8 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// deploy again // deploy again
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is deleted // assert pipeline is deleted
_, err = w.Pipelines.GetByName(ctx, pipelineName) _, err = w.Pipelines.GetByName(ctx, pipelineName)
@ -55,6 +58,7 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
assert.ErrorContains(t, err, "does not exist") assert.ErrorContains(t, err, "does not exist")
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
} }

View File

@ -19,16 +19,19 @@ func TestDeployBasicToSharedWorkspacePath(t *testing.T) {
currentUser, err := wt.W.CurrentUser.Me(ctx) currentUser, err := wt.W.CurrentUser.Me(ctx)
require.NoError(t, err) require.NoError(t, err)
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
"root_path": fmt.Sprintf("/Shared/%s", currentUser.UserName), "root_path": fmt.Sprintf("/Shared/%s", currentUser.UserName),
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(wt, ctx, bundleRoot) err = destroyBundle(wt, ctx, bundleRoot)
require.NoError(wt, err)
}) })
deployBundle(wt, ctx, bundleRoot) err = deployBundle(wt, ctx, bundleRoot)
require.NoError(wt, err)
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/databricks/cli/bundle/deploy" "github.com/databricks/cli/bundle/deploy"
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -20,16 +19,17 @@ func TestFilesAreSyncedCorrectlyWhenNoSnapshot(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12", "spark_version": "13.3.x-scala2.12",
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
}) })
require.NoError(t, err)
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
// Add some test file to the bundle // Add some test file to the bundle
err := os.WriteFile(filepath.Join(bundleRoot, "test.py"), []byte("print('Hello, World!')"), 0o644) err = os.WriteFile(filepath.Join(bundleRoot, "test.py"), []byte("print('Hello, World!')"), 0o644)
require.NoError(t, err) require.NoError(t, err)
err = os.WriteFile(filepath.Join(bundleRoot, "test_to_modify.py"), []byte("print('Hello, World!')"), 0o644) err = os.WriteFile(filepath.Join(bundleRoot, "test_to_modify.py"), []byte("print('Hello, World!')"), 0o644)
@ -39,10 +39,11 @@ func TestFilesAreSyncedCorrectlyWhenNoSnapshot(t *testing.T) {
err = os.WriteFile(filepath.Join(bundleRoot, "notebook.py"), []byte("# Databricks notebook source\nHello, World!"), 0o644) err = os.WriteFile(filepath.Join(bundleRoot, "notebook.py"), []byte("# Databricks notebook source\nHello, World!"), 0o644)
require.NoError(t, err) require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) require.NoError(t, destroyBundle(t, ctx, bundleRoot))
}) })
remoteRoot := getBundleRemoteRootPath(w, t, uniqueId) remoteRoot := getBundleRemoteRootPath(w, t, uniqueId)
@ -78,7 +79,8 @@ func TestFilesAreSyncedCorrectlyWhenNoSnapshot(t *testing.T) {
err = os.WriteFile(filepath.Join(bundleRoot, "test_to_modify.py"), []byte("print('Modified!')"), 0o644) err = os.WriteFile(filepath.Join(bundleRoot, "test_to_modify.py"), []byte("print('Modified!')"), 0o644)
require.NoError(t, err) require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Check that removed file is not in workspace anymore // Check that removed file is not in workspace anymore
_, err = w.Workspace.GetStatusByPath(ctx, path.Join(remoteRoot, "files", "test.py")) _, err = w.Workspace.GetStatusByPath(ctx, path.Join(remoteRoot, "files", "test.py"))

View File

@ -20,20 +20,22 @@ func TestBundleDestroy(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "deploy_then_remove_resources", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
snapshotsDir := filepath.Join(bundleRoot, ".databricks", "bundle", "default", "sync-snapshots") snapshotsDir := filepath.Join(bundleRoot, ".databricks", "bundle", "default", "sync-snapshots")
// Assert the snapshot file does not exist // Assert the snapshot file does not exist
_, err := os.ReadDir(snapshotsDir) _, err = os.ReadDir(snapshotsDir)
assert.ErrorIs(t, err, os.ErrNotExist) assert.ErrorIs(t, err, os.ErrNotExist)
// deploy resources // deploy resources
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Assert the snapshot file exists // Assert the snapshot file exists
entries, err := os.ReadDir(snapshotsDir) entries, err := os.ReadDir(snapshotsDir)
@ -58,7 +60,8 @@ func TestBundleDestroy(t *testing.T) {
assert.Equal(t, job.Settings.Name, jobName) assert.Equal(t, job.Settings.Name, jobName)
// destroy bundle // destroy bundle
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is deleted // assert pipeline is deleted
_, err = w.Pipelines.GetByName(ctx, pipelineName) _, err = w.Pipelines.GetByName(ctx, pipelineName)

View File

@ -26,9 +26,11 @@ func TestEmptyBundleDeploy(t *testing.T) {
f.Close() f.Close()
// deploy empty bundle // deploy empty bundle
deployBundle(t, ctx, tmpDir) err = deployBundle(t, ctx, tmpDir)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, tmpDir) err = destroyBundle(t, ctx, tmpDir)
require.NoError(t, err)
}) })
} }

View File

@ -13,14 +13,17 @@ func TestPythonWheelTaskWithEnvironmentsDeployAndRun(t *testing.T) {
ctx, _ := acc.WorkspaceTest(t) ctx, _ := acc.WorkspaceTest(t)
bundleRoot := initTestTemplate(t, ctx, "python_wheel_task_with_environments", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "python_wheel_task_with_environments", map[string]any{
"unique_id": uuid.New().String(), "unique_id": uuid.New().String(),
}) })
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
out, err := runResource(t, ctx, bundleRoot, "some_other_job") out, err := runResource(t, ctx, bundleRoot, "some_other_job")

View File

@ -12,7 +12,6 @@ import (
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/filer" "github.com/databricks/cli/libs/filer"
"github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/compute" "github.com/databricks/databricks-sdk-go/service/compute"
@ -26,21 +25,22 @@ func TestGenerateFromExistingJobAndDeploy(t *testing.T) {
gt := &generateJobTest{T: wt, w: wt.W} gt := &generateJobTest{T: wt, w: wt.W}
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "with_includes", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "with_includes", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
jobId := gt.createTestJob(ctx) jobId := gt.createTestJob(ctx)
t.Cleanup(func() { t.Cleanup(func() {
gt.destroyJob(ctx, jobId) gt.destroyJob(ctx, jobId)
}) })
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "job", c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "job",
"--existing-job-id", fmt.Sprint(jobId), "--existing-job-id", fmt.Sprint(jobId),
"--config-dir", filepath.Join(bundleRoot, "resources"), "--config-dir", filepath.Join(bundleRoot, "resources"),
"--source-dir", filepath.Join(bundleRoot, "src")) "--source-dir", filepath.Join(bundleRoot, "src"))
_, _, err := c.Run() _, _, err = c.Run()
require.NoError(t, err) require.NoError(t, err)
_, err = os.Stat(filepath.Join(bundleRoot, "src", "test.py")) _, err = os.Stat(filepath.Join(bundleRoot, "src", "test.py"))
@ -61,9 +61,11 @@ func TestGenerateFromExistingJobAndDeploy(t *testing.T) {
require.Contains(t, generatedYaml, "spark_version: 13.3.x-scala2.12") require.Contains(t, generatedYaml, "spark_version: 13.3.x-scala2.12")
require.Contains(t, generatedYaml, "num_workers: 1") require.Contains(t, generatedYaml, "num_workers: 1")
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
} }
type generateJobTest struct { type generateJobTest struct {

View File

@ -12,7 +12,6 @@ import (
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil" "github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/filer" "github.com/databricks/cli/libs/filer"
"github.com/databricks/databricks-sdk-go" "github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/pipelines" "github.com/databricks/databricks-sdk-go/service/pipelines"
@ -25,21 +24,22 @@ func TestGenerateFromExistingPipelineAndDeploy(t *testing.T) {
gt := &generatePipelineTest{T: wt, w: wt.W} gt := &generatePipelineTest{T: wt, w: wt.W}
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "with_includes", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "with_includes", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
}) })
require.NoError(t, err)
pipelineId, name := gt.createTestPipeline(ctx) pipelineId, name := gt.createTestPipeline(ctx)
t.Cleanup(func() { t.Cleanup(func() {
gt.destroyPipeline(ctx, pipelineId) gt.destroyPipeline(ctx, pipelineId)
}) })
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot) t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "pipeline", c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "pipeline",
"--existing-pipeline-id", fmt.Sprint(pipelineId), "--existing-pipeline-id", fmt.Sprint(pipelineId),
"--config-dir", filepath.Join(bundleRoot, "resources"), "--config-dir", filepath.Join(bundleRoot, "resources"),
"--source-dir", filepath.Join(bundleRoot, "src")) "--source-dir", filepath.Join(bundleRoot, "src"))
_, _, err := c.Run() _, _, err = c.Run()
require.NoError(t, err) require.NoError(t, err)
_, err = os.Stat(filepath.Join(bundleRoot, "src", "notebook.py")) _, err = os.Stat(filepath.Join(bundleRoot, "src", "notebook.py"))
@ -69,9 +69,11 @@ func TestGenerateFromExistingPipelineAndDeploy(t *testing.T) {
require.Contains(t, generatedYaml, "- file:") require.Contains(t, generatedYaml, "- file:")
require.Contains(t, generatedYaml, fmt.Sprintf("path: %s", filepath.Join("..", "src", "test.py"))) require.Contains(t, generatedYaml, fmt.Sprintf("path: %s", filepath.Join("..", "src", "test.py")))
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
} }
type generatePipelineTest struct { type generatePipelineTest struct {

View File

@ -26,43 +26,46 @@ import (
const defaultSparkVersion = "13.3.x-snapshot-scala2.12" const defaultSparkVersion = "13.3.x-snapshot-scala2.12"
func initTestTemplate(t testutil.TestingT, ctx context.Context, templateName string, config map[string]any) string { func initTestTemplate(t testutil.TestingT, ctx context.Context, templateName string, config map[string]any) (string, error) {
bundleRoot := t.TempDir() bundleRoot := t.TempDir()
return initTestTemplateWithBundleRoot(t, ctx, templateName, config, bundleRoot) return initTestTemplateWithBundleRoot(t, ctx, templateName, config, bundleRoot)
} }
func initTestTemplateWithBundleRoot(t testutil.TestingT, ctx context.Context, templateName string, config map[string]any, bundleRoot string) string { func initTestTemplateWithBundleRoot(t testutil.TestingT, ctx context.Context, templateName string, config map[string]any, bundleRoot string) (string, error) {
templateRoot := filepath.Join("bundles", templateName) templateRoot := filepath.Join("bundles", templateName)
configFilePath := writeConfigFile(t, config) configFilePath, err := writeConfigFile(t, config)
if err != nil {
return "", err
}
ctx = root.SetWorkspaceClient(ctx, nil) ctx = root.SetWorkspaceClient(ctx, nil)
cmd := cmdio.NewIO(ctx, flags.OutputJSON, strings.NewReader(""), os.Stdout, os.Stderr, "", "bundles") cmd := cmdio.NewIO(flags.OutputJSON, strings.NewReader(""), os.Stdout, os.Stderr, "", "bundles")
ctx = cmdio.InContext(ctx, cmd) ctx = cmdio.InContext(ctx, cmd)
out, err := filer.NewLocalClient(bundleRoot) out, err := filer.NewLocalClient(bundleRoot)
require.NoError(t, err) require.NoError(t, err)
err = template.Materialize(ctx, configFilePath, os.DirFS(templateRoot), out) err = template.Materialize(ctx, configFilePath, os.DirFS(templateRoot), out)
require.NoError(t, err) return bundleRoot, err
return bundleRoot
} }
func writeConfigFile(t testutil.TestingT, config map[string]any) string { func writeConfigFile(t testutil.TestingT, config map[string]any) (string, error) {
bytes, err := json.Marshal(config) bytes, err := json.Marshal(config)
require.NoError(t, err) if err != nil {
return "", err
}
dir := t.TempDir() dir := t.TempDir()
filepath := filepath.Join(dir, "config.json") filepath := filepath.Join(dir, "config.json")
t.Log("Configuration for template: ", string(bytes)) t.Log("Configuration for template: ", string(bytes))
err = os.WriteFile(filepath, bytes, 0o644) err = os.WriteFile(filepath, bytes, 0o644)
require.NoError(t, err) return filepath, err
return filepath
} }
func validateBundle(t testutil.TestingT, ctx context.Context, path string) ([]byte, error) { func validateBundle(t testutil.TestingT, ctx context.Context, path string) ([]byte, error) {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
c := testcli.NewRunner(t, ctx, "bundle", "validate", "--output", "json") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "validate", "--output", "json")
stdout, _, err := c.Run() stdout, _, err := c.Run()
return stdout.Bytes(), err return stdout.Bytes(), err
} }
@ -80,41 +83,35 @@ func unmarshalConfig(t testutil.TestingT, data []byte) *bundle.Bundle {
return bundle return bundle
} }
func deployBundle(t testutil.TestingT, ctx context.Context, path string) { func deployBundle(t testutil.TestingT, ctx context.Context, path string) error {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock", "--auto-approve") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock", "--auto-approve")
_, _, err := c.Run() _, _, err := c.Run()
require.NoError(t, err) return err
} }
func deployBundleWithArgsErr(t testutil.TestingT, ctx context.Context, path string, args ...string) (string, string, error) { func deployBundleWithArgs(t testutil.TestingT, ctx context.Context, path string, args ...string) (string, string, error) {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
args = append([]string{"bundle", "deploy"}, args...) args = append([]string{"bundle", "deploy"}, args...)
c := testcli.NewRunner(t, ctx, args...) c := testcli.NewRunnerWithContext(t, ctx, args...)
stdout, stderr, err := c.Run() stdout, stderr, err := c.Run()
return stdout.String(), stderr.String(), err return stdout.String(), stderr.String(), err
} }
func deployBundleWithArgs(t testutil.TestingT, ctx context.Context, path string, args ...string) (string, string) { func deployBundleWithFlags(t testutil.TestingT, ctx context.Context, path string, flags []string) error {
stdout, stderr, err := deployBundleWithArgsErr(t, ctx, path, args...)
require.NoError(t, err)
return stdout, stderr
}
func deployBundleWithFlags(t testutil.TestingT, ctx context.Context, path string, flags []string) {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
args := []string{"bundle", "deploy", "--force-lock"} args := []string{"bundle", "deploy", "--force-lock"}
args = append(args, flags...) args = append(args, flags...)
c := testcli.NewRunner(t, ctx, args...) c := testcli.NewRunnerWithContext(t, ctx, args...)
_, _, err := c.Run() _, _, err := c.Run()
require.NoError(t, err) return err
} }
func runResource(t testutil.TestingT, ctx context.Context, path, key string) (string, error) { func runResource(t testutil.TestingT, ctx context.Context, path, key string) (string, error) {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
ctx = cmdio.NewContext(ctx, cmdio.Default()) ctx = cmdio.NewContext(ctx, cmdio.Default())
c := testcli.NewRunner(t, ctx, "bundle", "run", key) c := testcli.NewRunnerWithContext(t, ctx, "bundle", "run", key)
stdout, _, err := c.Run() stdout, _, err := c.Run()
return stdout.String(), err return stdout.String(), err
} }
@ -126,16 +123,16 @@ func runResourceWithParams(t testutil.TestingT, ctx context.Context, path, key s
args := make([]string, 0) args := make([]string, 0)
args = append(args, "bundle", "run", key) args = append(args, "bundle", "run", key)
args = append(args, params...) args = append(args, params...)
c := testcli.NewRunner(t, ctx, args...) c := testcli.NewRunnerWithContext(t, ctx, args...)
stdout, _, err := c.Run() stdout, _, err := c.Run()
return stdout.String(), err return stdout.String(), err
} }
func destroyBundle(t testutil.TestingT, ctx context.Context, path string) { func destroyBundle(t testutil.TestingT, ctx context.Context, path string) error {
ctx = env.Set(ctx, "BUNDLE_ROOT", path) ctx = env.Set(ctx, "BUNDLE_ROOT", path)
c := testcli.NewRunner(t, ctx, "bundle", "destroy", "--auto-approve") c := testcli.NewRunnerWithContext(t, ctx, "bundle", "destroy", "--auto-approve")
_, _, err := c.Run() _, _, err := c.Run()
require.NoError(t, err) return err
} }
func getBundleRemoteRootPath(w *databricks.WorkspaceClient, t testutil.TestingT, uniqueId string) string { func getBundleRemoteRootPath(w *databricks.WorkspaceClient, t testutil.TestingT, uniqueId string) string {
@ -146,20 +143,16 @@ func getBundleRemoteRootPath(w *databricks.WorkspaceClient, t testutil.TestingT,
return root return root
} }
func blackBoxRun(t testutil.TestingT, ctx context.Context, root string, args ...string) (stdout, stderr string) { func blackBoxRun(t testutil.TestingT, root string, args ...string) (stdout, stderr string) {
gitRoot, err := folders.FindDirWithLeaf(".", ".git") gitRoot, err := folders.FindDirWithLeaf(".", ".git")
require.NoError(t, err) require.NoError(t, err)
t.Setenv("BUNDLE_ROOT", root)
// Create the command // Create the command
cmd := exec.Command("go", append([]string{"run", "main.go"}, args...)...) cmd := exec.Command("go", append([]string{"run", "main.go"}, args...)...)
cmd.Dir = gitRoot cmd.Dir = gitRoot
// Configure the environment
ctx = env.Set(ctx, "BUNDLE_ROOT", root)
for key, value := range env.All(ctx) {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, value))
}
// Create buffers to capture output // Create buffers to capture output
var outBuffer, errBuffer bytes.Buffer var outBuffer, errBuffer bytes.Buffer
cmd.Stdout = &outBuffer cmd.Stdout = &outBuffer

View File

@ -20,9 +20,8 @@ import (
) )
func TestBundleInitErrorOnUnknownFields(t *testing.T) { func TestBundleInitErrorOnUnknownFields(t *testing.T) {
ctx := context.Background()
tmpDir := t.TempDir() tmpDir := t.TempDir()
_, _, err := testcli.RequireErrorRun(t, ctx, "bundle", "init", "./testdata/init/field-does-not-exist", "--output-dir", tmpDir) _, _, err := testcli.RequireErrorRun(t, "bundle", "init", "./testdata/init/field-does-not-exist", "--output-dir", tmpDir)
assert.EqualError(t, err, "failed to compute file content for bar.tmpl. variable \"does_not_exist\" not defined") assert.EqualError(t, err, "failed to compute file content for bar.tmpl. variable \"does_not_exist\" not defined")
} }
@ -39,7 +38,7 @@ func TestBundleInitErrorOnUnknownFields(t *testing.T) {
// make changes that can break the MLOps Stacks DAB. In which case we should // make changes that can break the MLOps Stacks DAB. In which case we should
// skip this test until the MLOps Stacks DAB is updated to work again. // skip this test until the MLOps Stacks DAB is updated to work again.
func TestBundleInitOnMlopsStacks(t *testing.T) { func TestBundleInitOnMlopsStacks(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t) _, wt := acc.WorkspaceTest(t)
w := wt.W w := wt.W
tmpDir1 := t.TempDir() tmpDir1 := t.TempDir()
@ -62,7 +61,7 @@ func TestBundleInitOnMlopsStacks(t *testing.T) {
// Run bundle init // Run bundle init
assert.NoFileExists(t, filepath.Join(tmpDir2, "repo_name", projectName, "README.md")) assert.NoFileExists(t, filepath.Join(tmpDir2, "repo_name", projectName, "README.md"))
testcli.RequireSuccessfulRun(t, ctx, "bundle", "init", "mlops-stacks", "--output-dir", tmpDir2, "--config-file", filepath.Join(tmpDir1, "config.json")) testcli.RequireSuccessfulRun(t, "bundle", "init", "mlops-stacks", "--output-dir", tmpDir2, "--config-file", filepath.Join(tmpDir1, "config.json"))
// Assert that the README.md file was created // Assert that the README.md file was created
contents := testutil.ReadFile(t, filepath.Join(tmpDir2, "repo_name", projectName, "README.md")) contents := testutil.ReadFile(t, filepath.Join(tmpDir2, "repo_name", projectName, "README.md"))
@ -70,17 +69,17 @@ func TestBundleInitOnMlopsStacks(t *testing.T) {
// Validate the stack // Validate the stack
testutil.Chdir(t, filepath.Join(tmpDir2, "repo_name", projectName)) testutil.Chdir(t, filepath.Join(tmpDir2, "repo_name", projectName))
testcli.RequireSuccessfulRun(t, ctx, "bundle", "validate") testcli.RequireSuccessfulRun(t, "bundle", "validate")
// Deploy the stack // Deploy the stack
testcli.RequireSuccessfulRun(t, ctx, "bundle", "deploy") testcli.RequireSuccessfulRun(t, "bundle", "deploy")
t.Cleanup(func() { t.Cleanup(func() {
// Delete the stack // Delete the stack
testcli.RequireSuccessfulRun(t, ctx, "bundle", "destroy", "--auto-approve") testcli.RequireSuccessfulRun(t, "bundle", "destroy", "--auto-approve")
}) })
// Get summary of the bundle deployment // Get summary of the bundle deployment
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "bundle", "summary", "--output", "json") stdout, _ := testcli.RequireSuccessfulRun(t, "bundle", "summary", "--output", "json")
summary := &config.Root{} summary := &config.Root{}
err = json.Unmarshal(stdout.Bytes(), summary) err = json.Unmarshal(stdout.Bytes(), summary)
require.NoError(t, err) require.NoError(t, err)
@ -157,7 +156,7 @@ func TestBundleInitHelpers(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Run bundle init. // Run bundle init.
testcli.RequireSuccessfulRun(t, ctx, "bundle", "init", tmpDir, "--output-dir", tmpDir2) testcli.RequireSuccessfulRun(t, "bundle", "init", tmpDir, "--output-dir", tmpDir2)
// Assert that the helper function was correctly computed. // Assert that the helper function was correctly computed.
contents := testutil.ReadFile(t, filepath.Join(tmpDir2, "foo.txt")) contents := testutil.ReadFile(t, filepath.Join(tmpDir2, "foo.txt"))

View File

@ -24,18 +24,21 @@ func TestJobsMetadataFile(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "job_metadata", map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, "job_metadata", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
// deploy bundle // deploy bundle
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Cleanup the deployed bundle // Cleanup the deployed bundle
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
// assert job 1 is created // assert job 1 is created

View File

@ -27,14 +27,16 @@ func TestLocalStateStaleness(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String() uniqueId := uuid.New().String()
initialize := func() string { initialize := func() string {
root := initTestTemplate(t, ctx, "basic", map[string]any{ root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId, "unique_id": uniqueId,
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion, "spark_version": defaultSparkVersion,
}) })
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, root) err = destroyBundle(t, ctx, root)
require.NoError(t, err)
}) })
return root return root
@ -46,13 +48,16 @@ func TestLocalStateStaleness(t *testing.T) {
bundleB := initialize() bundleB := initialize()
// 1) Deploy bundle A // 1) Deploy bundle A
deployBundle(t, ctx, bundleA) err = deployBundle(t, ctx, bundleA)
require.NoError(t, err)
// 2) Deploy bundle B // 2) Deploy bundle B
deployBundle(t, ctx, bundleB) err = deployBundle(t, ctx, bundleB)
require.NoError(t, err)
// 3) Deploy bundle A again // 3) Deploy bundle A again
deployBundle(t, ctx, bundleA) err = deployBundle(t, ctx, bundleA)
require.NoError(t, err)
// Assert that there is only a single job in the workspace corresponding to this bundle. // Assert that there is only a single job in the workspace corresponding to this bundle.
iter := w.Jobs.List(context.Background(), jobs.ListJobsRequest{ iter := w.Jobs.List(context.Background(), jobs.ListJobsRequest{

View File

@ -15,18 +15,21 @@ func runPythonWheelTest(t *testing.T, templateName, sparkVersion string, pythonW
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
instancePoolId := env.Get(ctx, "TEST_INSTANCE_POOL_ID") instancePoolId := env.Get(ctx, "TEST_INSTANCE_POOL_ID")
bundleRoot := initTestTemplate(t, ctx, templateName, map[string]any{ bundleRoot, err := initTestTemplate(t, ctx, templateName, map[string]any{
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"unique_id": uuid.New().String(), "unique_id": uuid.New().String(),
"spark_version": sparkVersion, "spark_version": sparkVersion,
"python_wheel_wrapper": pythonWheelWrapper, "python_wheel_wrapper": pythonWheelWrapper,
"instance_pool_id": instancePoolId, "instance_pool_id": instancePoolId,
}) })
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
out, err := runResource(t, ctx, bundleRoot, "some_other_job") out, err := runResource(t, ctx, bundleRoot, "some_other_job")

View File

@ -15,7 +15,7 @@ func runSparkJarTestCommon(t *testing.T, ctx context.Context, sparkVersion, arti
nodeTypeId := testutil.GetCloud(t).NodeTypeID() nodeTypeId := testutil.GetCloud(t).NodeTypeID()
tmpDir := t.TempDir() tmpDir := t.TempDir()
instancePoolId := env.Get(ctx, "TEST_INSTANCE_POOL_ID") instancePoolId := env.Get(ctx, "TEST_INSTANCE_POOL_ID")
bundleRoot := initTestTemplateWithBundleRoot(t, ctx, "spark_jar_task", map[string]any{ bundleRoot, err := initTestTemplateWithBundleRoot(t, ctx, "spark_jar_task", map[string]any{
"node_type_id": nodeTypeId, "node_type_id": nodeTypeId,
"unique_id": uuid.New().String(), "unique_id": uuid.New().String(),
"spark_version": sparkVersion, "spark_version": sparkVersion,
@ -23,11 +23,14 @@ func runSparkJarTestCommon(t *testing.T, ctx context.Context, sparkVersion, arti
"artifact_path": artifactPath, "artifact_path": artifactPath,
"instance_pool_id": instancePoolId, "instance_pool_id": instancePoolId,
}, tmpDir) }, tmpDir)
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot) err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot) err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
}) })
out, err := runResource(t, ctx, bundleRoot, "jar_job") out, err := runResource(t, ctx, bundleRoot, "jar_job")

View File

@ -1,7 +1,6 @@
package alerts_test package alerts_test
import ( import (
"context"
"testing" "testing"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
@ -9,7 +8,6 @@ import (
) )
func TestAlertsCreateErrWhenNoArguments(t *testing.T) { func TestAlertsCreateErrWhenNoArguments(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "alerts-legacy", "create")
_, _, err := testcli.RequireErrorRun(t, ctx, "alerts-legacy", "create")
assert.Equal(t, "please provide command input in JSON format by specifying the --json flag", err.Error()) assert.Equal(t, "please provide command input in JSON format by specifying the --json flag", err.Error())
} }

View File

@ -1,7 +1,6 @@
package api_test package api_test
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"path" "path"
@ -17,9 +16,7 @@ import (
) )
func TestApiGet(t *testing.T) { func TestApiGet(t *testing.T) {
ctx := context.Background() stdout, _ := testcli.RequireSuccessfulRun(t, "api", "get", "/api/2.0/preview/scim/v2/Me")
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "api", "get", "/api/2.0/preview/scim/v2/Me")
// Deserialize SCIM API response. // Deserialize SCIM API response.
var out map[string]any var out map[string]any
@ -32,8 +29,6 @@ func TestApiGet(t *testing.T) {
} }
func TestApiPost(t *testing.T) { func TestApiPost(t *testing.T) {
ctx := context.Background()
if testutil.GetCloud(t) == testutil.GCP { if testutil.GetCloud(t) == testutil.GCP {
t.Skip("DBFS REST API is disabled on gcp") t.Skip("DBFS REST API is disabled on gcp")
} }
@ -46,11 +41,11 @@ func TestApiPost(t *testing.T) {
// Post to mkdir // Post to mkdir
{ {
testcli.RequireSuccessfulRun(t, ctx, "api", "post", "--json=@"+requestPath, "/api/2.0/dbfs/mkdirs") testcli.RequireSuccessfulRun(t, "api", "post", "--json=@"+requestPath, "/api/2.0/dbfs/mkdirs")
} }
// Post to delete // Post to delete
{ {
testcli.RequireSuccessfulRun(t, ctx, "api", "post", "--json=@"+requestPath, "/api/2.0/dbfs/delete") testcli.RequireSuccessfulRun(t, "api", "post", "--json=@"+requestPath, "/api/2.0/dbfs/delete")
} }
} }

View File

@ -13,8 +13,7 @@ import (
func TestAuthDescribeSuccess(t *testing.T) { func TestAuthDescribeSuccess(t *testing.T) {
t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010") t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010")
ctx := context.Background() stdout, _ := testcli.RequireSuccessfulRun(t, "auth", "describe")
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "auth", "describe")
outStr := stdout.String() outStr := stdout.String()
w, err := databricks.NewWorkspaceClient(&databricks.Config{}) w, err := databricks.NewWorkspaceClient(&databricks.Config{})
@ -35,8 +34,7 @@ func TestAuthDescribeSuccess(t *testing.T) {
func TestAuthDescribeFailure(t *testing.T) { func TestAuthDescribeFailure(t *testing.T) {
t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010") t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010")
ctx := context.Background() stdout, _ := testcli.RequireSuccessfulRun(t, "auth", "describe", "--profile", "nonexistent")
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "auth", "describe", "--profile", "nonexistent")
outStr := stdout.String() outStr := stdout.String()
require.NotEmpty(t, outStr) require.NotEmpty(t, outStr)

View File

@ -1,7 +1,6 @@
package clusters_test package clusters_test
import ( import (
"context"
"fmt" "fmt"
"regexp" "regexp"
"testing" "testing"
@ -15,8 +14,7 @@ import (
) )
func TestClustersList(t *testing.T) { func TestClustersList(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "clusters", "list")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "clusters", "list")
outStr := stdout.String() outStr := stdout.String()
assert.Contains(t, outStr, "ID") assert.Contains(t, outStr, "ID")
assert.Contains(t, outStr, "Name") assert.Contains(t, outStr, "Name")
@ -29,17 +27,15 @@ func TestClustersList(t *testing.T) {
} }
func TestClustersGet(t *testing.T) { func TestClustersGet(t *testing.T) {
ctx := context.Background()
clusterId := findValidClusterID(t) clusterId := findValidClusterID(t)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "clusters", "get", clusterId) stdout, stderr := testcli.RequireSuccessfulRun(t, "clusters", "get", clusterId)
outStr := stdout.String() outStr := stdout.String()
assert.Contains(t, outStr, fmt.Sprintf(`"cluster_id":"%s"`, clusterId)) assert.Contains(t, outStr, fmt.Sprintf(`"cluster_id":"%s"`, clusterId))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
} }
func TestClusterCreateErrorWhenNoArguments(t *testing.T) { func TestClusterCreateErrorWhenNoArguments(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "clusters", "create")
_, _, err := testcli.RequireErrorRun(t, ctx, "clusters", "create")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0") assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
} }

View File

@ -23,13 +23,11 @@ func TestFsCat(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories) err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "cat", path.Join(tmpDir, "hello.txt")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "cat", path.Join(tmpDir, "hello.txt"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "abcd", stdout.String()) assert.Equal(t, "abcd", stdout.String())
}) })
@ -45,13 +43,11 @@ func TestFsCatOnADir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "dir1") err := f.Mkdir(context.Background(), "dir1")
require.NoError(t, err) require.NoError(t, err)
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "cat", path.Join(tmpDir, "dir1")) _, _, err = testcli.RequireErrorRun(t, "fs", "cat", path.Join(tmpDir, "dir1"))
assert.ErrorAs(t, err, &filer.NotAFile{}) assert.ErrorAs(t, err, &filer.NotAFile{})
}) })
} }
@ -66,18 +62,16 @@ func TestFsCatOnNonExistentFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t) _, tmpDir := tc.setupFiler(t)
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cat", path.Join(tmpDir, "non-existent-file")) _, _, err := testcli.RequireErrorRun(t, "fs", "cat", path.Join(tmpDir, "non-existent-file"))
assert.ErrorIs(t, err, fs.ErrNotExist) assert.ErrorIs(t, err, fs.ErrNotExist)
}) })
} }
} }
func TestFsCatForDbfsInvalidScheme(t *testing.T) { func TestFsCatForDbfsInvalidScheme(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "fs", "cat", "dab:/non-existent-file")
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cat", "dab:/non-existent-file")
assert.ErrorContains(t, err, "invalid scheme: dab") assert.ErrorContains(t, err, "invalid scheme: dab")
} }
@ -92,6 +86,6 @@ func TestFsCatDoesNotSupportOutputModeJson(t *testing.T) {
err = f.Write(ctx, "hello.txt", strings.NewReader("abc")) err = f.Write(ctx, "hello.txt", strings.NewReader("abc"))
require.NoError(t, err) require.NoError(t, err)
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "cat", "dbfs:"+path.Join(tmpDir, "hello.txt"), "--output=json") _, _, err = testcli.RequireErrorRun(t, "fs", "cat", "dbfs:"+path.Join(tmpDir, "hello.txt"), "--output=json")
assert.ErrorContains(t, err, "json output not supported") assert.ErrorContains(t, err, "json output not supported")
} }

View File

@ -19,11 +19,10 @@ func setupCompletionFile(t *testing.T, f filer.Filer) {
} }
func TestFsCompletion(t *testing.T) { func TestFsCompletion(t *testing.T) {
ctx := context.Background()
f, tmpDir := setupDbfsFiler(t) f, tmpDir := setupDbfsFiler(t)
setupCompletionFile(t, f) setupCompletionFile(t, f)
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "__complete", "fs", "ls", tmpDir+"/") stdout, _ := testcli.RequireSuccessfulRun(t, "__complete", "fs", "ls", tmpDir+"/")
expectedOutput := fmt.Sprintf("%s/dir1/\n:2\n", tmpDir) expectedOutput := fmt.Sprintf("%s/dir1/\n:2\n", tmpDir)
assert.Equal(t, expectedOutput, stdout.String()) assert.Equal(t, expectedOutput, stdout.String())
} }

View File

@ -131,12 +131,11 @@ func TestFsCpDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", sourceDir, targetDir, "--recursive") testcli.RequireSuccessfulRun(t, "fs", "cp", sourceDir, targetDir, "--recursive")
assertTargetDir(t, context.Background(), targetFiler) assertTargetDir(t, context.Background(), targetFiler)
}) })
@ -152,12 +151,11 @@ func TestFsCpFileToFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceFile(t, context.Background(), sourceFiler) setupSourceFile(t, context.Background(), sourceFiler)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "foo.txt"), path.Join(targetDir, "bar.txt")) testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "foo.txt"), path.Join(targetDir, "bar.txt"))
assertTargetFile(t, context.Background(), targetFiler, "bar.txt") assertTargetFile(t, context.Background(), targetFiler, "bar.txt")
}) })
@ -173,12 +171,11 @@ func TestFsCpFileToDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceFile(t, context.Background(), sourceFiler) setupSourceFile(t, context.Background(), sourceFiler)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "foo.txt"), targetDir) testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "foo.txt"), targetDir)
assertTargetFile(t, context.Background(), targetFiler, "foo.txt") assertTargetFile(t, context.Background(), targetFiler, "foo.txt")
}) })
@ -197,7 +194,7 @@ func TestFsCpFileToDirForWindowsPaths(t *testing.T) {
windowsPath := filepath.Join(filepath.FromSlash(sourceDir), "foo.txt") windowsPath := filepath.Join(filepath.FromSlash(sourceDir), "foo.txt")
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", windowsPath, targetDir) testcli.RequireSuccessfulRun(t, "fs", "cp", windowsPath, targetDir)
assertTargetFile(t, ctx, targetFiler, "foo.txt") assertTargetFile(t, ctx, targetFiler, "foo.txt")
} }
@ -210,7 +207,6 @@ func TestFsCpDirToDirFileNotOverwritten(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -219,7 +215,7 @@ func TestFsCpDirToDirFileNotOverwritten(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", sourceDir, targetDir, "--recursive") testcli.RequireSuccessfulRun(t, "fs", "cp", sourceDir, targetDir, "--recursive")
assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "this should not be overwritten") assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "this should not be overwritten")
assertFileContent(t, context.Background(), targetFiler, "query.sql", "SELECT 1") assertFileContent(t, context.Background(), targetFiler, "query.sql", "SELECT 1")
assertFileContent(t, context.Background(), targetFiler, "pyNb.py", "# Databricks notebook source\nprint(123)") assertFileContent(t, context.Background(), targetFiler, "pyNb.py", "# Databricks notebook source\nprint(123)")
@ -236,7 +232,6 @@ func TestFsCpFileToDirFileNotOverwritten(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -245,7 +240,7 @@ func TestFsCpFileToDirFileNotOverwritten(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c")) testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c"))
assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "this should not be overwritten") assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "this should not be overwritten")
}) })
} }
@ -260,7 +255,6 @@ func TestFsCpFileToFileFileNotOverwritten(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -269,7 +263,7 @@ func TestFsCpFileToFileFileNotOverwritten(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/dontoverwrite.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/dontoverwrite.txt", strings.NewReader("this should not be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c/dontoverwrite.txt")) testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c/dontoverwrite.txt"))
assertFileContent(t, context.Background(), targetFiler, "a/b/c/dontoverwrite.txt", "this should not be overwritten") assertFileContent(t, context.Background(), targetFiler, "a/b/c/dontoverwrite.txt", "this should not be overwritten")
}) })
} }
@ -284,7 +278,6 @@ func TestFsCpDirToDirWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -293,7 +286,7 @@ func TestFsCpDirToDirWithOverwriteFlag(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", sourceDir, targetDir, "--recursive", "--overwrite") testcli.RequireSuccessfulRun(t, "fs", "cp", sourceDir, targetDir, "--recursive", "--overwrite")
assertTargetDir(t, context.Background(), targetFiler) assertTargetDir(t, context.Background(), targetFiler)
}) })
} }
@ -308,7 +301,6 @@ func TestFsCpFileToFileWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -317,7 +309,7 @@ func TestFsCpFileToFileWithOverwriteFlag(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/overwritten.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/overwritten.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c/overwritten.txt"), "--overwrite") testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c/overwritten.txt"), "--overwrite")
assertFileContent(t, context.Background(), targetFiler, "a/b/c/overwritten.txt", "hello, world\n") assertFileContent(t, context.Background(), targetFiler, "a/b/c/overwritten.txt", "hello, world\n")
}) })
} }
@ -332,7 +324,6 @@ func TestFsCpFileToDirWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -341,7 +332,7 @@ func TestFsCpFileToDirWithOverwriteFlag(t *testing.T) {
err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "a/b/c/hello.txt", strings.NewReader("this should be overwritten"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c"), "--overwrite") testcli.RequireSuccessfulRun(t, "fs", "cp", path.Join(sourceDir, "a/b/c/hello.txt"), path.Join(targetDir, "a/b/c"), "--overwrite")
assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "hello, world\n") assertFileContent(t, context.Background(), targetFiler, "a/b/c/hello.txt", "hello, world\n")
}) })
} }
@ -356,10 +347,9 @@ func TestFsCpErrorsWhenSourceIsDirWithoutRecursiveFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t) _, tmpDir := tc.setupFiler(t)
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cp", path.Join(tmpDir), path.Join(tmpDir, "foobar")) _, _, err := testcli.RequireErrorRun(t, "fs", "cp", path.Join(tmpDir), path.Join(tmpDir, "foobar"))
r := regexp.MustCompile("source path .* is a directory. Please specify the --recursive flag") r := regexp.MustCompile("source path .* is a directory. Please specify the --recursive flag")
assert.Regexp(t, r, err.Error()) assert.Regexp(t, r, err.Error())
}) })
@ -367,8 +357,7 @@ func TestFsCpErrorsWhenSourceIsDirWithoutRecursiveFlag(t *testing.T) {
} }
func TestFsCpErrorsOnInvalidScheme(t *testing.T) { func TestFsCpErrorsOnInvalidScheme(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "fs", "cp", "dbfs:/a", "https:/b")
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cp", "dbfs:/a", "https:/b")
assert.Equal(t, "invalid scheme: https", err.Error()) assert.Equal(t, "invalid scheme: https", err.Error())
} }
@ -381,7 +370,6 @@ func TestFsCpSourceIsDirectoryButTargetIsFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t) sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t) targetFiler, targetDir := tc.setupTarget(t)
setupSourceDir(t, context.Background(), sourceFiler) setupSourceDir(t, context.Background(), sourceFiler)
@ -390,7 +378,7 @@ func TestFsCpSourceIsDirectoryButTargetIsFile(t *testing.T) {
err := targetFiler.Write(context.Background(), "my_target", strings.NewReader("I'll block any attempts to recursively copy"), filer.CreateParentDirectories) err := targetFiler.Write(context.Background(), "my_target", strings.NewReader("I'll block any attempts to recursively copy"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "cp", sourceDir, path.Join(targetDir, "my_target"), "--recursive") _, _, err = testcli.RequireErrorRun(t, "fs", "cp", sourceDir, path.Join(targetDir, "my_target"), "--recursive")
assert.Error(t, err) assert.Error(t, err)
}) })
} }

View File

@ -49,11 +49,10 @@ func TestFsLs(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
setupLsFiles(t, f) setupLsFiles(t, f)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "ls", tmpDir, "--output=json") stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "ls", tmpDir, "--output=json")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
var parsedStdout []map[string]any var parsedStdout []map[string]any
@ -83,11 +82,10 @@ func TestFsLsWithAbsolutePaths(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
setupLsFiles(t, f) setupLsFiles(t, f)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "ls", tmpDir, "--output=json", "--absolute") stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "ls", tmpDir, "--output=json", "--absolute")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
var parsedStdout []map[string]any var parsedStdout []map[string]any
@ -116,12 +114,10 @@ func TestFsLsOnFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
setupLsFiles(t, f) setupLsFiles(t, f)
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "ls", path.Join(tmpDir, "a", "hello.txt"), "--output=json") _, _, err := testcli.RequireErrorRun(t, "fs", "ls", path.Join(tmpDir, "a", "hello.txt"), "--output=json")
assert.Regexp(t, regexp.MustCompile("not a directory: .*/a/hello.txt"), err.Error()) assert.Regexp(t, regexp.MustCompile("not a directory: .*/a/hello.txt"), err.Error())
assert.ErrorAs(t, err, &filer.NotADirectory{}) assert.ErrorAs(t, err, &filer.NotADirectory{})
}) })
@ -137,10 +133,9 @@ func TestFsLsOnEmptyDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t) _, tmpDir := tc.setupFiler(t)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "ls", tmpDir, "--output=json") stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "ls", tmpDir, "--output=json")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
var parsedStdout []map[string]any var parsedStdout []map[string]any
err := json.Unmarshal(stdout.Bytes(), &parsedStdout) err := json.Unmarshal(stdout.Bytes(), &parsedStdout)
@ -161,10 +156,9 @@ func TestFsLsForNonexistingDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t) _, tmpDir := tc.setupFiler(t)
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "ls", path.Join(tmpDir, "nonexistent"), "--output=json") _, _, err := testcli.RequireErrorRun(t, "fs", "ls", path.Join(tmpDir, "nonexistent"), "--output=json")
assert.ErrorIs(t, err, fs.ErrNotExist) assert.ErrorIs(t, err, fs.ErrNotExist)
assert.Regexp(t, regexp.MustCompile("no such directory: .*/nonexistent"), err.Error()) assert.Regexp(t, regexp.MustCompile("no such directory: .*/nonexistent"), err.Error())
}) })
@ -174,7 +168,6 @@ func TestFsLsForNonexistingDir(t *testing.T) {
func TestFsLsWithoutScheme(t *testing.T) { func TestFsLsWithoutScheme(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "fs", "ls", "/path-without-a-dbfs-scheme", "--output=json")
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "ls", "/path-without-a-dbfs-scheme", "--output=json")
assert.ErrorIs(t, err, fs.ErrNotExist) assert.ErrorIs(t, err, fs.ErrNotExist)
} }

View File

@ -22,11 +22,10 @@ func TestFsMkdir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
// create directory "a" // create directory "a"
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "mkdir", path.Join(tmpDir, "a")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "mkdir", path.Join(tmpDir, "a"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
@ -48,11 +47,10 @@ func TestFsMkdirCreatesIntermediateDirectories(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
// create directory "a/b/c" // create directory "a/b/c"
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "mkdir", path.Join(tmpDir, "a", "b", "c")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "mkdir", path.Join(tmpDir, "a", "b", "c"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
@ -86,7 +84,6 @@ func TestFsMkdirWhenDirectoryAlreadyExists(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
// create directory "a" // create directory "a"
@ -94,7 +91,7 @@ func TestFsMkdirWhenDirectoryAlreadyExists(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// assert run is successful without any errors // assert run is successful without any errors
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "mkdir", path.Join(tmpDir, "a")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "mkdir", path.Join(tmpDir, "a"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
}) })
@ -107,7 +104,6 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
t.Run("dbfs", func(t *testing.T) { t.Run("dbfs", func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := setupDbfsFiler(t) f, tmpDir := setupDbfsFiler(t)
// create file "hello" // create file "hello"
@ -115,7 +111,7 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// assert mkdir fails // assert mkdir fails
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "mkdir", path.Join(tmpDir, "hello")) _, _, err = testcli.RequireErrorRun(t, "fs", "mkdir", path.Join(tmpDir, "hello"))
// Different cloud providers or cloud configurations return different errors. // Different cloud providers or cloud configurations return different errors.
regex := regexp.MustCompile(`(^|: )Path is a file: .*$|(^|: )Cannot create directory .* because .* is an existing file\.$|(^|: )mkdirs\(hadoopPath: .*, permission: rwxrwxrwx\): failed$|(^|: )"The specified path already exists.".*$`) regex := regexp.MustCompile(`(^|: )Path is a file: .*$|(^|: )Cannot create directory .* because .* is an existing file\.$|(^|: )mkdirs\(hadoopPath: .*, permission: rwxrwxrwx\): failed$|(^|: )"The specified path already exists.".*$`)
@ -125,7 +121,6 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
t.Run("uc-volumes", func(t *testing.T) { t.Run("uc-volumes", func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := setupUcVolumesFiler(t) f, tmpDir := setupUcVolumesFiler(t)
// create file "hello" // create file "hello"
@ -133,7 +128,7 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// assert mkdir fails // assert mkdir fails
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "mkdir", path.Join(tmpDir, "hello")) _, _, err = testcli.RequireErrorRun(t, "fs", "mkdir", path.Join(tmpDir, "hello"))
assert.ErrorAs(t, err, &filer.FileAlreadyExistsError{}) assert.ErrorAs(t, err, &filer.FileAlreadyExistsError{})
}) })

View File

@ -23,7 +23,6 @@ func TestFsRmFile(t *testing.T) {
t.Parallel() t.Parallel()
// Create a file // Create a file
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories) err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories)
require.NoError(t, err) require.NoError(t, err)
@ -33,7 +32,7 @@ func TestFsRmFile(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Run rm command // Run rm command
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "rm", path.Join(tmpDir, "hello.txt")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "rm", path.Join(tmpDir, "hello.txt"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
@ -54,7 +53,6 @@ func TestFsRmEmptyDir(t *testing.T) {
t.Parallel() t.Parallel()
// Create a directory // Create a directory
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "a") err := f.Mkdir(context.Background(), "a")
require.NoError(t, err) require.NoError(t, err)
@ -64,7 +62,7 @@ func TestFsRmEmptyDir(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Run rm command // Run rm command
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "rm", path.Join(tmpDir, "a")) stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "rm", path.Join(tmpDir, "a"))
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
@ -85,7 +83,6 @@ func TestFsRmNonEmptyDirectory(t *testing.T) {
t.Parallel() t.Parallel()
// Create a directory // Create a directory
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "a") err := f.Mkdir(context.Background(), "a")
require.NoError(t, err) require.NoError(t, err)
@ -99,7 +96,7 @@ func TestFsRmNonEmptyDirectory(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Run rm command // Run rm command
_, _, err = testcli.RequireErrorRun(t, ctx, "fs", "rm", path.Join(tmpDir, "a")) _, _, err = testcli.RequireErrorRun(t, "fs", "rm", path.Join(tmpDir, "a"))
assert.ErrorIs(t, err, fs.ErrInvalid) assert.ErrorIs(t, err, fs.ErrInvalid)
assert.ErrorAs(t, err, &filer.DirectoryNotEmptyError{}) assert.ErrorAs(t, err, &filer.DirectoryNotEmptyError{})
}) })
@ -115,11 +112,10 @@ func TestFsRmForNonExistentFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t) _, tmpDir := tc.setupFiler(t)
// Expect error if file does not exist // Expect error if file does not exist
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "rm", path.Join(tmpDir, "does-not-exist")) _, _, err := testcli.RequireErrorRun(t, "fs", "rm", path.Join(tmpDir, "does-not-exist"))
assert.ErrorIs(t, err, fs.ErrNotExist) assert.ErrorIs(t, err, fs.ErrNotExist)
}) })
} }
@ -134,7 +130,6 @@ func TestFsRmDirRecursively(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t) f, tmpDir := tc.setupFiler(t)
// Create a directory // Create a directory
@ -150,7 +145,7 @@ func TestFsRmDirRecursively(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Run rm command // Run rm command
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "fs", "rm", path.Join(tmpDir, "a"), "--recursive") stdout, stderr := testcli.RequireSuccessfulRun(t, "fs", "rm", path.Join(tmpDir, "a"), "--recursive")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())

View File

@ -1,7 +1,6 @@
package jobs_test package jobs_test
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"testing" "testing"
@ -14,11 +13,10 @@ import (
func TestCreateJob(t *testing.T) { func TestCreateJob(t *testing.T) {
testutil.Require(t, testutil.Azure) testutil.Require(t, testutil.Azure)
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "jobs", "create", "--json", "@testdata/create_job_without_workers.json", "--log-level=debug")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "jobs", "create", "--json", "@testdata/create_job_without_workers.json", "--log-level=debug")
assert.Empty(t, stderr.String()) assert.Empty(t, stderr.String())
var output map[string]int var output map[string]int
err := json.Unmarshal(stdout.Bytes(), &output) err := json.Unmarshal(stdout.Bytes(), &output)
require.NoError(t, err) require.NoError(t, err)
testcli.RequireSuccessfulRun(t, ctx, "jobs", "delete", fmt.Sprint(output["job_id"]), "--log-level=debug") testcli.RequireSuccessfulRun(t, "jobs", "delete", fmt.Sprint(output["job_id"]), "--log-level=debug")
} }

View File

@ -53,7 +53,7 @@ func TestReposCreateWithProvider(t *testing.T) {
w := wt.W w := wt.W
repoPath := synthesizeTemporaryRepoPath(t, w, ctx) repoPath := synthesizeTemporaryRepoPath(t, w, ctx)
_, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "create", repoUrl, "gitHub", "--path", repoPath) _, stderr := testcli.RequireSuccessfulRun(t, "repos", "create", repoUrl, "gitHub", "--path", repoPath)
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Confirm the repo was created. // Confirm the repo was created.
@ -67,7 +67,7 @@ func TestReposCreateWithoutProvider(t *testing.T) {
w := wt.W w := wt.W
repoPath := synthesizeTemporaryRepoPath(t, w, ctx) repoPath := synthesizeTemporaryRepoPath(t, w, ctx)
_, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "create", repoUrl, "--path", repoPath) _, stderr := testcli.RequireSuccessfulRun(t, "repos", "create", repoUrl, "--path", repoPath)
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Confirm the repo was created. // Confirm the repo was created.
@ -83,22 +83,22 @@ func TestReposGet(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx) repoId, repoPath := createTemporaryRepo(t, w, ctx)
// Get by ID // Get by ID
byIdOutput, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "get", strconv.FormatInt(repoId, 10), "--output=json") byIdOutput, stderr := testcli.RequireSuccessfulRun(t, "repos", "get", strconv.FormatInt(repoId, 10), "--output=json")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Get by path // Get by path
byPathOutput, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "get", repoPath, "--output=json") byPathOutput, stderr := testcli.RequireSuccessfulRun(t, "repos", "get", repoPath, "--output=json")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Output should be the same // Output should be the same
assert.Equal(t, byIdOutput.String(), byPathOutput.String()) assert.Equal(t, byIdOutput.String(), byPathOutput.String())
// Get by path fails // Get by path fails
_, stderr, err := testcli.RequireErrorRun(t, ctx, "repos", "get", repoPath+"-doesntexist", "--output=json") _, stderr, err := testcli.RequireErrorRun(t, "repos", "get", repoPath+"-doesntexist", "--output=json")
assert.ErrorContains(t, err, "failed to look up repo") assert.ErrorContains(t, err, "failed to look up repo")
// Get by path resolves to something other than a repo // Get by path resolves to something other than a repo
_, stderr, err = testcli.RequireErrorRun(t, ctx, "repos", "get", "/Repos", "--output=json") _, stderr, err = testcli.RequireErrorRun(t, "repos", "get", "/Repos", "--output=json")
assert.ErrorContains(t, err, "is not a repo") assert.ErrorContains(t, err, "is not a repo")
} }
@ -109,11 +109,11 @@ func TestReposUpdate(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx) repoId, repoPath := createTemporaryRepo(t, w, ctx)
// Update by ID // Update by ID
byIdOutput, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "update", strconv.FormatInt(repoId, 10), "--branch", "ide") byIdOutput, stderr := testcli.RequireSuccessfulRun(t, "repos", "update", strconv.FormatInt(repoId, 10), "--branch", "ide")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Update by path // Update by path
byPathOutput, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "update", repoPath, "--branch", "ide") byPathOutput, stderr := testcli.RequireSuccessfulRun(t, "repos", "update", repoPath, "--branch", "ide")
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
// Output should be the same // Output should be the same
@ -127,7 +127,7 @@ func TestReposDeleteByID(t *testing.T) {
repoId, _ := createTemporaryRepo(t, w, ctx) repoId, _ := createTemporaryRepo(t, w, ctx)
// Delete by ID // Delete by ID
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "delete", strconv.FormatInt(repoId, 10)) stdout, stderr := testcli.RequireSuccessfulRun(t, "repos", "delete", strconv.FormatInt(repoId, 10))
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
@ -143,7 +143,7 @@ func TestReposDeleteByPath(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx) repoId, repoPath := createTemporaryRepo(t, w, ctx)
// Delete by path // Delete by path
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "repos", "delete", repoPath) stdout, stderr := testcli.RequireSuccessfulRun(t, "repos", "delete", repoPath)
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())

View File

@ -15,8 +15,7 @@ import (
) )
func TestSecretsCreateScopeErrWhenNoArguments(t *testing.T) { func TestSecretsCreateScopeErrWhenNoArguments(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "secrets", "create-scope")
_, _, err := testcli.RequireErrorRun(t, ctx, "secrets", "create-scope")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0") assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
} }
@ -70,7 +69,7 @@ func TestSecretsPutSecretStringValue(tt *testing.T) {
key := "test-key" key := "test-key"
value := "test-value\nwith-newlines\n" value := "test-value\nwith-newlines\n"
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "secrets", "put-secret", scope, key, "--string-value", value) stdout, stderr := testcli.RequireSuccessfulRun(t, "secrets", "put-secret", scope, key, "--string-value", value)
assert.Empty(t, stdout) assert.Empty(t, stdout)
assert.Empty(t, stderr) assert.Empty(t, stderr)
@ -84,7 +83,7 @@ func TestSecretsPutSecretBytesValue(tt *testing.T) {
key := "test-key" key := "test-key"
value := []byte{0x00, 0x01, 0x02, 0x03} value := []byte{0x00, 0x01, 0x02, 0x03}
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "secrets", "put-secret", scope, key, "--bytes-value", string(value)) stdout, stderr := testcli.RequireSuccessfulRun(t, "secrets", "put-secret", scope, key, "--bytes-value", string(value))
assert.Empty(t, stdout) assert.Empty(t, stdout)
assert.Empty(t, stderr) assert.Empty(t, stderr)

View File

@ -10,12 +10,12 @@ import (
) )
func TestStorageCredentialsListRendersResponse(t *testing.T) { func TestStorageCredentialsListRendersResponse(t *testing.T) {
ctx, _ := acc.WorkspaceTest(t) _, _ = acc.WorkspaceTest(t)
// Check if metastore is assigned for the workspace, otherwise test will fail // Check if metastore is assigned for the workspace, otherwise test will fail
t.Log(testutil.GetEnvOrSkipTest(t, "TEST_METASTORE_ID")) t.Log(testutil.GetEnvOrSkipTest(t, "TEST_METASTORE_ID"))
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "storage-credentials", "list") stdout, stderr := testcli.RequireSuccessfulRun(t, "storage-credentials", "list")
assert.NotEmpty(t, stdout) assert.NotEmpty(t, stdout)
assert.Empty(t, stderr) assert.Empty(t, stderr)
} }

View File

@ -72,8 +72,8 @@ type syncTest struct {
remoteRoot string remoteRoot string
} }
func setupSyncTest(t *testing.T, args ...string) (context.Context, *syncTest) { func setupSyncTest(t *testing.T, args ...string) *syncTest {
ctx, wt := acc.WorkspaceTest(t) _, wt := acc.WorkspaceTest(t)
w := wt.W w := wt.W
localRoot := t.TempDir() localRoot := t.TempDir()
@ -90,10 +90,10 @@ func setupSyncTest(t *testing.T, args ...string) (context.Context, *syncTest) {
"json", "json",
}, args...) }, args...)
c := testcli.NewRunner(t, ctx, args...) c := testcli.NewRunner(t, args...)
c.RunBackground() c.RunBackground()
return ctx, &syncTest{ return &syncTest{
t: t, t: t,
c: c, c: c,
w: w, w: w,
@ -231,7 +231,8 @@ func (a *syncTest) snapshotContains(files []string) {
} }
func TestSyncFullFileSync(t *testing.T) { func TestSyncFullFileSync(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--full", "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--full", "--watch")
// .gitignore is created by the sync process to enforce .databricks is not synced // .gitignore is created by the sync process to enforce .databricks is not synced
assertSync.waitForCompletionMarker() assertSync.waitForCompletionMarker()
@ -262,7 +263,8 @@ func TestSyncFullFileSync(t *testing.T) {
} }
func TestSyncIncrementalFileSync(t *testing.T) { func TestSyncIncrementalFileSync(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// .gitignore is created by the sync process to enforce .databricks is not synced // .gitignore is created by the sync process to enforce .databricks is not synced
assertSync.waitForCompletionMarker() assertSync.waitForCompletionMarker()
@ -295,7 +297,8 @@ func TestSyncIncrementalFileSync(t *testing.T) {
} }
func TestSyncNestedFolderSync(t *testing.T) { func TestSyncNestedFolderSync(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// .gitignore is created by the sync process to enforce .databricks is not synced // .gitignore is created by the sync process to enforce .databricks is not synced
assertSync.waitForCompletionMarker() assertSync.waitForCompletionMarker()
@ -322,7 +325,8 @@ func TestSyncNestedFolderSync(t *testing.T) {
} }
func TestSyncNestedFolderDoesntFailOnNonEmptyDirectory(t *testing.T) { func TestSyncNestedFolderDoesntFailOnNonEmptyDirectory(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// .gitignore is created by the sync process to enforce .databricks is not synced // .gitignore is created by the sync process to enforce .databricks is not synced
assertSync.waitForCompletionMarker() assertSync.waitForCompletionMarker()
@ -354,7 +358,8 @@ func TestSyncNestedFolderDoesntFailOnNonEmptyDirectory(t *testing.T) {
} }
func TestSyncNestedSpacePlusAndHashAreEscapedSync(t *testing.T) { func TestSyncNestedSpacePlusAndHashAreEscapedSync(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// .gitignore is created by the sync process to enforce .databricks is not synced // .gitignore is created by the sync process to enforce .databricks is not synced
assertSync.waitForCompletionMarker() assertSync.waitForCompletionMarker()
@ -389,7 +394,8 @@ func TestSyncNestedSpacePlusAndHashAreEscapedSync(t *testing.T) {
// In the above scenario sync should delete the empty folder and add foo to the remote // In the above scenario sync should delete the empty folder and add foo to the remote
// file system // file system
func TestSyncIncrementalFileOverwritesFolder(t *testing.T) { func TestSyncIncrementalFileOverwritesFolder(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create foo/bar.txt // create foo/bar.txt
localFilePath := filepath.Join(assertSync.localRoot, "foo/bar.txt") localFilePath := filepath.Join(assertSync.localRoot, "foo/bar.txt")
@ -418,7 +424,8 @@ func TestSyncIncrementalFileOverwritesFolder(t *testing.T) {
} }
func TestSyncIncrementalSyncPythonNotebookToFile(t *testing.T) { func TestSyncIncrementalSyncPythonNotebookToFile(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create python notebook // create python notebook
localFilePath := filepath.Join(assertSync.localRoot, "foo.py") localFilePath := filepath.Join(assertSync.localRoot, "foo.py")
@ -448,7 +455,8 @@ func TestSyncIncrementalSyncPythonNotebookToFile(t *testing.T) {
} }
func TestSyncIncrementalSyncFileToPythonNotebook(t *testing.T) { func TestSyncIncrementalSyncFileToPythonNotebook(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create vanilla python file // create vanilla python file
localFilePath := filepath.Join(assertSync.localRoot, "foo.py") localFilePath := filepath.Join(assertSync.localRoot, "foo.py")
@ -471,7 +479,8 @@ func TestSyncIncrementalSyncFileToPythonNotebook(t *testing.T) {
} }
func TestSyncIncrementalSyncPythonNotebookDelete(t *testing.T) { func TestSyncIncrementalSyncPythonNotebookDelete(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch") ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create python notebook // create python notebook
localFilePath := filepath.Join(assertSync.localRoot, "foo.py") localFilePath := filepath.Join(assertSync.localRoot, "foo.py")

View File

@ -1,7 +1,6 @@
package cmd_test package cmd_test
import ( import (
"context"
"testing" "testing"
"github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/internal/testcli"
@ -9,8 +8,7 @@ import (
) )
func TestUnknownCommand(t *testing.T) { func TestUnknownCommand(t *testing.T) {
ctx := context.Background() stdout, stderr, err := testcli.RequireErrorRun(t, "unknown-command")
stdout, stderr, err := testcli.RequireErrorRun(t, ctx, "unknown-command")
assert.Error(t, err, "unknown command", `unknown command "unknown-command" for "databricks"`) assert.Error(t, err, "unknown command", `unknown command "unknown-command" for "databricks"`)
assert.Equal(t, "", stdout.String()) assert.Equal(t, "", stdout.String())

View File

@ -1,7 +1,6 @@
package version_test package version_test
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"testing" "testing"
@ -14,29 +13,25 @@ import (
var expectedVersion = fmt.Sprintf("Databricks CLI v%s\n", build.GetInfo().Version) var expectedVersion = fmt.Sprintf("Databricks CLI v%s\n", build.GetInfo().Version)
func TestVersionFlagShort(t *testing.T) { func TestVersionFlagShort(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "-v")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "-v")
assert.Equal(t, expectedVersion, stdout.String()) assert.Equal(t, expectedVersion, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
} }
func TestVersionFlagLong(t *testing.T) { func TestVersionFlagLong(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "--version")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "--version")
assert.Equal(t, expectedVersion, stdout.String()) assert.Equal(t, expectedVersion, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
} }
func TestVersionCommand(t *testing.T) { func TestVersionCommand(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "version")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "version")
assert.Equal(t, expectedVersion, stdout.String()) assert.Equal(t, expectedVersion, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
} }
func TestVersionCommandWithJSONOutput(t *testing.T) { func TestVersionCommandWithJSONOutput(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "version", "--output", "json")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "version", "--output", "json")
assert.NotEmpty(t, stdout.String()) assert.NotEmpty(t, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())

View File

@ -20,8 +20,7 @@ import (
) )
func TestWorkspaceList(t *testing.T) { func TestWorkspaceList(t *testing.T) {
ctx := context.Background() stdout, stderr := testcli.RequireSuccessfulRun(t, "workspace", "list", "/")
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "workspace", "list", "/")
outStr := stdout.String() outStr := stdout.String()
assert.Contains(t, outStr, "ID") assert.Contains(t, outStr, "ID")
assert.Contains(t, outStr, "Type") assert.Contains(t, outStr, "Type")
@ -31,14 +30,12 @@ func TestWorkspaceList(t *testing.T) {
} }
func TestWorkpaceListErrorWhenNoArguments(t *testing.T) { func TestWorkpaceListErrorWhenNoArguments(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "workspace", "list")
_, _, err := testcli.RequireErrorRun(t, ctx, "workspace", "list")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0") assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
} }
func TestWorkpaceGetStatusErrorWhenNoArguments(t *testing.T) { func TestWorkpaceGetStatusErrorWhenNoArguments(t *testing.T) {
ctx := context.Background() _, _, err := testcli.RequireErrorRun(t, "workspace", "get-status")
_, _, err := testcli.RequireErrorRun(t, ctx, "workspace", "get-status")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0") assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
} }
@ -56,7 +53,7 @@ func TestWorkpaceExportPrintsContents(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Run export // Run export
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(tmpdir, "file-a")) stdout, stderr := testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(tmpdir, "file-a"))
assert.Equal(t, contents, stdout.String()) assert.Equal(t, contents, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
} }
@ -125,7 +122,7 @@ func TestExportDir(t *testing.T) {
}, "\n") }, "\n")
// Run Export // Run Export
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "workspace", "export-dir", sourceDir, targetDir) stdout, stderr := testcli.RequireSuccessfulRun(t, "workspace", "export-dir", sourceDir, targetDir)
assert.Equal(t, expectedLogs, stdout.String()) assert.Equal(t, expectedLogs, stdout.String())
assert.Equal(t, "", stderr.String()) assert.Equal(t, "", stderr.String())
@ -153,7 +150,7 @@ func TestExportDirDoesNotOverwrite(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Run Export // Run Export
testcli.RequireSuccessfulRun(t, ctx, "workspace", "export-dir", sourceDir, targetDir) testcli.RequireSuccessfulRun(t, "workspace", "export-dir", sourceDir, targetDir)
// Assert file is not overwritten // Assert file is not overwritten
assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "local content") assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "local content")
@ -174,7 +171,7 @@ func TestExportDirWithOverwriteFlag(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Run Export // Run Export
testcli.RequireSuccessfulRun(t, ctx, "workspace", "export-dir", sourceDir, targetDir, "--overwrite") testcli.RequireSuccessfulRun(t, "workspace", "export-dir", sourceDir, targetDir, "--overwrite")
// Assert file has been overwritten // Assert file has been overwritten
assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "content from workspace") assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "content from workspace")
@ -182,7 +179,7 @@ func TestExportDirWithOverwriteFlag(t *testing.T) {
func TestImportDir(t *testing.T) { func TestImportDir(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t) ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "workspace", "import-dir", "./testdata/import_dir", targetDir, "--log-level=debug") stdout, stderr := testcli.RequireSuccessfulRun(t, "workspace", "import-dir", "./testdata/import_dir", targetDir, "--log-level=debug")
expectedLogs := strings.Join([]string{ expectedLogs := strings.Join([]string{
fmt.Sprintf("Importing files from %s", "./testdata/import_dir"), fmt.Sprintf("Importing files from %s", "./testdata/import_dir"),
@ -223,7 +220,7 @@ func TestImportDirDoesNotOverwrite(t *testing.T) {
assertFilerFileContents(t, ctx, workspaceFiler, "file-a", "old file") assertFilerFileContents(t, ctx, workspaceFiler, "file-a", "old file")
assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"old notebook\")") assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"old notebook\")")
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import-dir", "./testdata/import_dir", targetDir) testcli.RequireSuccessfulRun(t, "workspace", "import-dir", "./testdata/import_dir", targetDir)
// Assert files are imported // Assert files are imported
assertFilerFileContents(t, ctx, workspaceFiler, "a/b/c/file-b", "file-in-dir") assertFilerFileContents(t, ctx, workspaceFiler, "a/b/c/file-b", "file-in-dir")
@ -251,7 +248,7 @@ func TestImportDirWithOverwriteFlag(t *testing.T) {
assertFilerFileContents(t, ctx, workspaceFiler, "file-a", "old file") assertFilerFileContents(t, ctx, workspaceFiler, "file-a", "old file")
assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"old notebook\")") assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"old notebook\")")
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import-dir", "./testdata/import_dir", targetDir, "--overwrite") testcli.RequireSuccessfulRun(t, "workspace", "import-dir", "./testdata/import_dir", targetDir, "--overwrite")
// Assert files are imported // Assert files are imported
assertFilerFileContents(t, ctx, workspaceFiler, "a/b/c/file-b", "file-in-dir") assertFilerFileContents(t, ctx, workspaceFiler, "a/b/c/file-b", "file-in-dir")
@ -273,7 +270,7 @@ func TestExport(t *testing.T) {
// Export vanilla file // Export vanilla file
err = f.Write(ctx, "file-a", strings.NewReader("abc")) err = f.Write(ctx, "file-a", strings.NewReader("abc"))
require.NoError(t, err) require.NoError(t, err)
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "file-a")) stdout, _ := testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "file-a"))
b, err := io.ReadAll(&stdout) b, err := io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "abc", string(b)) assert.Equal(t, "abc", string(b))
@ -281,13 +278,13 @@ func TestExport(t *testing.T) {
// Export python notebook // Export python notebook
err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source")) err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source"))
require.NoError(t, err) require.NoError(t, err)
stdout, _ = testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "pyNotebook")) stdout, _ = testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "pyNotebook"))
b, err = io.ReadAll(&stdout) b, err = io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "# Databricks notebook source\n", string(b)) assert.Equal(t, "# Databricks notebook source\n", string(b))
// Export python notebook as jupyter // Export python notebook as jupyter
stdout, _ = testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--format", "JUPYTER") stdout, _ = testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--format", "JUPYTER")
b, err = io.ReadAll(&stdout) b, err = io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
assert.Contains(t, string(b), `"cells":`, "jupyter notebooks contain the cells field") assert.Contains(t, string(b), `"cells":`, "jupyter notebooks contain the cells field")
@ -303,7 +300,7 @@ func TestExportWithFileFlag(t *testing.T) {
// Export vanilla file // Export vanilla file
err = f.Write(ctx, "file-a", strings.NewReader("abc")) err = f.Write(ctx, "file-a", strings.NewReader("abc"))
require.NoError(t, err) require.NoError(t, err)
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "file-a"), "--file", filepath.Join(localTmpDir, "file.txt")) stdout, _ := testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "file-a"), "--file", filepath.Join(localTmpDir, "file.txt"))
b, err := io.ReadAll(&stdout) b, err := io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
// Expect nothing to be printed to stdout // Expect nothing to be printed to stdout
@ -313,14 +310,14 @@ func TestExportWithFileFlag(t *testing.T) {
// Export python notebook // Export python notebook
err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source")) err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source"))
require.NoError(t, err) require.NoError(t, err)
stdout, _ = testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--file", filepath.Join(localTmpDir, "pyNb.py")) stdout, _ = testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--file", filepath.Join(localTmpDir, "pyNb.py"))
b, err = io.ReadAll(&stdout) b, err = io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "", string(b)) assert.Equal(t, "", string(b))
assertLocalFileContents(t, filepath.Join(localTmpDir, "pyNb.py"), "# Databricks notebook source\n") assertLocalFileContents(t, filepath.Join(localTmpDir, "pyNb.py"), "# Databricks notebook source\n")
// Export python notebook as jupyter // Export python notebook as jupyter
stdout, _ = testcli.RequireSuccessfulRun(t, ctx, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--format", "JUPYTER", "--file", filepath.Join(localTmpDir, "jupyterNb.ipynb")) stdout, _ = testcli.RequireSuccessfulRun(t, "workspace", "export", path.Join(sourceDir, "pyNotebook"), "--format", "JUPYTER", "--file", filepath.Join(localTmpDir, "jupyterNb.ipynb"))
b, err = io.ReadAll(&stdout) b, err = io.ReadAll(&stdout)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "", string(b)) assert.Equal(t, "", string(b))
@ -332,13 +329,13 @@ func TestImportFileUsingContentFormatSource(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t) ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// Content = `print(1)`. Uploaded as a notebook by default // Content = `print(1)`. Uploaded as a notebook by default
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "pyScript"), testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "pyScript"),
"--content", base64.StdEncoding.EncodeToString([]byte("print(1)")), "--language=PYTHON") "--content", base64.StdEncoding.EncodeToString([]byte("print(1)")), "--language=PYTHON")
assertFilerFileContents(t, ctx, workspaceFiler, "pyScript", "print(1)") assertFilerFileContents(t, ctx, workspaceFiler, "pyScript", "print(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "pyScript", workspace.ObjectTypeNotebook) assertWorkspaceFileType(t, ctx, workspaceFiler, "pyScript", workspace.ObjectTypeNotebook)
// Import with content = `# Databricks notebook source\nprint(1)`. Uploaded as a notebook with the content just being print(1) // Import with content = `# Databricks notebook source\nprint(1)`. Uploaded as a notebook with the content just being print(1)
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "pyNb"), testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "pyNb"),
"--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")), "--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")),
"--language=PYTHON") "--language=PYTHON")
assertFilerFileContents(t, ctx, workspaceFiler, "pyNb", "print(1)") assertFilerFileContents(t, ctx, workspaceFiler, "pyNb", "print(1)")
@ -349,19 +346,19 @@ func TestImportFileUsingContentFormatAuto(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t) ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// Content = `# Databricks notebook source\nprint(1)`. Upload as file if path has no extension. // Content = `# Databricks notebook source\nprint(1)`. Upload as file if path has no extension.
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "py-nb-as-file"), testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "py-nb-as-file"),
"--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")), "--format=AUTO") "--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")), "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "# Databricks notebook source\nprint(1)") assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "# Databricks notebook source\nprint(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile) assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile)
// Content = `# Databricks notebook source\nprint(1)`. Upload as notebook if path has py extension // Content = `# Databricks notebook source\nprint(1)`. Upload as notebook if path has py extension
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "py-nb-as-notebook.py"), testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "py-nb-as-notebook.py"),
"--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")), "--format=AUTO") "--content", base64.StdEncoding.EncodeToString([]byte("`# Databricks notebook source\nprint(1)")), "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-notebook", "# Databricks notebook source\nprint(1)") assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-notebook", "# Databricks notebook source\nprint(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-notebook", workspace.ObjectTypeNotebook) assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-notebook", workspace.ObjectTypeNotebook)
// Content = `print(1)`. Upload as file if content is not notebook (even if path has .py extension) // Content = `print(1)`. Upload as file if content is not notebook (even if path has .py extension)
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "not-a-notebook.py"), "--content", testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "not-a-notebook.py"), "--content",
base64.StdEncoding.EncodeToString([]byte("print(1)")), "--format=AUTO") base64.StdEncoding.EncodeToString([]byte("print(1)")), "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "not-a-notebook.py", "print(1)") assertFilerFileContents(t, ctx, workspaceFiler, "not-a-notebook.py", "print(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile) assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile)
@ -369,15 +366,15 @@ func TestImportFileUsingContentFormatAuto(t *testing.T) {
func TestImportFileFormatSource(t *testing.T) { func TestImportFileFormatSource(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t) ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "pyNotebook"), "--file", "./testdata/import_dir/pyNotebook.py", "--language=PYTHON") testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "pyNotebook"), "--file", "./testdata/import_dir/pyNotebook.py", "--language=PYTHON")
assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"python\")") assertFilerFileContents(t, ctx, workspaceFiler, "pyNotebook", "# Databricks notebook source\nprint(\"python\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "pyNotebook", workspace.ObjectTypeNotebook) assertWorkspaceFileType(t, ctx, workspaceFiler, "pyNotebook", workspace.ObjectTypeNotebook)
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "scalaNotebook"), "--file", "./testdata/import_dir/scalaNotebook.scala", "--language=SCALA") testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "scalaNotebook"), "--file", "./testdata/import_dir/scalaNotebook.scala", "--language=SCALA")
assertFilerFileContents(t, ctx, workspaceFiler, "scalaNotebook", "// Databricks notebook source\nprintln(\"scala\")") assertFilerFileContents(t, ctx, workspaceFiler, "scalaNotebook", "// Databricks notebook source\nprintln(\"scala\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "scalaNotebook", workspace.ObjectTypeNotebook) assertWorkspaceFileType(t, ctx, workspaceFiler, "scalaNotebook", workspace.ObjectTypeNotebook)
_, _, err := testcli.RequireErrorRun(t, ctx, "workspace", "import", path.Join(targetDir, "scalaNotebook"), "--file", "./testdata/import_dir/scalaNotebook.scala") _, _, err := testcli.RequireErrorRun(t, "workspace", "import", path.Join(targetDir, "scalaNotebook"), "--file", "./testdata/import_dir/scalaNotebook.scala")
assert.ErrorContains(t, err, "The zip file may not be valid or may be an unsupported version. Hint: Objects imported using format=SOURCE are expected to be zip encoded databricks source notebook(s) by default. Please specify a language using the --language flag if you are trying to import a single uncompressed notebook") assert.ErrorContains(t, err, "The zip file may not be valid or may be an unsupported version. Hint: Objects imported using format=SOURCE are expected to be zip encoded databricks source notebook(s) by default. Please specify a language using the --language flag if you are trying to import a single uncompressed notebook")
} }
@ -385,18 +382,18 @@ func TestImportFileFormatAuto(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t) ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// Upload as file if path has no extension // Upload as file if path has no extension
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "py-nb-as-file"), "--file", "./testdata/import_dir/pyNotebook.py", "--format=AUTO") testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "py-nb-as-file"), "--file", "./testdata/import_dir/pyNotebook.py", "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "# Databricks notebook source") assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "# Databricks notebook source")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "print(\"python\")") assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "print(\"python\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile) assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile)
// Upload as notebook if path has extension // Upload as notebook if path has extension
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "py-nb-as-notebook.py"), "--file", "./testdata/import_dir/pyNotebook.py", "--format=AUTO") testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "py-nb-as-notebook.py"), "--file", "./testdata/import_dir/pyNotebook.py", "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-notebook", "# Databricks notebook source\nprint(\"python\")") assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-notebook", "# Databricks notebook source\nprint(\"python\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-notebook", workspace.ObjectTypeNotebook) assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-notebook", workspace.ObjectTypeNotebook)
// Upload as file if content is not notebook (even if path has .py extension) // Upload as file if content is not notebook (even if path has .py extension)
testcli.RequireSuccessfulRun(t, ctx, "workspace", "import", path.Join(targetDir, "not-a-notebook.py"), "--file", "./testdata/import_dir/file-a", "--format=AUTO") testcli.RequireSuccessfulRun(t, "workspace", "import", path.Join(targetDir, "not-a-notebook.py"), "--file", "./testdata/import_dir/file-a", "--format=AUTO")
assertFilerFileContents(t, ctx, workspaceFiler, "not-a-notebook.py", "hello, world") assertFilerFileContents(t, ctx, workspaceFiler, "not-a-notebook.py", "hello, world")
assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile) assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile)
} }

View File

@ -5,10 +5,11 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"github.com/databricks/cli/internal/acc" "github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/dbr" "github.com/databricks/cli/libs/dbr"
"github.com/databricks/cli/libs/git" "github.com/databricks/cli/libs/git"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -38,18 +39,19 @@ func assertSparseGitInfo(t *testing.T, expectedRoot string, info git.RepositoryI
assert.Equal(t, expectedRoot, info.WorktreeRoot) assert.Equal(t, expectedRoot, info.WorktreeRoot)
} }
func ensureWorkspacePrefix(root string) string {
// The fixture helper doesn't include /Workspace, so include it here.
if !strings.HasPrefix(root, "/Workspace/") {
return path.Join("/Workspace", root)
}
return root
}
func TestFetchRepositoryInfoAPI_FromRepo(t *testing.T) { func TestFetchRepositoryInfoAPI_FromRepo(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t) ctx, wt := acc.WorkspaceTest(t)
targetPath := ensureWorkspacePrefix(acc.TemporaryRepo(wt, examplesRepoUrl)) me, err := wt.W.CurrentUser.Me(ctx)
require.NoError(t, err)
targetPath := testutil.RandomName(path.Join("/Workspace/Users", me.UserName, "/testing-clone-bundle-examples-"))
stdout, stderr := testcli.RequireSuccessfulRun(t, "repos", "create", examplesRepoUrl, examplesRepoProvider, "--path", targetPath)
t.Cleanup(func() {
testcli.RequireSuccessfulRun(t, "repos", "delete", targetPath)
})
assert.Empty(t, stderr.String())
assert.NotEmpty(t, stdout.String())
ctx = dbr.MockRuntime(ctx, true) ctx = dbr.MockRuntime(ctx, true)
for _, inputPath := range []string{ for _, inputPath := range []string{
@ -66,12 +68,16 @@ func TestFetchRepositoryInfoAPI_FromRepo(t *testing.T) {
func TestFetchRepositoryInfoAPI_FromNonRepo(t *testing.T) { func TestFetchRepositoryInfoAPI_FromNonRepo(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t) ctx, wt := acc.WorkspaceTest(t)
rootPath := ensureWorkspacePrefix(acc.TemporaryWorkspaceDir(wt, "testing-nonrepo-")) me, err := wt.W.CurrentUser.Me(ctx)
// Create directory inside this root path (this is cleaned up as part of the root path).
err := wt.W.Workspace.MkdirsByPath(ctx, path.Join(rootPath, "a/b/c"))
require.NoError(t, err) require.NoError(t, err)
rootPath := testutil.RandomName(path.Join("/Workspace/Users", me.UserName, "testing-nonrepo-"))
_, stderr := testcli.RequireSuccessfulRun(t, "workspace", "mkdirs", path.Join(rootPath, "a/b/c"))
t.Cleanup(func() {
testcli.RequireSuccessfulRun(t, "workspace", "delete", "--recursive", rootPath)
})
assert.Empty(t, stderr.String())
ctx = dbr.MockRuntime(ctx, true) ctx = dbr.MockRuntime(ctx, true)
tests := []struct { tests := []struct {

View File

@ -281,7 +281,16 @@ func (r *Runner) RunAndParseJSON(v any) {
require.NoError(r, err) require.NoError(r, err)
} }
func NewRunner(t testutil.TestingT, ctx context.Context, args ...string) *Runner { func NewRunner(t testutil.TestingT, args ...string) *Runner {
return &Runner{
TestingT: t,
ctx: context.Background(),
args: args,
}
}
func NewRunnerWithContext(t testutil.TestingT, ctx context.Context, args ...string) *Runner {
return &Runner{ return &Runner{
TestingT: t, TestingT: t,
@ -290,16 +299,16 @@ func NewRunner(t testutil.TestingT, ctx context.Context, args ...string) *Runner
} }
} }
func RequireSuccessfulRun(t testutil.TestingT, ctx context.Context, args ...string) (bytes.Buffer, bytes.Buffer) { func RequireSuccessfulRun(t testutil.TestingT, args ...string) (bytes.Buffer, bytes.Buffer) {
t.Logf("run args: [%s]", strings.Join(args, ", ")) t.Logf("run args: [%s]", strings.Join(args, ", "))
r := NewRunner(t, ctx, args...) r := NewRunner(t, args...)
stdout, stderr, err := r.Run() stdout, stderr, err := r.Run()
require.NoError(t, err) require.NoError(t, err)
return stdout, stderr return stdout, stderr
} }
func RequireErrorRun(t testutil.TestingT, ctx context.Context, args ...string) (bytes.Buffer, bytes.Buffer, error) { func RequireErrorRun(t testutil.TestingT, args ...string) (bytes.Buffer, bytes.Buffer, error) {
r := NewRunner(t, ctx, args...) r := NewRunner(t, args...)
stdout, stderr, err := r.Run() stdout, stderr, err := r.Run()
require.Error(t, err) require.Error(t, err)
return stdout, stderr, err return stdout, stderr, err

View File

@ -31,9 +31,9 @@ type cmdIO struct {
err io.Writer err io.Writer
} }
func NewIO(ctx context.Context, outputFormat flags.Output, in io.Reader, out, err io.Writer, headerTemplate, template string) *cmdIO { func NewIO(outputFormat flags.Output, in io.Reader, out, err io.Writer, headerTemplate, template string) *cmdIO {
// The check below is similar to color.NoColor but uses the specified err writer. // The check below is similar to color.NoColor but uses the specified err writer.
dumb := env.Get(ctx, "NO_COLOR") != "" || env.Get(ctx, "TERM") == "dumb" dumb := os.Getenv("NO_COLOR") != "" || os.Getenv("TERM") == "dumb"
if f, ok := err.(*os.File); ok && !dumb { if f, ok := err.(*os.File); ok && !dumb {
dumb = !isatty.IsTerminal(f.Fd()) && !isatty.IsCygwinTerminal(f.Fd()) dumb = !isatty.IsTerminal(f.Fd()) && !isatty.IsCygwinTerminal(f.Fd())
} }

View File

@ -171,9 +171,8 @@ func TestRender(t *testing.T) {
for _, c := range testCases { for _, c := range testCases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
output := &bytes.Buffer{} output := &bytes.Buffer{}
ctx := context.Background() cmdIO := NewIO(c.outputFormat, nil, output, output, c.headerTemplate, c.template)
cmdIO := NewIO(ctx, c.outputFormat, nil, output, output, c.headerTemplate, c.template) ctx := InContext(context.Background(), cmdIO)
ctx = InContext(ctx, cmdIO)
var err error var err error
if vv, ok := c.v.(listing.Iterator[*provisioning.Workspace]); ok { if vv, ok := c.v.(listing.Iterator[*provisioning.Workspace]); ok {
err = RenderIterator(ctx, vv) err = RenderIterator(ctx, vv)

View File

@ -115,7 +115,7 @@ func TestFirstCompatibleCluster(t *testing.T) {
w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg))) w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg)))
ctx := context.Background() ctx := context.Background()
ctx = cmdio.InContext(ctx, cmdio.NewIO(ctx, flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "...")) ctx = cmdio.InContext(ctx, cmdio.NewIO(flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "..."))
clusterID, err := AskForCluster(ctx, w, WithDatabricksConnect("13.1")) clusterID, err := AskForCluster(ctx, w, WithDatabricksConnect("13.1"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "bcd-id", clusterID) require.Equal(t, "bcd-id", clusterID)
@ -162,7 +162,7 @@ func TestNoCompatibleClusters(t *testing.T) {
w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg))) w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg)))
ctx := context.Background() ctx := context.Background()
ctx = cmdio.InContext(ctx, cmdio.NewIO(ctx, flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "...")) ctx = cmdio.InContext(ctx, cmdio.NewIO(flags.OutputText, &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}, "", "..."))
_, err := AskForCluster(ctx, w, WithDatabricksConnect("13.1")) _, err := AskForCluster(ctx, w, WithDatabricksConnect("13.1"))
require.Equal(t, ErrNoCompatibleClusters, err) require.Equal(t, ErrNoCompatibleClusters, err)
} }

View File

@ -162,7 +162,7 @@ func TestWorkspaceHost(t *testing.T) {
func TestWorkspaceHostNotConfigured(t *testing.T) { func TestWorkspaceHostNotConfigured(t *testing.T) {
ctx := context.Background() ctx := context.Background()
cmd := cmdio.NewIO(ctx, flags.OutputJSON, strings.NewReader(""), os.Stdout, os.Stderr, "", "template") cmd := cmdio.NewIO(flags.OutputJSON, strings.NewReader(""), os.Stdout, os.Stderr, "", "template")
ctx = cmdio.InContext(ctx, cmd) ctx = cmdio.InContext(ctx, cmd)
w := &databricks.WorkspaceClient{ w := &databricks.WorkspaceClient{