mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
fix: set a failed canceled job status correctly (#3101)
* set a failed canceled job status correctly resolves #1374 * added unit test for convertProvisionerJob * Update coderd/provisionerjobs_internal_test.go Co-authored-by: Cian Johnston <cian@coder.com> * PR feedback Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
@ -312,7 +312,11 @@ func convertProvisionerJob(provisionerJob database.ProvisionerJob) codersdk.Prov
|
|||||||
switch {
|
switch {
|
||||||
case provisionerJob.CanceledAt.Valid:
|
case provisionerJob.CanceledAt.Valid:
|
||||||
if provisionerJob.CompletedAt.Valid {
|
if provisionerJob.CompletedAt.Valid {
|
||||||
job.Status = codersdk.ProvisionerJobCanceled
|
if job.Error == "" {
|
||||||
|
job.Status = codersdk.ProvisionerJobCanceled
|
||||||
|
} else {
|
||||||
|
job.Status = codersdk.ProvisionerJobFailed
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
job.Status = codersdk.ProvisionerJobCanceling
|
job.Status = codersdk.ProvisionerJobCanceling
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package coderd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -146,6 +147,109 @@ func TestProvisionerJobLogs_Unit(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConvertProvisionerJob_Unit(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
validNullTimeMock := sql.NullTime{
|
||||||
|
Time: database.Now(),
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
invalidNullTimeMock := sql.NullTime{}
|
||||||
|
errorMock := sql.NullString{
|
||||||
|
String: "error",
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
input database.ProvisionerJob
|
||||||
|
expected codersdk.ProvisionerJob
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
input: database.ProvisionerJob{},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
Status: codersdk.ProvisionerJobPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cancellation pending",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
CanceledAt: validNullTimeMock,
|
||||||
|
CompletedAt: invalidNullTimeMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
Status: codersdk.ProvisionerJobCanceling,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cancellation failed",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
CanceledAt: validNullTimeMock,
|
||||||
|
CompletedAt: validNullTimeMock,
|
||||||
|
Error: errorMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
CompletedAt: &validNullTimeMock.Time,
|
||||||
|
Status: codersdk.ProvisionerJobFailed,
|
||||||
|
Error: errorMock.String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cancellation succeeded",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
CanceledAt: validNullTimeMock,
|
||||||
|
CompletedAt: validNullTimeMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
CompletedAt: &validNullTimeMock.Time,
|
||||||
|
Status: codersdk.ProvisionerJobCanceled,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job pending",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
StartedAt: invalidNullTimeMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
Status: codersdk.ProvisionerJobPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job failed",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
CompletedAt: validNullTimeMock,
|
||||||
|
StartedAt: validNullTimeMock,
|
||||||
|
Error: errorMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
CompletedAt: &validNullTimeMock.Time,
|
||||||
|
StartedAt: &validNullTimeMock.Time,
|
||||||
|
Error: errorMock.String,
|
||||||
|
Status: codersdk.ProvisionerJobFailed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job succeeded",
|
||||||
|
input: database.ProvisionerJob{
|
||||||
|
CompletedAt: validNullTimeMock,
|
||||||
|
StartedAt: validNullTimeMock,
|
||||||
|
},
|
||||||
|
expected: codersdk.ProvisionerJob{
|
||||||
|
CompletedAt: &validNullTimeMock.Time,
|
||||||
|
StartedAt: &validNullTimeMock.Time,
|
||||||
|
Status: codersdk.ProvisionerJobSucceeded,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
testCase := testCase
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
actual := convertProvisionerJob(testCase.input)
|
||||||
|
assert.Equal(t, testCase.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type fakePubSub struct {
|
type fakePubSub struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
cond *sync.Cond
|
cond *sync.Cond
|
||||||
|
@ -125,6 +125,11 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
|
|||||||
var apiErr *codersdk.Error
|
var apiErr *codersdk.Error
|
||||||
require.ErrorAs(t, err, &apiErr)
|
require.ErrorAs(t, err, &apiErr)
|
||||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||||
|
require.Eventually(t, func() bool {
|
||||||
|
var err error
|
||||||
|
version, err = client.TemplateVersion(context.Background(), version.ID)
|
||||||
|
return assert.NoError(t, err) && version.Job.Status == codersdk.ProvisionerJobFailed
|
||||||
|
}, 5*time.Second, 25*time.Millisecond)
|
||||||
})
|
})
|
||||||
// TODO(Cian): until we are able to test cancellation properly, validating
|
// TODO(Cian): until we are able to test cancellation properly, validating
|
||||||
// Running -> Canceling is the best we can do for now.
|
// Running -> Canceling is the best we can do for now.
|
||||||
|
Reference in New Issue
Block a user