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

Lines changed: 5 additions & 1 deletion
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

Lines changed: 104 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy