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/hashicorp/go-cleanhttp v0.5.2 // 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/sys v0.28.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/zclconf/go-cty v1.15.1 h1:RgQYm4j2EvoBRXOPxhUvxPzRrGDo1eCOhHXuGfrj5S0=
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.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
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/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=

View File

@ -160,7 +160,7 @@ func TestJobRunnerRestart(t *testing.T) {
m := mocks.NewMockWorkspaceClient(t)
b.SetWorkpaceClient(m.WorkspaceClient)
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))
jobApi := m.GetMockJobsAPI()
@ -231,7 +231,7 @@ func TestJobRunnerRestartForContinuousUnpausedJobs(t *testing.T) {
m := mocks.NewMockWorkspaceClient(t)
b.SetWorkpaceClient(m.WorkspaceClient)
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))
jobApi := m.GetMockJobsAPI()

View File

@ -76,7 +76,7 @@ func TestPipelineRunnerRestart(t *testing.T) {
}
b.SetWorkpaceClient(m.WorkspaceClient)
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))
mockWait := &pipelines.WaitGetPipelineIdle[struct{}]{

View File

@ -11,7 +11,7 @@ import (
func TestListsInstalledProjects(t *testing.T) {
ctx := context.Background()
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(`
Name Description Version
blueprint Blueprint Project v0.3.15

View File

@ -12,7 +12,7 @@ import (
func TestListingWorks(t *testing.T) {
ctx := context.Background()
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()
require.NoError(t, err)
require.Contains(t, stdout.String(), "ucx")

View File

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

View File

@ -236,7 +236,7 @@ func TestInstallerWorksForReleases(t *testing.T) {
// │ │ │ └── site-packages
// │ │ │ ├── ...
// │ │ │ ├── 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")
}
@ -356,7 +356,7 @@ account_id = abc
// └── databrickslabs-blueprint-releases.json
// `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()
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_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")
// 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"]
}
ctx := cmd.Context()
cmdIO := cmdio.NewIO(ctx, f.output, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), headerTemplate, template)
ctx = cmdio.InContext(ctx, cmdIO)
cmdIO := cmdio.NewIO(f.output, cmd.InOrStdin(), cmd.OutOrStdout(), cmd.ErrOrStderr(), headerTemplate, template)
ctx := cmdio.InContext(cmd.Context(), cmdIO)
cmd.SetContext(ctx)
return nil
}

4
go.mod
View File

@ -28,7 +28,7 @@ require (
golang.org/x/oauth2 v0.24.0
golang.org/x/sync v0.10.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/yaml.v3 v3.0.1
)
@ -62,7 +62,7 @@ require (
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric 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/sys v0.28.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=
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.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
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-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
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/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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
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/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
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/testcli"
"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/compute"
"github.com/databricks/databricks-sdk-go/service/jobs"
@ -247,14 +246,15 @@ func TestUploadArtifactFileToVolumeThatDoesNotExist(t *testing.T) {
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(),
"schema_name": schemaName,
"volume_name": "doesnotexist",
})
require.NoError(t, err)
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, ctx, "bundle", "deploy")
t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, "bundle", "deploy")
assert.Error(t, err)
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)
})
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(),
"schema_name": schemaName,
"volume_name": "my_volume",
})
require.NoError(t, err)
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, ctx, "bundle", "deploy")
t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.RequireErrorRun(t, "bundle", "deploy")
assert.Error(t, err)
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()
uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "basic", map[string]any{
root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, root)
err = destroyBundle(t, ctx, root)
require.NoError(t, err)
})
// 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
require.NoError(t, os.RemoveAll(filepath.Join(root, ".databricks")))
err = os.RemoveAll(filepath.Join(root, ".databricks"))
require.NoError(t, err)
// 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/testcli"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/jobs"
"github.com/google/uuid"
@ -23,27 +22,30 @@ func TestBindJobToExistingJob(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12",
"node_type_id": nodeTypeId,
})
require.NoError(t, err)
jobId := gt.createTestJob(ctx)
t.Cleanup(func() {
gt.destroyJob(ctx, jobId)
require.NoError(t, err)
})
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId), "--auto-approve")
_, _, err := c.Run()
t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId), "--auto-approve")
_, _, err = c.Run()
require.NoError(t, err)
// Remove .databricks directory to simulate a fresh deployment
err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks"))
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
w, err := databricks.NewWorkspaceClient()
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.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()
require.NoError(t, err)
@ -64,7 +66,8 @@ func TestBindJobToExistingJob(t *testing.T) {
err = os.RemoveAll(filepath.Join(bundleRoot, ".databricks"))
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
job, err = w.Jobs.Get(ctx, jobs.GetJobRequest{
@ -81,29 +84,32 @@ func TestAbortBind(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12",
"node_type_id": nodeTypeId,
})
require.NoError(t, err)
jobId := gt.createTestJob(ctx)
t.Cleanup(func() {
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.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId))
t.Setenv("BUNDLE_ROOT", bundleRoot)
t.Setenv("TERM", "dumb")
c := testcli.NewRunner(t, "bundle", "deployment", "bind", "foo", fmt.Sprint(jobId))
// 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, "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()
require.NoError(t, err)
@ -123,9 +129,10 @@ func TestGenerateAndBind(t *testing.T) {
gt := &generateJobTest{T: wt, w: wt.W}
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,
})
require.NoError(t, err)
w, err := databricks.NewWorkspaceClient()
require.NoError(t, err)
@ -140,8 +147,8 @@ func TestGenerateAndBind(t *testing.T) {
}
})
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "job",
t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "job",
"--key", "test_job_key",
"--existing-job-id", fmt.Sprint(jobId),
"--config-dir", filepath.Join(bundleRoot, "resources"),
@ -157,13 +164,15 @@ func TestGenerateAndBind(t *testing.T) {
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()
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
_, err = w.Jobs.Get(ctx, jobs.GetJobRequest{

View File

@ -20,14 +20,16 @@ func TestDeployBundleWithCluster(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "clusters", map[string]any{
root, err := initTestTemplate(t, ctx, "clusters", map[string]any{
"unique_id": uniqueId,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
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))
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, 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")
uniqueID := uuid.New().String()
root := initTestTemplate(t, ctx, "dashboards", map[string]any{
root, err := initTestTemplate(t, ctx, "dashboards", map[string]any{
"unique_id": uniqueID,
"warehouse_id": warehouseID,
})
require.NoError(t, err)
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.
b := unmarshalConfig(t, mustValidateBundle(t, ctx, root))
@ -52,11 +55,12 @@ func TestDashboards(t *testing.T) {
require.NoError(t, err)
// 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)
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.
_, stderr := deployBundleWithArgs(t, ctx, root, "--force")
_, stderr, err := deployBundleWithArgs(t, ctx, root, "--force")
require.NoError(t, err)
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/testcli"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/apierr"
"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 {
bundleRoot := initTestTemplate(t, ctx, "uc_schema", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "uc_schema", map[string]any{
"unique_id": uniqueId,
})
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
})
// Assert the schema is created
@ -94,7 +96,8 @@ func TestBundleDeployUcSchema(t *testing.T) {
require.NoError(t, err)
// Redeploy the bundle
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Assert the schema is deleted
_, err = w.Schemas.GetByFullName(ctx, strings.Join([]string{catalogName, schemaName}, "."))
@ -115,9 +118,9 @@ func TestBundleDeployUcSchemaFailsWithoutAutoApprove(t *testing.T) {
require.NoError(t, err)
// Redeploy the bundle
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock")
t.Setenv("BUNDLE_ROOT", bundleRoot)
t.Setenv("TERM", "dumb")
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock")
stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -131,14 +134,16 @@ func TestBundlePipelineDeleteWithoutAutoApprove(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
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,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
// deploy pipeline
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is created
pipelineName := "test-bundle-pipeline-" + uniqueId
@ -157,9 +162,9 @@ func TestBundlePipelineDeleteWithoutAutoApprove(t *testing.T) {
require.NoError(t, err)
// Redeploy the bundle. Expect it to fail because deleting the pipeline requires --auto-approve.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock")
t.Setenv("BUNDLE_ROOT", bundleRoot)
t.Setenv("TERM", "dumb")
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock")
stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -176,14 +181,17 @@ func TestBundlePipelineRecreateWithoutAutoApprove(t *testing.T) {
w := wt.W
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,
})
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
})
// Assert the pipeline is created
@ -193,9 +201,9 @@ func TestBundlePipelineRecreateWithoutAutoApprove(t *testing.T) {
require.Equal(t, pipelineName, pipeline.Name)
// Redeploy the bundle, pointing the DLT pipeline to a different UC catalog.
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
c := testcli.NewRunner(t, ctx, "bundle", "deploy", "--force-lock", "--var=\"catalog=whatever\"")
t.Setenv("BUNDLE_ROOT", bundleRoot)
t.Setenv("TERM", "dumb")
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--force-lock", "--var=\"catalog=whatever\"")
stdout, stderr, err := c.Run()
assert.EqualError(t, err, root.ErrAlreadyPrinted.Error())
@ -212,20 +220,22 @@ func TestDeployBasicBundleLogs(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
root := initTestTemplate(t, ctx, "basic", map[string]any{
root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, root)
err = destroyBundle(t, ctx, root)
require.NoError(t, err)
})
currentUser, err := wt.W.CurrentUser.Me(ctx)
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{
fmt.Sprintf("Uploading bundle files to /Workspace/Users/%s/.bundle/%s/files...", currentUser.UserName, uniqueId),
"Deploying resources...",
@ -240,14 +250,17 @@ func TestDeployUcVolume(t *testing.T) {
w := wt.W
uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "volume", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "volume", map[string]any{
"unique_id": uniqueId,
})
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
})
// 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)
// Recreation of the volume without --auto-approve should fail since prompting is not possible
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
stdout, stderr, err := testcli.NewRunner(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}").Run()
t.Setenv("TERM", "dumb")
t.Setenv("BUNDLE_ROOT", bundleRoot)
stdout, stderr, err := testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}").Run()
assert.Error(t, err)
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
@ -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")
// Successfully recreate the volume with --auto-approve
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
ctx = env.Set(ctx, "TERM", "dumb")
_, _, err = testcli.NewRunner(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}", "--auto-approve").Run()
t.Setenv("TERM", "dumb")
t.Setenv("BUNDLE_ROOT", bundleRoot)
_, _, err = testcli.NewRunnerWithContext(t, ctx, "bundle", "deploy", "--var=schema_name=${resources.schemas.schema2.name}", "--auto-approve").Run()
assert.NoError(t, err)
// Assert the volume is updated successfully

View File

@ -18,14 +18,16 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
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,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
// deploy pipeline
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is created
pipelineName := "test-bundle-pipeline-" + uniqueId
@ -44,7 +46,8 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
require.NoError(t, err)
// deploy again
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is deleted
_, err = w.Pipelines.GetByName(ctx, pipelineName)
@ -55,6 +58,7 @@ func TestBundleDeployThenRemoveResources(t *testing.T) {
assert.ErrorContains(t, err, "does not exist")
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)
require.NoError(t, err)
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
"root_path": fmt.Sprintf("/Shared/%s", currentUser.UserName),
})
require.NoError(t, err)
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/internal/acc"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
)
@ -20,16 +19,17 @@ func TestFilesAreSyncedCorrectlyWhenNoSnapshot(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
bundleRoot := initTestTemplate(t, ctx, "basic", map[string]any{
bundleRoot, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"spark_version": "13.3.x-scala2.12",
"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
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)
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)
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
require.NoError(t, destroyBundle(t, ctx, bundleRoot))
})
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)
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
_, 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()
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,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
snapshotsDir := filepath.Join(bundleRoot, ".databricks", "bundle", "default", "sync-snapshots")
// Assert the snapshot file does not exist
_, err := os.ReadDir(snapshotsDir)
_, err = os.ReadDir(snapshotsDir)
assert.ErrorIs(t, err, os.ErrNotExist)
// deploy resources
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Assert the snapshot file exists
entries, err := os.ReadDir(snapshotsDir)
@ -58,7 +60,8 @@ func TestBundleDestroy(t *testing.T) {
assert.Equal(t, job.Settings.Name, jobName)
// destroy bundle
destroyBundle(t, ctx, bundleRoot)
err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// assert pipeline is deleted
_, err = w.Pipelines.GetByName(ctx, pipelineName)

View File

@ -26,9 +26,11 @@ func TestEmptyBundleDeploy(t *testing.T) {
f.Close()
// deploy empty bundle
deployBundle(t, ctx, tmpDir)
err = deployBundle(t, ctx, tmpDir)
require.NoError(t, err)
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)
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(),
})
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
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")

