TestMissedWebhookRecovery simulates a job that was queued while GARM was offline.
()
| 411 | |
| 412 | // TestMissedWebhookRecovery simulates a job that was queued while GARM was offline. |
| 413 | func (s *PoolStressTestSuite) TestMissedWebhookRecovery() { |
| 414 | s.setupProviderMocks() |
| 415 | |
| 416 | labels := []string{"self-hosted", "linux", "x64"} |
| 417 | |
| 418 | // Directly insert a queued job into the DB (simulating a job we received but |
| 419 | // the runner was never created because GARM was restarted). |
| 420 | job := params.Job{ |
| 421 | WorkflowJobID: 4001, |
| 422 | Action: "queued", |
| 423 | Status: "queued", |
| 424 | Labels: labels, |
| 425 | RepositoryName: "test-repo", |
| 426 | RepositoryOwner: "test-owner", |
| 427 | RepoID: garmTesting.Ptr(mustParseUUID(s.entity.ID)), |
| 428 | } |
| 429 | _, err := s.store.CreateOrUpdateJob(s.adminCtx, job) |
| 430 | s.Require().NoError(err) |
| 431 | |
| 432 | // Populate the in-memory jobs map |
| 433 | s.syncJobsFromDB() |
| 434 | |
| 435 | // consumeQueuedJobs should create a runner for this orphaned job |
| 436 | err = s.mgr.consumeQueuedJobs() |
| 437 | s.Require().NoError(err) |
| 438 | |
| 439 | instances, err := s.store.ListPoolInstances(s.adminCtx, s.pool.ID, false) |
| 440 | s.Require().NoError(err) |
| 441 | s.NotEmpty(instances, "expected a runner to be created for the missed job") |
| 442 | |
| 443 | // Verify DB: the orphaned job should still be queued but locked. |
| 444 | queuedJobs, err := s.store.ListJobsByStatus(s.adminCtx, params.JobStatusQueued) |
| 445 | s.Require().NoError(err) |
| 446 | s.Len(queuedJobs, 1, "exactly 1 queued job should exist") |
| 447 | s.NotEqual(uuid.UUID{}, queuedJobs[0].LockedBy, "job should be locked after consume") |
| 448 | } |
| 449 | |
| 450 | // TestConsumeQueuedJobsRespectsBackoff verifies the JobBackoff fix. |
| 451 | func (s *PoolStressTestSuite) TestConsumeQueuedJobsRespectsBackoff() { |
nothing calls this directly
no test coverage detected