2023-07-12 12:09:25 +00:00
|
|
|
package root
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-03-28 10:32:34 +00:00
|
|
|
"fmt"
|
2023-07-12 12:09:25 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/databricks/cli/bundle"
|
2023-09-12 13:28:53 +00:00
|
|
|
"github.com/databricks/cli/internal/testutil"
|
2023-07-26 11:17:09 +00:00
|
|
|
"github.com/spf13/cobra"
|
2023-07-12 12:09:25 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2024-03-28 10:32:34 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2023-07-12 12:09:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func setupDatabricksCfg(t *testing.T) {
|
|
|
|
tempHomeDir := t.TempDir()
|
|
|
|
homeEnvVar := "HOME"
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
homeEnvVar = "USERPROFILE"
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg := []byte("[PROFILE-1]\nhost = https://a.com\ntoken = a\n[PROFILE-2]\nhost = https://a.com\ntoken = b\n")
|
|
|
|
err := os.WriteFile(filepath.Join(tempHomeDir, ".databrickscfg"), cfg, 0644)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
t.Setenv("DATABRICKS_CONFIG_FILE", "")
|
|
|
|
t.Setenv(homeEnvVar, tempHomeDir)
|
|
|
|
}
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
func emptyCommand(t *testing.T) *cobra.Command {
|
2023-07-12 12:09:25 +00:00
|
|
|
ctx := context.Background()
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := &cobra.Command{}
|
|
|
|
cmd.SetContext(ctx)
|
|
|
|
initProfileFlag(cmd)
|
|
|
|
return cmd
|
|
|
|
}
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
func setupWithHost(t *testing.T, cmd *cobra.Command, host string) *bundle.Bundle {
|
2023-07-26 11:17:09 +00:00
|
|
|
setupDatabricksCfg(t)
|
|
|
|
|
2024-03-27 10:49:05 +00:00
|
|
|
rootPath := t.TempDir()
|
2024-03-28 10:32:34 +00:00
|
|
|
testutil.Chdir(t, rootPath)
|
|
|
|
|
|
|
|
contents := fmt.Sprintf(`
|
|
|
|
workspace:
|
|
|
|
host: %q
|
|
|
|
`, host)
|
|
|
|
err := os.WriteFile(filepath.Join(rootPath, "databricks.yml"), []byte(contents), 0644)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
b, diags := MustConfigureBundle(cmd)
|
|
|
|
require.NoError(t, diags.Error())
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupWithProfile(t *testing.T, cmd *cobra.Command, profile string) *bundle.Bundle {
|
|
|
|
setupDatabricksCfg(t)
|
|
|
|
|
|
|
|
rootPath := t.TempDir()
|
|
|
|
testutil.Chdir(t, rootPath)
|
|
|
|
|
|
|
|
contents := fmt.Sprintf(`
|
|
|
|
workspace:
|
|
|
|
profile: %q
|
|
|
|
`, profile)
|
|
|
|
err := os.WriteFile(filepath.Join(rootPath, "databricks.yml"), []byte(contents), 0644)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
b, diags := MustConfigureBundle(cmd)
|
|
|
|
require.NoError(t, diags.Error())
|
|
|
|
return b
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureDefault(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://x.com")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://x.com", client.Config.Host)
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithMultipleMatches(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://a.com")
|
|
|
|
|
|
|
|
_, err := b.InitializeWorkspaceClient()
|
|
|
|
assert.ErrorContains(t, err, "multiple profiles matched: PROFILE-1, PROFILE-2")
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithNonExistentProfileFlag(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("NOEXIST")
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://x.com")
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
_, err := b.InitializeWorkspaceClient()
|
|
|
|
assert.ErrorContains(t, err, "has no NOEXIST profile configured")
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithMismatchedProfile(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("PROFILE-1")
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://x.com")
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
_, err := b.InitializeWorkspaceClient()
|
|
|
|
assert.ErrorContains(t, err, "config host mismatch: profile uses host https://a.com, but CLI configured to use https://x.com")
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithCorrectProfile(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("PROFILE-1")
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://a.com")
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "PROFILE-1", client.Config.Profile)
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithMismatchedProfileEnvVariable(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
t.Setenv("DATABRICKS_CONFIG_PROFILE", "PROFILE-1")
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://x.com")
|
|
|
|
|
|
|
|
_, err := b.InitializeWorkspaceClient()
|
|
|
|
assert.ErrorContains(t, err, "config host mismatch: profile uses host https://a.com, but CLI configured to use https://x.com")
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureWithProfileFlagAndEnvVariable(t *testing.T) {
|
2023-09-12 13:28:53 +00:00
|
|
|
testutil.CleanupEnvironment(t)
|
2023-07-12 12:09:25 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
t.Setenv("DATABRICKS_CONFIG_PROFILE", "NOEXIST")
|
2023-07-26 11:17:09 +00:00
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("PROFILE-1")
|
2024-03-28 10:32:34 +00:00
|
|
|
b := setupWithHost(t, cmd, "https://a.com")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "PROFILE-1", client.Config.Profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureProfileDefault(t *testing.T) {
|
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
|
|
|
// The profile in the databricks.yml file is used
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
b := setupWithProfile(t, cmd, "PROFILE-1")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "a", client.Config.Token)
|
|
|
|
assert.Equal(t, "PROFILE-1", client.Config.Profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureProfileFlag(t *testing.T) {
|
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
|
|
|
// The --profile flag takes precedence over the profile in the databricks.yml file
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("PROFILE-2")
|
|
|
|
b := setupWithProfile(t, cmd, "PROFILE-1")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "b", client.Config.Token)
|
|
|
|
assert.Equal(t, "PROFILE-2", client.Config.Profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBundleConfigureProfileEnvVariable(t *testing.T) {
|
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
|
|
|
// The DATABRICKS_CONFIG_PROFILE environment variable takes precedence over the profile in the databricks.yml file
|
|
|
|
t.Setenv("DATABRICKS_CONFIG_PROFILE", "PROFILE-2")
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
b := setupWithProfile(t, cmd, "PROFILE-1")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "b", client.Config.Token)
|
|
|
|
assert.Equal(t, "PROFILE-2", client.Config.Profile)
|
|
|
|
}
|
2023-07-26 11:17:09 +00:00
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
func TestBundleConfigureProfileFlagAndEnvVariable(t *testing.T) {
|
|
|
|
testutil.CleanupEnvironment(t)
|
|
|
|
|
|
|
|
// The --profile flag takes precedence over the DATABRICKS_CONFIG_PROFILE environment variable
|
|
|
|
t.Setenv("DATABRICKS_CONFIG_PROFILE", "NOEXIST")
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
cmd.Flag("profile").Value.Set("PROFILE-2")
|
|
|
|
b := setupWithProfile(t, cmd, "PROFILE-1")
|
|
|
|
|
|
|
|
client, err := b.InitializeWorkspaceClient()
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "https://a.com", client.Config.Host)
|
|
|
|
assert.Equal(t, "b", client.Config.Token)
|
|
|
|
assert.Equal(t, "PROFILE-2", client.Config.Profile)
|
2023-07-12 12:09:25 +00:00
|
|
|
}
|
2023-08-17 15:22:32 +00:00
|
|
|
|
|
|
|
func TestTargetFlagFull(t *testing.T) {
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
initTargetFlag(cmd)
|
|
|
|
cmd.SetArgs([]string{"version", "--target", "development"})
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
err := cmd.ExecuteContext(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
assert.Equal(t, "development", getTarget(cmd))
|
2023-08-17 15:22:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTargetFlagShort(t *testing.T) {
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
initTargetFlag(cmd)
|
|
|
|
cmd.SetArgs([]string{"version", "-t", "production"})
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
err := cmd.ExecuteContext(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
assert.Equal(t, "production", getTarget(cmd))
|
2023-08-28 17:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: remove when environment flag is fully deprecated
|
|
|
|
func TestTargetEnvironmentFlag(t *testing.T) {
|
|
|
|
cmd := emptyCommand(t)
|
|
|
|
initTargetFlag(cmd)
|
|
|
|
initEnvironmentFlag(cmd)
|
|
|
|
cmd.SetArgs([]string{"version", "--environment", "development"})
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
err := cmd.ExecuteContext(ctx)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
2024-03-28 10:32:34 +00:00
|
|
|
assert.Equal(t, "development", getTarget(cmd))
|
2023-08-17 15:22:32 +00:00
|
|
|
}
|