mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
fix(coderd): ensure agent timings are non-zero on insert (#18065)
Relates to https://github.com/coder/coder/issues/15432 Ensures that no workspace build timings with zero values for started_at or ended_at are inserted into the DB or returned from the API.
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
@ -20,8 +21,10 @@ func TestScriptCompleted(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
scriptID uuid.UUID
|
||||
timing *agentproto.Timing
|
||||
scriptID uuid.UUID
|
||||
timing *agentproto.Timing
|
||||
expectInsert bool
|
||||
expectError string
|
||||
}{
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
@ -32,6 +35,7 @@ func TestScriptCompleted(t *testing.T) {
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: true,
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
@ -42,6 +46,7 @@ func TestScriptCompleted(t *testing.T) {
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: true,
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
@ -52,6 +57,7 @@ func TestScriptCompleted(t *testing.T) {
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: true,
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
@ -62,6 +68,7 @@ func TestScriptCompleted(t *testing.T) {
|
||||
Status: agentproto.Timing_TIMED_OUT,
|
||||
ExitCode: 255,
|
||||
},
|
||||
expectInsert: true,
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
@ -72,6 +79,67 @@ func TestScriptCompleted(t *testing.T) {
|
||||
Status: agentproto.Timing_EXIT_FAILURE,
|
||||
ExitCode: 1,
|
||||
},
|
||||
expectInsert: true,
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
timing: &agentproto.Timing{
|
||||
Stage: agentproto.Timing_START,
|
||||
Start: nil,
|
||||
End: timestamppb.New(dbtime.Now().Add(time.Second)),
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: false,
|
||||
expectError: "script start time is required and cannot be zero",
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
timing: &agentproto.Timing{
|
||||
Stage: agentproto.Timing_START,
|
||||
Start: timestamppb.New(dbtime.Now()),
|
||||
End: nil,
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: false,
|
||||
expectError: "script end time is required and cannot be zero",
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
timing: &agentproto.Timing{
|
||||
Stage: agentproto.Timing_START,
|
||||
Start: timestamppb.New(time.Time{}),
|
||||
End: timestamppb.New(dbtime.Now()),
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: false,
|
||||
expectError: "script start time is required and cannot be zero",
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
timing: &agentproto.Timing{
|
||||
Stage: agentproto.Timing_START,
|
||||
Start: timestamppb.New(dbtime.Now()),
|
||||
End: timestamppb.New(time.Time{}),
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: false,
|
||||
expectError: "script end time is required and cannot be zero",
|
||||
},
|
||||
{
|
||||
scriptID: uuid.New(),
|
||||
timing: &agentproto.Timing{
|
||||
Stage: agentproto.Timing_START,
|
||||
Start: timestamppb.New(dbtime.Now()),
|
||||
End: timestamppb.New(dbtime.Now().Add(-time.Second)),
|
||||
Status: agentproto.Timing_OK,
|
||||
ExitCode: 0,
|
||||
},
|
||||
expectInsert: false,
|
||||
expectError: "script start time cannot be after end time",
|
||||
},
|
||||
}
|
||||
|
||||
@ -80,19 +148,26 @@ func TestScriptCompleted(t *testing.T) {
|
||||
tt.timing.ScriptId = tt.scriptID[:]
|
||||
|
||||
mDB := dbmock.NewMockStore(gomock.NewController(t))
|
||||
mDB.EXPECT().InsertWorkspaceAgentScriptTimings(gomock.Any(), database.InsertWorkspaceAgentScriptTimingsParams{
|
||||
ScriptID: tt.scriptID,
|
||||
Stage: protoScriptTimingStageToDatabase(tt.timing.Stage),
|
||||
Status: protoScriptTimingStatusToDatabase(tt.timing.Status),
|
||||
StartedAt: tt.timing.Start.AsTime(),
|
||||
EndedAt: tt.timing.End.AsTime(),
|
||||
ExitCode: tt.timing.ExitCode,
|
||||
})
|
||||
if tt.expectInsert {
|
||||
mDB.EXPECT().InsertWorkspaceAgentScriptTimings(gomock.Any(), database.InsertWorkspaceAgentScriptTimingsParams{
|
||||
ScriptID: tt.scriptID,
|
||||
Stage: protoScriptTimingStageToDatabase(tt.timing.Stage),
|
||||
Status: protoScriptTimingStatusToDatabase(tt.timing.Status),
|
||||
StartedAt: tt.timing.Start.AsTime(),
|
||||
EndedAt: tt.timing.End.AsTime(),
|
||||
ExitCode: tt.timing.ExitCode,
|
||||
})
|
||||
}
|
||||
|
||||
api := &agentapi.ScriptsAPI{Database: mDB}
|
||||
api.ScriptCompleted(context.Background(), &agentproto.WorkspaceAgentScriptCompletedRequest{
|
||||
_, err := api.ScriptCompleted(context.Background(), &agentproto.WorkspaceAgentScriptCompletedRequest{
|
||||
Timing: tt.timing,
|
||||
})
|
||||
if tt.expectError != "" {
|
||||
require.Contains(t, err.Error(), tt.expectError, "expected error did not match")
|
||||
} else {
|
||||
require.NoError(t, err, "expected no error but got one")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user