Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions acceptance/experimental/air/help/output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ List your active runs for the current profile (use --all-status for finished run

Usage:
databricks experimental air list [flags]
databricks experimental air list [command]

Available Commands:
provisioned_capacity List the pre-provisioned AI Runtime capacity reservations for the current workspace

Flags:
--all-status Show runs in all states (default: active only)
Expand All @@ -49,6 +53,8 @@ Global Flags:
-p, --profile string ~/.databrickscfg profile
-t, --target string bundle target to use (if applicable)

Use "databricks experimental air list [command] --help" for more information about a command.

=== logs help
>>> [CLI] experimental air logs --help
Stream logs from an active run, or fetch logs from a completed run.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions acceptance/experimental/air/provisioned-capacity/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

=== list provisioned capacity (text)
>>> [CLI] experimental air list provisioned_capacity
ID ACCELERATOR RESERVED
cap-8xh100-alpha GPU_8xH100 64
cap-1xh100-beta GPU_1xH100 8

=== list provisioned capacity (json)
>>> [CLI] experimental air list provisioned_capacity -o json
{
"v": 1,
"ts": "[TIMESTAMP]",
"data": {
"provisioned_capacities": [
{
"provisioned_capacity_id": "cap-8xh100-alpha",
"accelerator_type": "GPU_8xH100",
"reserved_accelerators": 64
},
{
"provisioned_capacity_id": "cap-1xh100-beta",
"accelerator_type": "GPU_1xH100",
"reserved_accelerators": 8
}
]
}
}

=== get provisioned capacity (text)
>>> [CLI] experimental air get provisioned_capacity cap-8xh100-alpha
Provisioned Capacity ID: cap-8xh100-alpha
Accelerator Type: GPU_8xH100
Reserved Accelerators: 64
Used Accelerators: 40
Idle Accelerators: 24

=== get provisioned capacity (json)
>>> [CLI] experimental air get provisioned_capacity cap-8xh100-alpha -o json
{
"v": 1,
"ts": "[TIMESTAMP]",
"data": {
"provisioned_capacity_id": "cap-8xh100-alpha",
"accelerator_type": "GPU_8xH100",
"reserved_accelerators": 64,
"used_accelerators": 40,
"idle_accelerators": 24
}
}
11 changes: 11 additions & 0 deletions acceptance/experimental/air/provisioned-capacity/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
title "list provisioned capacity (text)"
trace $CLI experimental air list provisioned_capacity

title "list provisioned capacity (json)"
trace $CLI experimental air list provisioned_capacity -o json

title "get provisioned capacity (text)"
trace $CLI experimental air get provisioned_capacity cap-8xh100-alpha

title "get provisioned capacity (json)"
trace $CLI experimental air get provisioned_capacity cap-8xh100-alpha -o json
29 changes: 29 additions & 0 deletions acceptance/experimental/air/provisioned-capacity/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# The SDK occasionally probes host reachability with a HEAD request; stub it so
# the test is deterministic.
[[Server]]
Pattern = "HEAD /"
Response.Body = ''

# List returns the workspace's reservations. usage is intentionally absent here:
# the real endpoint populates it only on Get. name is the AIP resource name.
[[Server]]
Pattern = "GET /api/2.0/ai-training/provisioned-capacities"
Response.Body = '''
{
"provisioned_capacities": [
{"name": "provisioned-capacities/cap-8xh100-alpha", "spec": {"accelerator_type": "GPU_8xH100", "accelerator_count": 64}},
{"name": "provisioned-capacities/cap-1xh100-beta", "spec": {"accelerator_type": "GPU_1xH100", "accelerator_count": 8}}
]
}
'''

# Get returns one reservation with its usage summary populated.
[[Server]]
Pattern = "GET /api/2.0/ai-training/provisioned-capacities/cap-8xh100-alpha"
Response.Body = '''
{
"name": "provisioned-capacities/cap-8xh100-alpha",
"spec": {"accelerator_type": "GPU_8xH100", "accelerator_count": 64},
"status": {"usage": {"used_accelerator_count": 40, "idle_accelerator_count": 24}}
}
'''
2 changes: 2 additions & 0 deletions experimental/air/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ func newGetCommand() *cobra.Command {
return nil
}

cmd.AddCommand(newGetProvisionedCapacityCommand())

return cmd
}

Expand Down
9 changes: 6 additions & 3 deletions experimental/air/cmd/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ func renderGet(t *testing.T, data getData) string {
}

// TestGetCommandShape locks in that `get` takes the run id directly as
// `air get JOB_RUN_ID` and has no `run` subcommand (it was collapsed back into
// `get`). The acceptance test exercises the happy path end to end.
// `air get JOB_RUN_ID` (there is no `run` subcommand — it was collapsed back
// into `get`). Its only subcommand is the `provisioned_capacity` noun. The
// acceptance test exercises the happy path end to end.
func TestGetCommandShape(t *testing.T) {
cmd := newGetCommand()
assert.Equal(t, "get JOB_RUN_ID", cmd.Use)
assert.Empty(t, cmd.Commands(), "get must not register subcommands")
subs := cmd.Commands()
require.Len(t, subs, 1)
assert.Equal(t, "provisioned_capacity", subs[0].Name())
// ExactArgs(1): exactly one run id is required.
assert.NoError(t, cmd.Args(cmd, []string{"123"}))
assert.Error(t, cmd.Args(cmd, []string{}))
Expand Down
2 changes: 2 additions & 0 deletions experimental/air/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ func newListCommand() *cobra.Command {
return renderListText(cmd, fetcher, limit)
}

cmd.AddCommand(newListProvisionedCapacityCommand())

return cmd
}

Expand Down
Loading
Loading