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:
Kira Pilot
2022-07-21 16:47:06 -04:00
committed by GitHub
parent 77f4ab16a4
commit 0aa8c2efeb
3 changed files with 114 additions and 1 deletions

View File

@ -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
} }

View File

@ -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

View File

@ -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.