Skip to content

Commit 0aa8c2e

Browse files
Kira-Pilotjohnstcn
andauthored
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>
1 parent 77f4ab1 commit 0aa8c2e

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

coderd/provisionerjobs.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,11 @@ func convertProvisionerJob(provisionerJob database.ProvisionerJob) codersdk.Prov
312312
switch {
313313
case provisionerJob.CanceledAt.Valid:
314314
if provisionerJob.CompletedAt.Valid {
315-
job.Status = codersdk.ProvisionerJobCanceled
315+
if job.Error == "" {
316+
job.Status = codersdk.ProvisionerJobCanceled
317+
} else {
318+
job.Status = codersdk.ProvisionerJobFailed
319+
}
316320
} else {
317321
job.Status = codersdk.ProvisionerJobCanceling
318322
}

coderd/provisionerjobs_internal_test.go

+104
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package coderd
33
import (
44
"context"
55
"crypto/sha256"
6+
"database/sql"
67
"encoding/json"
78
"net/http/httptest"
89
"net/url"
@@ -146,6 +147,109 @@ func TestProvisionerJobLogs_Unit(t *testing.T) {
146147
})
147148
}
148149

150+
func TestConvertProvisionerJob_Unit(t *testing.T) {
151+
t.Parallel()
152+
validNullTimeMock := sql.NullTime{
153+
Time: database.Now(),
154+
Valid: true,
155+
}
156+
invalidNullTimeMock := sql.NullTime{}
157+
errorMock := sql.NullString{
158+
String: "error",
159+
Valid: true,
160+
}
161+
testCases := []struct {
162+
name string
163+
input database.ProvisionerJob
164+
expected codersdk.ProvisionerJob
165+
}{
166+
{
167+
name: "empty",
168+
input: database.ProvisionerJob{},
169+
expected: codersdk.ProvisionerJob{
170+
Status: codersdk.ProvisionerJobPending,
171+
},
172+
},
173+
{
174+
name: "cancellation pending",
175+
input: database.ProvisionerJob{
176+
CanceledAt: validNullTimeMock,
177+
CompletedAt: invalidNullTimeMock,
178+
},
179+
expected: codersdk.ProvisionerJob{
180+
Status: codersdk.ProvisionerJobCanceling,
181+
},
182+
},
183+
{
184+
name: "cancellation failed",
185+
input: database.ProvisionerJob{
186+
CanceledAt: validNullTimeMock,
187+
CompletedAt: validNullTimeMock,
188+
Error: errorMock,
189+
},
190+
expected: codersdk.ProvisionerJob{
191+
CompletedAt: &validNullTimeMock.Time,
192+
Status: codersdk.ProvisionerJobFailed,
193+
Error: errorMock.String,
194+
},
195+
},
196+
{
197+
name: "cancellation succeeded",
198+
input: database.ProvisionerJob{
199+
CanceledAt: validNullTimeMock,
200+
CompletedAt: validNullTimeMock,
201+
},
202+
expected: codersdk.ProvisionerJob{
203+
CompletedAt: &validNullTimeMock.Time,
204+
Status: codersdk.ProvisionerJobCanceled,
205+
},
206+
},
207+
{
208+
name: "job pending",
209+
input: database.ProvisionerJob{
210+
StartedAt: invalidNullTimeMock,
211+
},
212+
expected: codersdk.ProvisionerJob{
213+
Status: codersdk.ProvisionerJobPending,
214+
},
215+
},
216+
{
217+
name: "job failed",
218+
input: database.ProvisionerJob{
219+
CompletedAt: validNullTimeMock,
220+
StartedAt: validNullTimeMock,
221+
Error: errorMock,
222+
},
223+
expected: codersdk.ProvisionerJob{
224+
CompletedAt: &validNullTimeMock.Time,
225+
StartedAt: &validNullTimeMock.Time,
226+
Error: errorMock.String,
227+
Status: codersdk.ProvisionerJobFailed,
228+
},
229+
},
230+
{
231+
name: "job succeeded",
232+
input: database.ProvisionerJob{
233+
CompletedAt: validNullTimeMock,
234+
StartedAt: validNullTimeMock,
235+
},
236+
expected: codersdk.ProvisionerJob{
237+
CompletedAt: &validNullTimeMock.Time,
238+
StartedAt: &validNullTimeMock.Time,
239+
Status: codersdk.ProvisionerJobSucceeded,
240+
},
241+
},
242+
}
243+
for _, testCase := range testCases {
244+
testCase := testCase
245+
t.Run(testCase.name, func(t *testing.T) {
246+
t.Parallel()
247+
actual := convertProvisionerJob(testCase.input)
248+
assert.Equal(t, testCase.expected, actual)
249+
})
250+
}
251+
}
252+
149253
type fakePubSub struct {
150254
t *testing.T
151255
cond *sync.Cond

coderd/templateversions_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
125125
var apiErr *codersdk.Error
126126
require.ErrorAs(t, err, &apiErr)
127127
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
128+
require.Eventually(t, func() bool {
129+
var err error
130+
version, err = client.TemplateVersion(context.Background(), version.ID)
131+
return assert.NoError(t, err) && version.Job.Status == codersdk.ProvisionerJobFailed
132+
}, 5*time.Second, 25*time.Millisecond)
128133
})
129134
// TODO(Cian): until we are able to test cancellation properly, validating
130135
// Running -> Canceling is the best we can do for now.

0 commit comments

Comments
 (0)