Files
coder/cli/exp_task_logs_test.go
T

201 lines
5.3 KiB
Go

package cli_test
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/testutil"
)
func Test_TaskLogs(t *testing.T) {
t.Parallel()
var (
clock = time.Date(2025, 8, 26, 12, 34, 56, 0, time.UTC)
taskID = uuid.MustParse("11111111-1111-1111-1111-111111111111")
taskName = "task-workspace"
taskLogs = []codersdk.TaskLogEntry{
{
ID: 0,
Content: "What is 1 + 1?",
Type: codersdk.TaskLogTypeInput,
Time: clock,
},
{
ID: 1,
Content: "2",
Type: codersdk.TaskLogTypeOutput,
Time: clock.Add(1 * time.Second),
},
}
)
tests := []struct {
args []string
expectTable string
expectLogs []codersdk.TaskLogEntry
expectError string
handler func(t *testing.T, ctx context.Context) http.HandlerFunc
}{
{
args: []string{taskName, "--output", "json"},
expectLogs: taskLogs,
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case fmt.Sprintf("/api/v2/users/me/workspace/%s", taskName):
httpapi.Write(ctx, w, http.StatusOK, codersdk.Workspace{
ID: taskID,
})
case fmt.Sprintf("/api/experimental/tasks/me/%s/logs", taskID.String()):
httpapi.Write(ctx, w, http.StatusOK, codersdk.TaskLogsResponse{
Logs: taskLogs,
})
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
{
args: []string{taskID.String(), "--output", "json"},
expectLogs: taskLogs,
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case fmt.Sprintf("/api/experimental/tasks/me/%s/logs", taskID.String()):
httpapi.Write(ctx, w, http.StatusOK, codersdk.TaskLogsResponse{
Logs: taskLogs,
})
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
{
args: []string{taskID.String()},
expectTable: `
TYPE CONTENT
input What is 1 + 1?
output 2`,
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case fmt.Sprintf("/api/experimental/tasks/me/%s/logs", taskID.String()):
httpapi.Write(ctx, w, http.StatusOK, codersdk.TaskLogsResponse{
Logs: taskLogs,
})
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
{
args: []string{"doesnotexist"},
expectError: httpapi.ResourceNotFoundResponse.Message,
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v2/users/me/workspace/doesnotexist":
httpapi.ResourceNotFound(w)
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
{
args: []string{uuid.Nil.String()}, // uuid does not exist
expectError: httpapi.ResourceNotFoundResponse.Message,
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case fmt.Sprintf("/api/experimental/tasks/me/%s/logs", uuid.Nil.String()):
httpapi.ResourceNotFound(w)
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
{
args: []string{"err-fetching-logs"},
expectError: assert.AnError.Error(),
handler: func(t *testing.T, ctx context.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v2/users/me/workspace/err-fetching-logs":
httpapi.Write(ctx, w, http.StatusOK, codersdk.Workspace{
ID: taskID,
})
case fmt.Sprintf("/api/experimental/tasks/me/%s/logs", taskID.String()):
httpapi.InternalServerError(w, assert.AnError)
default:
t.Errorf("unexpected path: %s", r.URL.Path)
}
}
},
},
}
for _, tt := range tests {
t.Run(strings.Join(tt.args, ","), func(t *testing.T) {
t.Parallel()
var (
ctx = testutil.Context(t, testutil.WaitShort)
srv = httptest.NewServer(tt.handler(t, ctx))
client = codersdk.New(testutil.MustURL(t, srv.URL))
args = []string{"exp", "task", "logs"}
stdout strings.Builder
err error
)
t.Cleanup(srv.Close)
inv, root := clitest.New(t, append(args, tt.args...)...)
inv.Stdout = &stdout
inv.Stderr = &stdout
clitest.SetupConfig(t, client, root)
err = inv.WithContext(ctx).Run()
if tt.expectError == "" {
assert.NoError(t, err)
} else {
assert.ErrorContains(t, err, tt.expectError)
}
if tt.expectTable != "" {
if diff := tableDiff(tt.expectTable, stdout.String()); diff != "" {
t.Errorf("unexpected output diff (-want +got):\n%s", diff)
}
}
if tt.expectLogs != nil {
var logs []codersdk.TaskLogEntry
err = json.NewDecoder(strings.NewReader(stdout.String())).Decode(&logs)
require.NoError(t, err)
assert.Equal(t, tt.expectLogs, logs)
}
})
}
}