View File

@ -12,7 +12,6 @@ import (
"github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/filer"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/compute"
@ -26,21 +25,22 @@ func TestGenerateFromExistingJobAndDeploy(t *testing.T) {
gt := &generateJobTest{T: wt, w: wt.W}
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,
})
require.NoError(t, err)
jobId := gt.createTestJob(ctx)
t.Cleanup(func() {
gt.destroyJob(ctx, jobId)
})
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "job",
t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "job",
"--existing-job-id", fmt.Sprint(jobId),
"--config-dir", filepath.Join(bundleRoot, "resources"),
"--source-dir", filepath.Join(bundleRoot, "src"))
_, _, err := c.Run()
_, _, err = c.Run()
require.NoError(t, err)
_, 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, "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 {

View File

@ -12,7 +12,6 @@ import (
"github.com/databricks/cli/internal/acc"
"github.com/databricks/cli/internal/testcli"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
"github.com/databricks/cli/libs/filer"
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/service/pipelines"
@ -25,21 +24,22 @@ func TestGenerateFromExistingPipelineAndDeploy(t *testing.T) {
gt := &generatePipelineTest{T: wt, w: wt.W}
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,
})
require.NoError(t, err)
pipelineId, name := gt.createTestPipeline(ctx)
t.Cleanup(func() {
gt.destroyPipeline(ctx, pipelineId)
})
ctx = env.Set(ctx, "BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunner(t, ctx, "bundle", "generate", "pipeline",
t.Setenv("BUNDLE_ROOT", bundleRoot)
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "generate", "pipeline",
"--existing-pipeline-id", fmt.Sprint(pipelineId),
"--config-dir", filepath.Join(bundleRoot, "resources"),
"--source-dir", filepath.Join(bundleRoot, "src"))
_, _, err := c.Run()
_, _, err = c.Run()
require.NoError(t, err)
_, 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, 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 {

View File

@ -26,43 +26,46 @@ import (
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()
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)
configFilePath := writeConfigFile(t, config)
configFilePath, err := writeConfigFile(t, config)
if err != nil {
return "", err
}
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)
out, err := filer.NewLocalClient(bundleRoot)
require.NoError(t, err)
err = template.Materialize(ctx, configFilePath, os.DirFS(templateRoot), out)
require.NoError(t, err)
return bundleRoot
return bundleRoot, err
}
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)
require.NoError(t, err)
if err != nil {
return "", err
}
dir := t.TempDir()
filepath := filepath.Join(dir, "config.json")
t.Log("Configuration for template: ", string(bytes))
err = os.WriteFile(filepath, bytes, 0o644)
require.NoError(t, err)
return filepath
return filepath, err
}
func validateBundle(t testutil.TestingT, ctx context.Context, path string) ([]byte, error) {
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()
return stdout.Bytes(), err
}
@ -80,41 +83,35 @@ func unmarshalConfig(t testutil.TestingT, data []byte) *bundle.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)
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()
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)
args = append([]string{"bundle", "deploy"}, args...)
c := testcli.NewRunner(t, ctx, args...)
c := testcli.NewRunnerWithContext(t, ctx, args...)
stdout, stderr, err := c.Run()
return stdout.String(), stderr.String(), err
}
func deployBundleWithArgs(t testutil.TestingT, ctx context.Context, path string, args ...string) (string, string) {
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) {
func deployBundleWithFlags(t testutil.TestingT, ctx context.Context, path string, flags []string) error {
ctx = env.Set(ctx, "BUNDLE_ROOT", path)
args := []string{"bundle", "deploy", "--force-lock"}
args = append(args, flags...)
c := testcli.NewRunner(t, ctx, args...)
c := testcli.NewRunnerWithContext(t, ctx, args...)
_, _, err := c.Run()
require.NoError(t, err)
return err
}
func runResource(t testutil.TestingT, ctx context.Context, path, key string) (string, error) {
ctx = env.Set(ctx, "BUNDLE_ROOT", path)
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()
return stdout.String(), err
}
@ -126,16 +123,16 @@ func runResourceWithParams(t testutil.TestingT, ctx context.Context, path, key s
args := make([]string, 0)
args = append(args, "bundle", "run", key)
args = append(args, params...)
c := testcli.NewRunner(t, ctx, args...)
c := testcli.NewRunnerWithContext(t, ctx, args...)
stdout, _, err := c.Run()
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)
c := testcli.NewRunner(t, ctx, "bundle", "destroy", "--auto-approve")
c := testcli.NewRunnerWithContext(t, ctx, "bundle", "destroy", "--auto-approve")
_, _, err := c.Run()
require.NoError(t, err)
return err
}
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
}
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")
require.NoError(t, err)
t.Setenv("BUNDLE_ROOT", root)
// Create the command
cmd := exec.Command("go", append([]string{"run", "main.go"}, args...)...)
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
var outBuffer, errBuffer bytes.Buffer
cmd.Stdout = &outBuffer

View File

@ -20,9 +20,8 @@ import (
)
func TestBundleInitErrorOnUnknownFields(t *testing.T) {
ctx := context.Background()
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")
}
@ -39,7 +38,7 @@ func TestBundleInitErrorOnUnknownFields(t *testing.T) {
// 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.
func TestBundleInitOnMlopsStacks(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t)
_, wt := acc.WorkspaceTest(t)
w := wt.W
tmpDir1 := t.TempDir()
@ -62,7 +61,7 @@ func TestBundleInitOnMlopsStacks(t *testing.T) {
// Run bundle init
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
contents := testutil.ReadFile(t, filepath.Join(tmpDir2, "repo_name", projectName, "README.md"))
@ -70,17 +69,17 @@ func TestBundleInitOnMlopsStacks(t *testing.T) {
// Validate the stack
testutil.Chdir(t, filepath.Join(tmpDir2, "repo_name", projectName))
testcli.RequireSuccessfulRun(t, ctx, "bundle", "validate")
testcli.RequireSuccessfulRun(t, "bundle", "validate")
// Deploy the stack
testcli.RequireSuccessfulRun(t, ctx, "bundle", "deploy")
testcli.RequireSuccessfulRun(t, "bundle", "deploy")
t.Cleanup(func() {
// Delete the stack
testcli.RequireSuccessfulRun(t, ctx, "bundle", "destroy", "--auto-approve")
testcli.RequireSuccessfulRun(t, "bundle", "destroy", "--auto-approve")
})
// 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{}
err = json.Unmarshal(stdout.Bytes(), summary)
require.NoError(t, err)
@ -157,7 +156,7 @@ func TestBundleInitHelpers(t *testing.T) {
require.NoError(t, err)
// 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.
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()
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,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
// deploy bundle
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
// Cleanup the deployed bundle
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
err = destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
})
// assert job 1 is created

View File

@ -27,14 +27,16 @@ func TestLocalStateStaleness(t *testing.T) {
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
uniqueId := uuid.New().String()
initialize := func() string {
root := initTestTemplate(t, ctx, "basic", map[string]any{
root, err := initTestTemplate(t, ctx, "basic", map[string]any{
"unique_id": uniqueId,
"node_type_id": nodeTypeId,
"spark_version": defaultSparkVersion,
})
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, root)
err = destroyBundle(t, ctx, root)
require.NoError(t, err)
})
return root
@ -46,13 +48,16 @@ func TestLocalStateStaleness(t *testing.T) {
bundleB := initialize()
// 1) Deploy bundle A
deployBundle(t, ctx, bundleA)
err = deployBundle(t, ctx, bundleA)
require.NoError(t, err)
// 2) Deploy bundle B
deployBundle(t, ctx, bundleB)
err = deployBundle(t, ctx, bundleB)
require.NoError(t, err)
// 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.
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()
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,
"unique_id": uuid.New().String(),
"spark_version": sparkVersion,
"python_wheel_wrapper": pythonWheelWrapper,
"instance_pool_id": instancePoolId,
})
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
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")

View File

@ -15,7 +15,7 @@ func runSparkJarTestCommon(t *testing.T, ctx context.Context, sparkVersion, arti
nodeTypeId := testutil.GetCloud(t).NodeTypeID()
tmpDir := t.TempDir()
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,
"unique_id": uuid.New().String(),
"spark_version": sparkVersion,
@ -23,11 +23,14 @@ func runSparkJarTestCommon(t *testing.T, ctx context.Context, sparkVersion, arti
"artifact_path": artifactPath,
"instance_pool_id": instancePoolId,
}, tmpDir)
require.NoError(t, err)
deployBundle(t, ctx, bundleRoot)
err = deployBundle(t, ctx, bundleRoot)
require.NoError(t, err)
t.Cleanup(func() {
destroyBundle(t, ctx, bundleRoot)
err := destroyBundle(t, ctx, bundleRoot)
require.NoError(t, err)
})
out, err := runResource(t, ctx, bundleRoot, "jar_job")

View File

@ -1,7 +1,6 @@
package alerts_test
import (
"context"
"testing"
"github.com/databricks/cli/internal/testcli"
@ -9,7 +8,6 @@ import (
)
func TestAlertsCreateErrWhenNoArguments(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "alerts-legacy", "create")
_, _, err := testcli.RequireErrorRun(t, "alerts-legacy", "create")
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
import (
"context"
"encoding/json"
"fmt"
"path"
@ -17,9 +16,7 @@ import (
)
func TestApiGet(t *testing.T) {
ctx := context.Background()
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "api", "get", "/api/2.0/preview/scim/v2/Me")
stdout, _ := testcli.RequireSuccessfulRun(t, "api", "get", "/api/2.0/preview/scim/v2/Me")
// Deserialize SCIM API response.
var out map[string]any
@ -32,8 +29,6 @@ func TestApiGet(t *testing.T) {
}
func TestApiPost(t *testing.T) {
ctx := context.Background()
if testutil.GetCloud(t) == testutil.GCP {
t.Skip("DBFS REST API is disabled on gcp")
}
@ -46,11 +41,11 @@ func TestApiPost(t *testing.T) {
// 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
{
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) {
t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010")
ctx := context.Background()
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "auth", "describe")
stdout, _ := testcli.RequireSuccessfulRun(t, "auth", "describe")
outStr := stdout.String()
w, err := databricks.NewWorkspaceClient(&databricks.Config{})
@ -35,8 +34,7 @@ func TestAuthDescribeSuccess(t *testing.T) {
func TestAuthDescribeFailure(t *testing.T) {
t.Skipf("Skipping because of https://github.com/databricks/cli/issues/2010")
ctx := context.Background()
stdout, _ := testcli.RequireSuccessfulRun(t, ctx, "auth", "describe", "--profile", "nonexistent")
stdout, _ := testcli.RequireSuccessfulRun(t, "auth", "describe", "--profile", "nonexistent")
outStr := stdout.String()
require.NotEmpty(t, outStr)

View File

@ -1,7 +1,6 @@
package clusters_test
import (
"context"
"fmt"
"regexp"
"testing"
@ -15,8 +14,7 @@ import (
)
func TestClustersList(t *testing.T) {
ctx := context.Background()
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "clusters", "list")
stdout, stderr := testcli.RequireSuccessfulRun(t, "clusters", "list")
outStr := stdout.String()
assert.Contains(t, outStr, "ID")
assert.Contains(t, outStr, "Name")
@ -29,17 +27,15 @@ func TestClustersList(t *testing.T) {
}
func TestClustersGet(t *testing.T) {
ctx := context.Background()
clusterId := findValidClusterID(t)
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "clusters", "get", clusterId)
stdout, stderr := testcli.RequireSuccessfulRun(t, "clusters", "get", clusterId)
outStr := stdout.String()
assert.Contains(t, outStr, fmt.Sprintf(`"cluster_id":"%s"`, clusterId))
assert.Equal(t, "", stderr.String())
}
func TestClusterCreateErrorWhenNoArguments(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "clusters", "create")
_, _, err := testcli.RequireErrorRun(t, "clusters", "create")
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.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories)
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, "abcd", stdout.String())
})
@ -45,13 +43,11 @@ func TestFsCatOnADir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "dir1")
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{})
})
}
@ -66,18 +62,16 @@ func TestFsCatOnNonExistentFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, 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)
})
}
}
func TestFsCatForDbfsInvalidScheme(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cat", "dab:/non-existent-file")
_, _, err := testcli.RequireErrorRun(t, "fs", "cat", "dab:/non-existent-file")
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"))
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")
}

