11package setup
22
33import (
4+ "context"
45 "errors"
56 "fmt"
67 "os"
@@ -10,6 +11,7 @@ import (
1011
1112 "github.com/databricks/cli/experimental/ssh/internal/client"
1213 "github.com/databricks/cli/libs/cmdio"
14+ "github.com/databricks/databricks-sdk-go"
1315 "github.com/databricks/databricks-sdk-go/experimental/mocks"
1416 "github.com/databricks/databricks-sdk-go/service/compute"
1517 "github.com/stretchr/testify/assert"
@@ -134,10 +136,9 @@ func TestGenerateHostConfig_Valid(t *testing.T) {
134136 SSHKeysDir : tmpDir ,
135137 ShutdownDelay : 30 * time .Second ,
136138 Profile : "test-profile" ,
137- ProxyCommand : proxyCommand ,
138139 }
139140
140- result , err := generateHostConfig (t .Context (), opts )
141+ result , err := generateHostConfig (t .Context (), opts , proxyCommand )
141142 assert .NoError (t , err )
142143
143144 assert .Contains (t , result , "Host test-host" )
@@ -169,10 +170,9 @@ func TestGenerateHostConfig_WithoutProfile(t *testing.T) {
169170 SSHKeysDir : tmpDir ,
170171 ShutdownDelay : 30 * time .Second ,
171172 Profile : "" ,
172- ProxyCommand : proxyCommand ,
173173 }
174174
175- result , err := generateHostConfig (t .Context (), opts )
175+ result , err := generateHostConfig (t .Context (), opts , proxyCommand )
176176 assert .NoError (t , err )
177177
178178 assert .NotContains (t , result , "--profile=" )
@@ -193,7 +193,7 @@ func TestGenerateHostConfig_PathEscaping(t *testing.T) {
193193 ShutdownDelay : 30 * time .Second ,
194194 }
195195
196- result , err := generateHostConfig (t .Context (), opts )
196+ result , err := generateHostConfig (t .Context (), opts , "" )
197197 assert .NoError (t , err )
198198
199199 // Check that quotes are properly escaped
@@ -225,17 +225,7 @@ func TestSetup_SuccessfulWithNewConfigFile(t *testing.T) {
225225 Profile : "test-profile" ,
226226 }
227227
228- clientOpts := client.ClientOptions {
229- ClusterID : opts .ClusterID ,
230- AutoStartCluster : opts .AutoStartCluster ,
231- ShutdownDelay : opts .ShutdownDelay ,
232- Profile : opts .Profile ,
233- }
234- proxyCommand , err := clientOpts .ToProxyCommand ()
235- require .NoError (t , err )
236- opts .ProxyCommand = proxyCommand
237-
238- err = Setup (ctx , m .WorkspaceClient , opts )
228+ err := Setup (ctx , m .WorkspaceClient , opts )
239229 assert .NoError (t , err )
240230
241231 // Check that main config has Include directive
@@ -285,15 +275,7 @@ func TestSetup_AutoApproveRecreatesExistingHost(t *testing.T) {
285275 AutoApprove : true ,
286276 }
287277
288- clientOpts := client.ClientOptions {
289- ClusterID : opts .ClusterID ,
290- ShutdownDelay : opts .ShutdownDelay ,
291- }
292- proxyCommand , err := clientOpts .ToProxyCommand ()
293- require .NoError (t , err )
294- opts .ProxyCommand = proxyCommand
295-
296- err = Setup (ctx , m .WorkspaceClient , opts )
278+ err := Setup (ctx , m .WorkspaceClient , opts )
297279 assert .NoError (t , err )
298280
299281 // Host config should be recreated (no longer contains the stale User).
@@ -304,6 +286,50 @@ func TestSetup_AutoApproveRecreatesExistingHost(t *testing.T) {
304286 assert .Contains (t , s , "--cluster=cluster-123" )
305287}
306288
289+ func TestSetup_PromptsForClusterWhenNotProvided (t * testing.T ) {
290+ ctx := cmdio .MockDiscard (t .Context ())
291+ tmpDir := t .TempDir ()
292+ t .Setenv ("HOME" , tmpDir )
293+ t .Setenv ("USERPROFILE" , tmpDir )
294+
295+ configPath := filepath .Join (tmpDir , "ssh_config" )
296+
297+ // Replace the cluster picker with a stub returning a fixed ID. This lets the
298+ // test exercise the empty-ClusterID path of Setup without driving promptui.
299+ origPrompt := clusterSelectionPrompt
300+ t .Cleanup (func () { clusterSelectionPrompt = origPrompt })
301+ promptCalled := false
302+ clusterSelectionPrompt = func (_ context.Context , _ * databricks.WorkspaceClient ) (string , error ) {
303+ promptCalled = true
304+ return "picked-cluster" , nil
305+ }
306+
307+ m := mocks .NewMockWorkspaceClient (t )
308+ clustersAPI := m .GetMockClustersAPI ()
309+ clustersAPI .EXPECT ().Get (ctx , compute.GetClusterRequest {ClusterId : "picked-cluster" }).Return (& compute.ClusterDetails {
310+ DataSecurityMode : compute .DataSecurityModeSingleUser ,
311+ }, nil )
312+
313+ opts := SetupOptions {
314+ HostName : "test-host" ,
315+ SSHConfigPath : configPath ,
316+ SSHKeysDir : tmpDir ,
317+ ShutdownDelay : 30 * time .Second ,
318+ }
319+
320+ err := Setup (ctx , m .WorkspaceClient , opts )
321+ require .NoError (t , err )
322+ assert .True (t , promptCalled , "cluster picker should run when ClusterID is empty" )
323+
324+ // The picked ID must be serialized into the ProxyCommand's --cluster= flag.
325+ hostConfigPath := filepath .Join (tmpDir , ".databricks" , "ssh-tunnel-configs" , "test-host" )
326+ hostContent , err := os .ReadFile (hostConfigPath )
327+ require .NoError (t , err )
328+ hostConfigStr := string (hostContent )
329+ assert .Contains (t , hostConfigStr , "--cluster=picked-cluster" )
330+ assert .NotContains (t , hostConfigStr , "--cluster= " )
331+ }
332+
307333func TestSetup_SuccessfulWithExistingConfigFile (t * testing.T ) {
308334 ctx := cmdio .MockDiscard (t .Context ())
309335 tmpDir := t .TempDir ()
@@ -332,16 +358,6 @@ func TestSetup_SuccessfulWithExistingConfigFile(t *testing.T) {
332358 ShutdownDelay : 60 * time .Second ,
333359 }
334360
335- clientOpts := client.ClientOptions {
336- ClusterID : opts .ClusterID ,
337- AutoStartCluster : opts .AutoStartCluster ,
338- ShutdownDelay : opts .ShutdownDelay ,
339- Profile : opts .Profile ,
340- }
341- proxyCommand , err := clientOpts .ToProxyCommand ()
342- require .NoError (t , err )
343- opts .ProxyCommand = proxyCommand
344-
345361 err = Setup (ctx , m .WorkspaceClient , opts )
346362 assert .NoError (t , err )
347363
0 commit comments