|
9 | 9 | "testing" |
10 | 10 |
|
11 | 11 | langsmith "github.com/langchain-ai/langsmith-go" |
| 12 | + "github.com/spf13/cobra" |
12 | 13 | "github.com/stretchr/testify/assert" |
13 | 14 | "github.com/stretchr/testify/require" |
14 | 15 | ) |
@@ -157,6 +158,65 @@ func TestSandboxCreateCmd_AllowsNoArgs(t *testing.T) { |
157 | 158 | require.NotContains(t, body, "snapshot_id") |
158 | 159 | } |
159 | 160 |
|
| 161 | +func TestSandboxExecCmd_PositionalNameAndCommandSeparator(t *testing.T) { |
| 162 | + cmd := newSandboxExecCmd() |
| 163 | + require.NoError(t, cmd.Args(cmd, []string{"my-vm", "echo", "hi"})) |
| 164 | + require.Error(t, cmd.Args(cmd, []string{})) |
| 165 | +} |
| 166 | + |
| 167 | +func TestSandboxExecCmd_WritesCommandOutputDirectly(t *testing.T) { |
| 168 | + var body map[string]any |
| 169 | + ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) { |
| 170 | + w.Header().Set("Content-Type", "application/json") |
| 171 | + switch { |
| 172 | + case r.Method == http.MethodGet && r.URL.Path == "/v2/sandboxes/boxes/my-vm": |
| 173 | + _, err := w.Write([]byte(`{"id":"box-id","name":"my-vm","status":"ready","dataplane_url":"` + tsURL(t, r) + `"}`)) |
| 174 | + require.NoError(t, err) |
| 175 | + case r.Method == http.MethodPost && r.URL.Path == "/execute": |
| 176 | + require.NoError(t, json.NewDecoder(r.Body).Decode(&body)) |
| 177 | + _, err := w.Write([]byte(`{"stdout":"hello\n","stderr":"","exit_code":0}`)) |
| 178 | + require.NoError(t, err) |
| 179 | + default: |
| 180 | + t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path) |
| 181 | + } |
| 182 | + }) |
| 183 | + |
| 184 | + var out string |
| 185 | + var err error |
| 186 | + stdout := captureStdout(t, func() { |
| 187 | + out, err = executeCommand(t, "--api-key", "test-key", "--api-url", ts.URL, "sandbox", "exec", "my-vm", "--", "echo", "hello") |
| 188 | + }) |
| 189 | + |
| 190 | + require.NoError(t, err) |
| 191 | + assert.Empty(t, out) |
| 192 | + assert.Equal(t, "hello\n", stdout) |
| 193 | + assert.Equal(t, "'echo' 'hello'", body["command"]) |
| 194 | +} |
| 195 | + |
| 196 | +func tsURL(t *testing.T, r *http.Request) string { |
| 197 | + t.Helper() |
| 198 | + return "http://" + r.Host |
| 199 | +} |
| 200 | + |
| 201 | +func TestSandboxCustomOutputCommands_Flags(t *testing.T) { |
| 202 | + tests := []struct { |
| 203 | + name string |
| 204 | + cmd *cobra.Command |
| 205 | + want []string |
| 206 | + }{ |
| 207 | + {"console", newSandboxConsoleCmd(), []string{"shell", "forward-ssh-agent"}}, |
| 208 | + {"tunnel", newSandboxTunnelCmd(), []string{"url", "name", "remote-port", "local-port", "stdio", "log-level"}}, |
| 209 | + {"ssh-setup", newSandboxSSHSetupCmd(), []string{"identity"}}, |
| 210 | + } |
| 211 | + for _, tc := range tests { |
| 212 | + t.Run(tc.name, func(t *testing.T) { |
| 213 | + for _, name := range tc.want { |
| 214 | + require.NotNil(t, tc.cmd.Flags().Lookup(name), "flag --%s not found", name) |
| 215 | + } |
| 216 | + }) |
| 217 | + } |
| 218 | +} |
| 219 | + |
160 | 220 | func TestSandboxTunnelCmd_PositionalNameOrURL(t *testing.T) { |
161 | 221 | cmd := newSandboxTunnelCmd() |
162 | 222 | // Should accept 0 or 1 args |
|
0 commit comments