View File

@ -19,11 +19,10 @@ func setupCompletionFile(t *testing.T, f filer.Filer) {
}
func TestFsCompletion(t *testing.T) {
ctx := context.Background()
f, tmpDir := setupDbfsFiler(t)
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)
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.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
})
@ -152,12 +151,11 @@ func TestFsCpFileToFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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")
})
@ -173,12 +171,11 @@ func TestFsCpFileToDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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")
})
@ -197,7 +194,7 @@ func TestFsCpFileToDirForWindowsPaths(t *testing.T) {
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")
}
@ -210,7 +207,6 @@ func TestFsCpDirToDirFileNotOverwritten(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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, "query.sql", "SELECT 1")
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.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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")
})
}
@ -260,7 +255,6 @@ func TestFsCpFileToFileFileNotOverwritten(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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")
})
}
@ -284,7 +278,6 @@ func TestFsCpDirToDirWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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)
})
}
@ -308,7 +301,6 @@ func TestFsCpFileToFileWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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")
})
}
@ -332,7 +324,6 @@ func TestFsCpFileToDirWithOverwriteFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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")
})
}
@ -356,10 +347,9 @@ func TestFsCpErrorsWhenSourceIsDirWithoutRecursiveFlag(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, 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")
assert.Regexp(t, r, err.Error())
})
@ -367,8 +357,7 @@ func TestFsCpErrorsWhenSourceIsDirWithoutRecursiveFlag(t *testing.T) {
}
func TestFsCpErrorsOnInvalidScheme(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "cp", "dbfs:/a", "https:/b")
_, _, err := testcli.RequireErrorRun(t, "fs", "cp", "dbfs:/a", "https:/b")
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.Parallel()
ctx := context.Background()
sourceFiler, sourceDir := tc.setupSource(t)
targetFiler, targetDir := tc.setupTarget(t)
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)
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)
})
}

