(ctx context.Context, t *testing.T, client *codersdk.Client, agentID uuid.UUID, signedToken string)
| 2393 | } |
| 2394 | |
| 2395 | func testReconnectingPTY(ctx context.Context, t *testing.T, client *codersdk.Client, agentID uuid.UUID, signedToken string) { |
| 2396 | opts := workspacesdk.WorkspaceAgentReconnectingPTYOpts{ |
| 2397 | AgentID: agentID, |
| 2398 | Reconnect: uuid.New(), |
| 2399 | Width: 80, |
| 2400 | Height: 80, |
| 2401 | // --norc disables executing .bashrc, which is often used to customize the bash prompt |
| 2402 | Command: "bash --norc", |
| 2403 | SignedToken: signedToken, |
| 2404 | } |
| 2405 | matchPrompt := func(line string) bool { |
| 2406 | return strings.Contains(line, "$ ") || strings.Contains(line, "# ") |
| 2407 | } |
| 2408 | matchEchoCommand := func(line string) bool { |
| 2409 | return strings.Contains(line, "echo test") |
| 2410 | } |
| 2411 | matchEchoOutput := func(line string) bool { |
| 2412 | return strings.Contains(line, "test") && !strings.Contains(line, "echo") |
| 2413 | } |
| 2414 | matchExitCommand := func(line string) bool { |
| 2415 | return strings.Contains(line, "exit") |
| 2416 | } |
| 2417 | matchExitOutput := func(line string) bool { |
| 2418 | return strings.Contains(line, "exit") || strings.Contains(line, "logout") |
| 2419 | } |
| 2420 | |
| 2421 | conn, err := workspacesdk.New(client).AgentReconnectingPTY(ctx, opts) |
| 2422 | require.NoError(t, err) |
| 2423 | defer conn.Close() |
| 2424 | |
| 2425 | tr := testutil.NewTerminalReader(t, conn) |
| 2426 | // Wait for the prompt before writing commands. If the command arrives before the prompt is written, screen |
| 2427 | // will sometimes put the command output on the same line as the command and the test will flake |
| 2428 | require.NoError(t, tr.ReadUntil(ctx, matchPrompt), "find prompt") |
| 2429 | |
| 2430 | data, err := json.Marshal(workspacesdk.ReconnectingPTYRequest{ |
| 2431 | Data: "echo test\r", |
| 2432 | }) |
| 2433 | require.NoError(t, err) |
| 2434 | _, err = conn.Write(data) |
| 2435 | require.NoError(t, err) |
| 2436 | |
| 2437 | require.NoError(t, tr.ReadUntil(ctx, matchEchoCommand), "find echo command") |
| 2438 | require.NoError(t, tr.ReadUntil(ctx, matchEchoOutput), "find echo output") |
| 2439 | |
| 2440 | // Exit should cause the connection to close. |
| 2441 | data, err = json.Marshal(workspacesdk.ReconnectingPTYRequest{ |
| 2442 | Data: "exit\r", |
| 2443 | }) |
| 2444 | require.NoError(t, err) |
| 2445 | _, err = conn.Write(data) |
| 2446 | require.NoError(t, err) |
| 2447 | |
| 2448 | // Once for the input and again for the output. |
| 2449 | require.NoError(t, tr.ReadUntil(ctx, matchExitCommand), "find exit command") |
| 2450 | require.NoError(t, tr.ReadUntil(ctx, matchExitOutput), "find exit output") |
| 2451 | |
| 2452 | // Ensure the connection closes. |
no test coverage detected