@@ -13,6 +13,7 @@ import ScaleError from './ScaleError';
13
13
import * as scaleUpModule from './scale-up' ;
14
14
import { getParameter } from '@aws-github-runner/aws-ssm-util' ;
15
15
import { describe , it , expect , beforeEach , vi } from 'vitest' ;
16
+ import { publishRetryMessage } from './job-retry' ;
16
17
17
18
const mockOctokit = {
18
19
paginate : vi . fn ( ) ,
@@ -33,6 +34,7 @@ const mockCreateRunner = vi.mocked(createRunner);
33
34
const mockListRunners = vi . mocked ( listEC2Runners ) ;
34
35
const mockSSMClient = mockClient ( SSMClient ) ;
35
36
const mockSSMgetParameter = vi . mocked ( getParameter ) ;
37
+ const mockPublishRetryMessage = vi . mocked ( publishRetryMessage ) ;
36
38
37
39
vi . mock ( '@octokit/rest' , ( ) => ( {
38
40
Octokit : vi . fn ( ) . mockImplementation ( ( ) => mockOctokit ) ,
@@ -60,6 +62,10 @@ vi.mock('@aws-github-runner/aws-ssm-util', async () => {
60
62
} ;
61
63
} ) ;
62
64
65
+ vi . mock ( './job-retry' , async ( ) => ( {
66
+ publishRetryMessage : vi . fn ( ) ,
67
+ } ) ) ;
68
+
63
69
export type RunnerType = 'ephemeral' | 'non-ephemeral' ;
64
70
65
71
// for ephemeral and non-ephemeral runners
@@ -134,6 +140,9 @@ beforeEach(() => {
134
140
owner : TEST_DATA . repositoryOwner ,
135
141
} ,
136
142
] ) ;
143
+ mockPublishRetryMessage . mockImplementation ( async ( ) => {
144
+ return ;
145
+ } ) ;
137
146
138
147
mockedAppAuth . mockResolvedValue ( {
139
148
type : 'app' ,
@@ -328,6 +337,36 @@ describe('scaleUp with GHES', () => {
328
337
] ,
329
338
} ) ;
330
339
} ) ;
340
+
341
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
342
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
343
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
344
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
345
+ } ) ;
346
+
347
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
348
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
349
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
350
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
351
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
352
+ } ) ;
353
+
354
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
355
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
356
+ process . env . ENABLE_EPHEMERAL_RUNNERS = 'false' ;
357
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
358
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
359
+ } ) ;
360
+
361
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
362
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
363
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
364
+ data : { status : 'completed' } ,
365
+ } ) ) ;
366
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
367
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
368
+ } ) ;
369
+
331
370
it . each ( RUNNER_TYPES ) (
332
371
'calls create start runner config of 40' + ' instances (ssm rate limit condition) to test time delay ' ,
333
372
async ( type : RunnerType ) => {
@@ -456,6 +495,34 @@ describe('scaleUp with GHES', () => {
456
495
await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( 'no retry' ) ;
457
496
mockCreateRunners . mockReset ( ) ;
458
497
} ) ;
498
+
499
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
500
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
501
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
502
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
503
+ } ) ;
504
+
505
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
506
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
507
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
508
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
509
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
510
+ } ) ;
511
+
512
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
513
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
514
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
515
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
516
+ } ) ;
517
+
518
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
519
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
520
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
521
+ data : { status : 'completed' } ,
522
+ } ) ) ;
523
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
524
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
525
+ } ) ;
459
526
} ) ;
460
527
} ) ;
461
528
@@ -530,6 +597,34 @@ describe('scaleUp with public GH', () => {
530
597
await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
531
598
expect ( createRunner ) . toBeCalledWith ( expectedRunnerParams ) ;
532
599
} ) ;
600
+
601
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
602
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
603
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
604
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
605
+ } ) ;
606
+
607
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
608
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
609
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
610
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
611
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
612
+ } ) ;
613
+
614
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
615
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
616
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
617
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
618
+ } ) ;
619
+
620
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
621
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
622
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
623
+ data : { status : 'completed' } ,
624
+ } ) ) ;
625
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
626
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
627
+ } ) ;
533
628
} ) ;
534
629
535
630
describe ( 'on repo level' , ( ) => {
@@ -687,6 +782,34 @@ describe('scaleUp with public GH', () => {
687
782
process . env . ENABLE_EPHEMERAL_RUNNERS = 'true' ;
688
783
await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toBeInstanceOf ( ScaleError ) ;
689
784
} ) ;
785
+
786
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
787
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
788
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
789
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
790
+ } ) ;
791
+
792
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
793
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
794
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
795
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
796
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
797
+ } ) ;
798
+
799
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
800
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
801
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
802
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
803
+ } ) ;
804
+
805
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
806
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
807
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
808
+ data : { status : 'completed' } ,
809
+ } ) ) ;
810
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
811
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
812
+ } ) ;
690
813
} ) ;
691
814
} ) ;
692
815
@@ -863,6 +986,36 @@ describe('scaleUp with Github Data Residency', () => {
863
986
] ,
864
987
} ) ;
865
988
} ) ;
989
+
990
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
991
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
992
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
993
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
994
+ } ) ;
995
+
996
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
997
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
998
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
999
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
1000
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
1001
+ } ) ;
1002
+
1003
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
1004
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
1005
+ process . env . ENABLE_EPHEMERAL_RUNNERS = 'false' ;
1006
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
1007
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
1008
+ } ) ;
1009
+
1010
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
1011
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
1012
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
1013
+ data : { status : 'completed' } ,
1014
+ } ) ) ;
1015
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
1016
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
1017
+ } ) ;
1018
+
866
1019
it . each ( RUNNER_TYPES ) (
867
1020
'calls create start runner config of 40' + ' instances (ssm rate limit condition) to test time delay ' ,
868
1021
async ( type : RunnerType ) => {
@@ -991,6 +1144,34 @@ describe('scaleUp with Github Data Residency', () => {
991
1144
await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( 'no retry' ) ;
992
1145
mockCreateRunners . mockReset ( ) ;
993
1146
} ) ;
1147
+
1148
+ it ( 'tries to publish a retry message when runner creation succeeds' , async ( ) => {
1149
+ await scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ;
1150
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
1151
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
1152
+ } ) ;
1153
+
1154
+ it ( 'tries to publish a retry message when runner creation fails' , async ( ) => {
1155
+ const mockCreateRunners = vi . mocked ( createRunner ) ;
1156
+ mockCreateRunners . mockRejectedValue ( new Error ( 'no retry' ) ) ;
1157
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . rejects . toThrow ( ) ;
1158
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
1159
+ } ) ;
1160
+
1161
+ it ( 'tries to publish a retry message when maximum runners has been reached' , async ( ) => {
1162
+ process . env . RUNNERS_MAXIMUM_COUNT = '1' ;
1163
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
1164
+ expect ( publishRetryMessage ) . toBeCalledWith ( TEST_DATA ) ;
1165
+ } ) ;
1166
+
1167
+ it ( 'does not publish a retry message when the job is not queued' , async ( ) => {
1168
+ process . env . ENABLE_JOB_QUEUED_CHECK = 'true' ;
1169
+ mockOctokit . actions . getJobForWorkflowRun . mockImplementation ( ( ) => ( {
1170
+ data : { status : 'completed' } ,
1171
+ } ) ) ;
1172
+ await expect ( scaleUpModule . scaleUp ( 'aws:sqs' , TEST_DATA ) ) . resolves . not . toThrow ( ) ;
1173
+ expect ( publishRetryMessage ) . not . toBeCalled ( ) ;
1174
+ } ) ;
994
1175
} ) ;
995
1176
} ) ;
996
1177
0 commit comments