View File

@ -49,11 +49,10 @@ func TestFsLs(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
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())
var parsedStdout []map[string]any
@ -83,11 +82,10 @@ func TestFsLsWithAbsolutePaths(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
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())
var parsedStdout []map[string]any
@ -116,12 +114,10 @@ func TestFsLsOnFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
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.ErrorAs(t, err, &filer.NotADirectory{})
})
@ -137,10 +133,9 @@ func TestFsLsOnEmptyDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, 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())
var parsedStdout []map[string]any
err := json.Unmarshal(stdout.Bytes(), &parsedStdout)
@ -161,10 +156,9 @@ func TestFsLsForNonexistingDir(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, 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.Regexp(t, regexp.MustCompile("no such directory: .*/nonexistent"), err.Error())
})
@ -174,7 +168,6 @@ func TestFsLsForNonexistingDir(t *testing.T) {
func TestFsLsWithoutScheme(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "fs", "ls", "/path-without-a-dbfs-scheme", "--output=json")
_, _, err := testcli.RequireErrorRun(t, "fs", "ls", "/path-without-a-dbfs-scheme", "--output=json")
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.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
// 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, "", stdout.String())
@ -48,11 +47,10 @@ func TestFsMkdirCreatesIntermediateDirectories(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
// 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, "", stdout.String())
@ -86,7 +84,6 @@ func TestFsMkdirWhenDirectoryAlreadyExists(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
// create directory "a"
@ -94,7 +91,7 @@ func TestFsMkdirWhenDirectoryAlreadyExists(t *testing.T) {
require.NoError(t, err)
// 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, "", stdout.String())
})
@ -107,7 +104,6 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
t.Run("dbfs", func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := setupDbfsFiler(t)
// create file "hello"
@ -115,7 +111,7 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
require.NoError(t, err)
// 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.
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.Parallel()
ctx := context.Background()
f, tmpDir := setupUcVolumesFiler(t)
// create file "hello"
@ -133,7 +128,7 @@ func TestFsMkdirWhenFileExistsAtPath(t *testing.T) {
require.NoError(t, err)
// 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{})
})

View File

@ -23,7 +23,6 @@ func TestFsRmFile(t *testing.T) {
t.Parallel()
// Create a file
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
err := f.Write(context.Background(), "hello.txt", strings.NewReader("abcd"), filer.CreateParentDirectories)
require.NoError(t, err)
@ -33,7 +32,7 @@ func TestFsRmFile(t *testing.T) {
assert.NoError(t, err)
// 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, "", stdout.String())
@ -54,7 +53,6 @@ func TestFsRmEmptyDir(t *testing.T) {
t.Parallel()
// Create a directory
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "a")
require.NoError(t, err)
@ -64,7 +62,7 @@ func TestFsRmEmptyDir(t *testing.T) {
assert.NoError(t, err)
// 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, "", stdout.String())
@ -85,7 +83,6 @@ func TestFsRmNonEmptyDirectory(t *testing.T) {
t.Parallel()
// Create a directory
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
err := f.Mkdir(context.Background(), "a")
require.NoError(t, err)
@ -99,7 +96,7 @@ func TestFsRmNonEmptyDirectory(t *testing.T) {
assert.NoError(t, err)
// 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.ErrorAs(t, err, &filer.DirectoryNotEmptyError{})
})
@ -115,11 +112,10 @@ func TestFsRmForNonExistentFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
_, tmpDir := tc.setupFiler(t)
// 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)
})
}
@ -134,7 +130,6 @@ func TestFsRmDirRecursively(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
f, tmpDir := tc.setupFiler(t)
// Create a directory
@ -150,7 +145,7 @@ func TestFsRmDirRecursively(t *testing.T) {
assert.NoError(t, err)
// 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, "", stdout.String())

View File

@ -1,7 +1,6 @@
package jobs_test
import (
"context"
"encoding/json"
"fmt"
"testing"
@ -14,11 +13,10 @@ import (
func TestCreateJob(t *testing.T) {
testutil.Require(t, testutil.Azure)
ctx := context.Background()
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "jobs", "create", "--json", "@testdata/create_job_without_workers.json", "--log-level=debug")
stdout, stderr := testcli.RequireSuccessfulRun(t, "jobs", "create", "--json", "@testdata/create_job_without_workers.json", "--log-level=debug")
assert.Empty(t, stderr.String())
var output map[string]int
err := json.Unmarshal(stdout.Bytes(), &output)
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
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())
// Confirm the repo was created.
@ -67,7 +67,7 @@ func TestReposCreateWithoutProvider(t *testing.T) {
w := wt.W
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())
// Confirm the repo was created.
@ -83,22 +83,22 @@ func TestReposGet(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx)
// 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())
// 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())
// Output should be the same
assert.Equal(t, byIdOutput.String(), byPathOutput.String())
// 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")
// 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")
}
@ -109,11 +109,11 @@ func TestReposUpdate(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx)
// 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())
// 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())
// Output should be the same
@ -127,7 +127,7 @@ func TestReposDeleteByID(t *testing.T) {
repoId, _ := createTemporaryRepo(t, w, ctx)
// 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, "", stderr.String())
@ -143,7 +143,7 @@ func TestReposDeleteByPath(t *testing.T) {
repoId, repoPath := createTemporaryRepo(t, w, ctx)
// 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, "", stderr.String())

View File

@ -15,8 +15,7 @@ import (
)
func TestSecretsCreateScopeErrWhenNoArguments(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "secrets", "create-scope")
_, _, err := testcli.RequireErrorRun(t, "secrets", "create-scope")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
}
@ -70,7 +69,7 @@ func TestSecretsPutSecretStringValue(tt *testing.T) {
key := "test-key"
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, stderr)
@ -84,7 +83,7 @@ func TestSecretsPutSecretBytesValue(tt *testing.T) {
key := "test-key"
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, stderr)

View File

@ -10,12 +10,12 @@ import (
)
func TestStorageCredentialsListRendersResponse(t *testing.T) {
ctx, _ := acc.WorkspaceTest(t)
_, _ = acc.WorkspaceTest(t)
// Check if metastore is assigned for the workspace, otherwise test will fail
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.Empty(t, stderr)
}

View File

@ -72,8 +72,8 @@ type syncTest struct {
remoteRoot string
}
func setupSyncTest(t *testing.T, args ...string) (context.Context, *syncTest) {
ctx, wt := acc.WorkspaceTest(t)
func setupSyncTest(t *testing.T, args ...string) *syncTest {
_, wt := acc.WorkspaceTest(t)
w := wt.W
localRoot := t.TempDir()
@ -90,10 +90,10 @@ func setupSyncTest(t *testing.T, args ...string) (context.Context, *syncTest) {
"json",
}, args...)
c := testcli.NewRunner(t, ctx, args...)
c := testcli.NewRunner(t, args...)
c.RunBackground()
return ctx, &syncTest{
return &syncTest{
t: t,
c: c,
w: w,
@ -231,7 +231,8 @@ func (a *syncTest) snapshotContains(files []string) {
}
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
assertSync.waitForCompletionMarker()
@ -262,7 +263,8 @@ func TestSyncFullFileSync(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
assertSync.waitForCompletionMarker()
@ -295,7 +297,8 @@ func TestSyncIncrementalFileSync(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
assertSync.waitForCompletionMarker()
@ -322,7 +325,8 @@ func TestSyncNestedFolderSync(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
assertSync.waitForCompletionMarker()
@ -354,7 +358,8 @@ func TestSyncNestedFolderDoesntFailOnNonEmptyDirectory(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
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
// file system
func TestSyncIncrementalFileOverwritesFolder(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch")
ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create 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) {
ctx, assertSync := setupSyncTest(t, "--watch")
ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create python notebook
localFilePath := filepath.Join(assertSync.localRoot, "foo.py")
@ -448,7 +455,8 @@ func TestSyncIncrementalSyncPythonNotebookToFile(t *testing.T) {
}
func TestSyncIncrementalSyncFileToPythonNotebook(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch")
ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create vanilla python file
localFilePath := filepath.Join(assertSync.localRoot, "foo.py")
@ -471,7 +479,8 @@ func TestSyncIncrementalSyncFileToPythonNotebook(t *testing.T) {
}
func TestSyncIncrementalSyncPythonNotebookDelete(t *testing.T) {
ctx, assertSync := setupSyncTest(t, "--watch")
ctx := context.Background()
assertSync := setupSyncTest(t, "--watch")
// create python notebook
localFilePath := filepath.Join(assertSync.localRoot, "foo.py")

View File

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

View File

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

View File

@ -20,8 +20,7 @@ import (
)
func TestWorkspaceList(t *testing.T) {
ctx := context.Background()
stdout, stderr := testcli.RequireSuccessfulRun(t, ctx, "workspace", "list", "/")
stdout, stderr := testcli.RequireSuccessfulRun(t, "workspace", "list", "/")
outStr := stdout.String()
assert.Contains(t, outStr, "ID")
assert.Contains(t, outStr, "Type")
@ -31,14 +30,12 @@ func TestWorkspaceList(t *testing.T) {
}
func TestWorkpaceListErrorWhenNoArguments(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "workspace", "list")
_, _, err := testcli.RequireErrorRun(t, "workspace", "list")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
}
func TestWorkpaceGetStatusErrorWhenNoArguments(t *testing.T) {
ctx := context.Background()
_, _, err := testcli.RequireErrorRun(t, ctx, "workspace", "get-status")
_, _, err := testcli.RequireErrorRun(t, "workspace", "get-status")
assert.Contains(t, err.Error(), "accepts 1 arg(s), received 0")
}
@ -56,7 +53,7 @@ func TestWorkpaceExportPrintsContents(t *testing.T) {
require.NoError(t, err)
// 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, "", stderr.String())
}
@ -125,7 +122,7 @@ func TestExportDir(t *testing.T) {
}, "\n")
// 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, "", stderr.String())
@ -153,7 +150,7 @@ func TestExportDirDoesNotOverwrite(t *testing.T) {
require.NoError(t, err)
// Run Export
testcli.RequireSuccessfulRun(t, ctx, "workspace", "export-dir", sourceDir, targetDir)
testcli.RequireSuccessfulRun(t, "workspace", "export-dir", sourceDir, targetDir)
// Assert file is not overwritten
assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "local content")
@ -174,7 +171,7 @@ func TestExportDirWithOverwriteFlag(t *testing.T) {
require.NoError(t, err)
// 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
assertLocalFileContents(t, filepath.Join(targetDir, "file-a"), "content from workspace")
@ -182,7 +179,7 @@ func TestExportDirWithOverwriteFlag(t *testing.T) {
func TestImportDir(t *testing.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{
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, "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
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, "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
assertFilerFileContents(t, ctx, workspaceFiler, "a/b/c/file-b", "file-in-dir")
@ -273,7 +270,7 @@ func TestExport(t *testing.T) {
// Export vanilla file
err = f.Write(ctx, "file-a", strings.NewReader("abc"))
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)
require.NoError(t, err)
assert.Equal(t, "abc", string(b))
@ -281,13 +278,13 @@ func TestExport(t *testing.T) {
// Export python notebook
err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source"))
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)
require.NoError(t, err)
assert.Equal(t, "# Databricks notebook source\n", string(b))
// 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)
require.NoError(t, err)
assert.Contains(t, string(b), `"cells":`, "jupyter notebooks contain the cells field")
@ -303,7 +300,7 @@ func TestExportWithFileFlag(t *testing.T) {
// Export vanilla file
err = f.Write(ctx, "file-a", strings.NewReader("abc"))
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)
require.NoError(t, err)
// Expect nothing to be printed to stdout
@ -313,14 +310,14 @@ func TestExportWithFileFlag(t *testing.T) {
// Export python notebook
err = f.Write(ctx, "pyNotebook.py", strings.NewReader("# Databricks notebook source"))
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)
require.NoError(t, err)
assert.Equal(t, "", string(b))
assertLocalFileContents(t, filepath.Join(localTmpDir, "pyNb.py"), "# Databricks notebook source\n")
// 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)
require.NoError(t, err)
assert.Equal(t, "", string(b))
@ -332,13 +329,13 @@ func TestImportFileUsingContentFormatSource(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// 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")
assertFilerFileContents(t, ctx, workspaceFiler, "pyScript", "print(1)")
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)
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)")),
"--language=PYTHON")
assertFilerFileContents(t, ctx, workspaceFiler, "pyNb", "print(1)")
@ -349,19 +346,19 @@ func TestImportFileUsingContentFormatAuto(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// 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")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-file", "# Databricks notebook source\nprint(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile)
// 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")
assertFilerFileContents(t, ctx, workspaceFiler, "py-nb-as-notebook", "# Databricks notebook source\nprint(1)")
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)
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")
assertFilerFileContents(t, ctx, workspaceFiler, "not-a-notebook.py", "print(1)")
assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile)
@ -369,15 +366,15 @@ func TestImportFileUsingContentFormatAuto(t *testing.T) {
func TestImportFileFormatSource(t *testing.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\")")
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\")")
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")
}
@ -385,18 +382,18 @@ func TestImportFileFormatAuto(t *testing.T) {
ctx, workspaceFiler, targetDir := setupWorkspaceImportExportTest(t)
// 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", "print(\"python\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-file", workspace.ObjectTypeFile)
// 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\")")
assertWorkspaceFileType(t, ctx, workspaceFiler, "py-nb-as-notebook", workspace.ObjectTypeNotebook)
// 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")
assertWorkspaceFileType(t, ctx, workspaceFiler, "not-a-notebook.py", workspace.ObjectTypeFile)
}

View File

@ -5,10 +5,11 @@ import (
"os/exec"
"path"
"path/filepath"
"strings"
"testing"
"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/git"
"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)
}
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) {
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)
for _, inputPath := range []string{
@ -66,12 +68,16 @@ func TestFetchRepositoryInfoAPI_FromRepo(t *testing.T) {
func TestFetchRepositoryInfoAPI_FromNonRepo(t *testing.T) {
ctx, wt := acc.WorkspaceTest(t)
rootPath := ensureWorkspacePrefix(acc.TemporaryWorkspaceDir(wt, "testing-nonrepo-"))
// 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"))
me, err := wt.W.CurrentUser.Me(ctx)
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)
tests := []struct {

View File

@ -281,7 +281,16 @@ func (r *Runner) RunAndParseJSON(v any) {
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{
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, ", "))
r := NewRunner(t, ctx, args...)
r := NewRunner(t, args...)
stdout, stderr, err := r.Run()
require.NoError(t, err)
return stdout, stderr
}
func RequireErrorRun(t testutil.TestingT, ctx context.Context, args ...string) (bytes.Buffer, bytes.Buffer, error) {
r := NewRunner(t, ctx, args...)
func RequireErrorRun(t testutil.TestingT, args ...string) (bytes.Buffer, bytes.Buffer, error) {
r := NewRunner(t, args...)
stdout, stderr, err := r.Run()
require.Error(t, err)
return stdout, stderr, err

View File

@ -31,9 +31,9 @@ type cmdIO struct {
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.
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 {
dumb = !isatty.IsTerminal(f.Fd()) && !isatty.IsCygwinTerminal(f.Fd())
}

View File

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

View File

@ -115,7 +115,7 @@ func TestFirstCompatibleCluster(t *testing.T) {
w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg)))
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"))
require.NoError(t, err)
require.Equal(t, "bcd-id", clusterID)
@ -162,7 +162,7 @@ func TestNoCompatibleClusters(t *testing.T) {
w := databricks.Must(databricks.NewWorkspaceClient((*databricks.Config)(cfg)))
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"))
require.Equal(t, ErrNoCompatibleClusters, err)
}

View File

@ -162,7 +162,7 @@ func TestWorkspaceHost(t *testing.T) {
func TestWorkspaceHostNotConfigured(t *testing.T) {
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)
w := &databricks.WorkspaceClient{