Skip to content

Commit 8630a9b

Browse files
authored
Add cloud-only acceptance tests for ssh tunnel (#3825)
## Changes Based on #3775 Make a simple connection with "echo 'Hello'" and check that databricks ssh connect output has it. SSH tunnel requires linux releases to be present, so it can upload them to the workspace for the ssh server to use. Added the build step directly to the acceptance_test, similar to how we build the CLI itself there. Initially I've modified our runner to install goreleaser and running make snapshot-release, but it takes over 10m on linux machines. Current build step only adds ~1m to the test time.
1 parent 5292698 commit 8630a9b

File tree

6 files changed

+92
-12
lines changed

6 files changed

+92
-12
lines changed

acceptance/acceptance_test.go

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,15 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int {
153153
// Consistent behavior of locale-dependent tools, such as 'sort'
154154
t.Setenv("LC_ALL", "C")
155155

156-
buildDir := filepath.Join(cwd, "build", fmt.Sprintf("%s_%s", runtime.GOOS, runtime.GOARCH))
157-
err = os.MkdirAll(buildDir, os.ModePerm)
158-
require.NoError(t, err)
156+
buildDir := getBuildDir(t, cwd, runtime.GOOS, runtime.GOARCH)
159157

160158
terraformDir := TerraformDir
161159
if terraformDir == "" {
162160
terraformDir = buildDir
163161
}
164162

165163
// Download terraform and provider and create config.
166-
RunCommand(t, []string{"python3", filepath.Join(cwd, "install_terraform.py"), "--targetdir", terraformDir}, ".")
164+
RunCommand(t, []string{"python3", filepath.Join(cwd, "install_terraform.py"), "--targetdir", terraformDir}, ".", []string{})
167165

168166
wheelPath := buildDatabricksBundlesWheel(t, buildDir)
169167
if wheelPath != "" {
@@ -190,7 +188,7 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int {
190188
if UseVersion != "" {
191189
execPath = DownloadCLI(t, buildDir, UseVersion)
192190
} else {
193-
execPath = BuildCLI(t, buildDir, coverDir)
191+
execPath = BuildCLI(t, buildDir, coverDir, runtime.GOOS, runtime.GOARCH)
194192
}
195193
}
196194

@@ -234,6 +232,12 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int {
234232
}
235233
}
236234

235+
if cloudEnv != "" && UseVersion == "" {
236+
// Create linux release artifacts, to be used by the cloud-only ssh tunnel tests
237+
releasesDir := CreateReleaseArtifacts(t, cwd, coverDir, "linux")
238+
t.Setenv("CLI_RELEASES_DIR", releasesDir)
239+
}
240+
237241
testDefaultWarehouseId := os.Getenv("TEST_DEFAULT_WAREHOUSE_ID")
238242
if testDefaultWarehouseId != "" {
239243
repls.Set(testDefaultWarehouseId, "[TEST_DEFAULT_WAREHOUSE_ID]")
@@ -871,9 +875,20 @@ func readMergedScriptContents(t *testing.T, dir string) string {
871875
return strings.Join(prepares, "\n")
872876
}
873877

874-
func BuildCLI(t *testing.T, buildDir, coverDir string) string {
878+
func getBuildDirRoot(cwd string) string {
879+
return filepath.Join(cwd, "build")
880+
}
881+
882+
func getBuildDir(t *testing.T, cwd, osName, arch string) string {
883+
buildDir := filepath.Join(getBuildDirRoot(cwd), fmt.Sprintf("%s_%s", osName, arch))
884+
err := os.MkdirAll(buildDir, os.ModePerm)
885+
require.NoError(t, err)
886+
return buildDir
887+
}
888+
889+
func BuildCLI(t *testing.T, buildDir, coverDir, osName, arch string) string {
875890
execPath := filepath.Join(buildDir, "databricks")
876-
if runtime.GOOS == "windows" {
891+
if osName == "windows" {
877892
execPath += ".exe"
878893
}
879894

@@ -885,17 +900,62 @@ func BuildCLI(t *testing.T, buildDir, coverDir string) string {
885900
args = append(args, "-cover")
886901
}
887902

888-
if runtime.GOOS == "windows" {
903+
if osName == "windows" {
889904
// Get this error on my local Windows:
890905
// error obtaining VCS status: exit status 128
891906
// Use -buildvcs=false to disable VCS stamping.
892907
args = append(args, "-buildvcs=false")
893908
}
894909

895-
RunCommand(t, args, "..")
910+
RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch})
896911
return execPath
897912
}
898913

914+
// CreateReleaseArtifacts builds release artifacts for the given OS using amd64 and arm64 architectures,
915+
// archives them into zip files, and returns the directory containing the release artifacts.
916+
func CreateReleaseArtifacts(t *testing.T, cwd, coverDir, osName string) string {
917+
releasesDir := filepath.Join(getBuildDirRoot(cwd), "releases")
918+
require.NoError(t, os.MkdirAll(releasesDir, os.ModePerm))
919+
for _, arch := range []string{"amd64", "arm64"} {
920+
CreateReleaseArtifact(t, cwd, releasesDir, coverDir, osName, arch)
921+
}
922+
return releasesDir
923+
}
924+
925+
func CreateReleaseArtifact(t *testing.T, cwd, releasesDir, coverDir, osName, arch string) {
926+
buildDir := getBuildDir(t, cwd, osName, arch)
927+
execPath := BuildCLI(t, buildDir, coverDir, osName, arch)
928+
execInfo, err := os.Stat(execPath)
929+
require.NoError(t, err)
930+
931+
zipName := fmt.Sprintf("databricks_cli_%s_%s.zip", osName, arch)
932+
zipPath := filepath.Join(releasesDir, zipName)
933+
934+
zipFile, err := os.Create(zipPath)
935+
require.NoError(t, err)
936+
defer zipFile.Close()
937+
938+
zipWriter := zip.NewWriter(zipFile)
939+
defer zipWriter.Close()
940+
941+
header, err := zip.FileInfoHeader(execInfo)
942+
require.NoError(t, err)
943+
header.Name = "databricks"
944+
header.Method = zip.Deflate
945+
946+
writer, err := zipWriter.CreateHeader(header)
947+
require.NoError(t, err)
948+
949+
binaryFile, err := os.Open(execPath)
950+
require.NoError(t, err)
951+
defer binaryFile.Close()
952+
953+
_, err = io.Copy(writer, binaryFile)
954+
require.NoError(t, err)
955+
956+
t.Logf("Created %s %s release: %s", osName, arch, zipPath)
957+
}
958+
899959
// DownloadCLI downloads a released CLI binary archive for the given version,
900960
// extracts the executable, and returns its path.
901961
func DownloadCLI(t *testing.T, buildDir, version string) string {
@@ -1116,10 +1176,11 @@ func getUVDefaultCacheDir(t *testing.T) string {
11161176
}
11171177
}
11181178

1119-
func RunCommand(t *testing.T, args []string, dir string) {
1179+
func RunCommand(t *testing.T, args []string, dir string, env []string) {
11201180
start := time.Now()
11211181
cmd := exec.Command(args[0], args[1:]...)
11221182
cmd.Dir = dir
1183+
cmd.Env = append(os.Environ(), env...)
11231184
out, err := cmd.CombinedOutput()
11241185
elapsed := time.Since(start)
11251186
t.Logf("%s took %s", args, elapsed)
@@ -1241,7 +1302,7 @@ func buildDatabricksBundlesWheel(t *testing.T, buildDir string) string {
12411302
// so we prepare here by keeping only one.
12421303
_ = prepareWheelBuildDirectory(t, buildDir)
12431304

1244-
RunCommand(t, []string{"uv", "build", "--no-cache", "-q", "--wheel", "--out-dir", buildDir}, "../python")
1305+
RunCommand(t, []string{"uv", "build", "--no-cache", "-q", "--wheel", "--out-dir", buildDir}, "../python", []string{})
12451306

12461307
latestWheel := prepareWheelBuildDirectory(t, buildDir)
12471308
if latestWheel == "" {
@@ -1369,7 +1430,7 @@ func BuildYamlfmt(t *testing.T) {
13691430
args := []string{
13701431
"make", "-s", "tools/yamlfmt" + exeSuffix,
13711432
}
1372-
RunCommand(t, args, "..")
1433+
RunCommand(t, args, "..", []string{})
13731434
}
13741435

13751436
func loadUserReplacements(t *testing.T, repls *testdiff.ReplacementsContext, tmpDir string) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Connection successful

acceptance/ssh/connection/out.test.toml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

acceptance/ssh/connection/output.txt

Whitespace-only changes.

acceptance/ssh/connection/script

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
errcode $CLI ssh connect --cluster=$TEST_DEFAULT_CLUSTER_ID --releases-dir=$CLI_RELEASES_DIR -- "echo 'Connection successful'" >out.stdout.txt 2>LOG.stderr
2+
3+
if ! grep -q "Connection successful" out.stdout.txt; then
4+
run_id=$(cat LOG.stderr | grep -o "Job submitted successfully with run ID: [0-9]*" | grep -o "[0-9]*$")
5+
trace $CLI jobs get-run "$run_id" > LOG.job
6+
fi
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Local = false
2+
Cloud = true
3+
RequiresCluster = true
4+
5+
[EnvMatrix]
6+
DATABRICKS_BUNDLE_ENGINE = ["direct-exp"]

0 commit comments

Comments
 (0)