@@ -4,7 +4,7 @@ import nock from 'nock';
44
55import { RunnerInfo , RunnerList } from '../aws/runners.d' ;
66import * as ghAuth from '../github/auth' ;
7- import { listEC2Runners , terminateRunner , tag } from './../aws/runners' ;
7+ import { listEC2Runners , terminateRunner , tag , untag } from './../aws/runners' ;
88import { githubCache } from './cache' ;
99import { newestFirstStrategy , oldestFirstStrategy , scaleDown } from './scale-down' ;
1010import { describe , it , expect , beforeEach , vi } from 'vitest' ;
@@ -33,6 +33,7 @@ vi.mock('./../aws/runners', async (importOriginal) => {
3333 return {
3434 ...actual ,
3535 tag : vi . fn ( ) ,
36+ untag : vi . fn ( ) ,
3637 terminateRunner : vi . fn ( ) ,
3738 listEC2Runners : vi . fn ( ) ,
3839 } ;
@@ -62,6 +63,7 @@ const mockedInstallationAuth = vi.mocked(ghAuth.createGithubInstallationAuth);
6263const mockCreateClient = vi . mocked ( ghAuth . createOctokitClient ) ;
6364const mockListRunners = vi . mocked ( listEC2Runners ) ;
6465const mockTagRunners = vi . mocked ( tag ) ;
66+ const mockUntagRunners = vi . mocked ( untag ) ;
6567const mockTerminateRunners = vi . mocked ( terminateRunner ) ;
6668
6769export interface TestData {
@@ -312,7 +314,7 @@ describe('Scale down runners', () => {
312314 checkNonTerminated ( runners ) ;
313315 } ) ;
314316
315- it ( `Should terminate orphan. ` , async ( ) => {
317+ it ( `Should terminate orphan (Non JIT) ` , async ( ) => {
316318 // setup
317319 const orphanRunner = createRunnerTestData ( 'orphan-1' , type , MINIMUM_BOOT_TIME + 1 , false , false , false ) ;
318320 const idleRunner = createRunnerTestData ( 'idle-1' , type , MINIMUM_BOOT_TIME + 1 , true , false , false ) ;
@@ -334,6 +336,7 @@ describe('Scale down runners', () => {
334336 Value : 'true' ,
335337 } ,
336338 ] ) ;
339+
337340 expect ( mockTagRunners ) . not . toHaveBeenCalledWith ( idleRunner . instanceId , expect . anything ( ) ) ;
338341
339342 // next cycle, update test data set orphan to true and terminate should be true
@@ -348,6 +351,51 @@ describe('Scale down runners', () => {
348351 checkNonTerminated ( runners ) ;
349352 } ) ;
350353
354+ it ( 'Should test if orphaned runner untag if online and busy, else terminate (JIT)' , async ( ) => {
355+ // arrange
356+ const orphanRunner = createRunnerTestData ( 'orphan-jit' , type , MINIMUM_BOOT_TIME + 1 , false , true , false , undefined , 1234567890 ) ;
357+ const runners = [ orphanRunner ] ;
358+
359+ mockGitHubRunners ( [ ] ) ;
360+ mockAwsRunners ( runners ) ;
361+
362+ if ( type === 'Repo' ) {
363+ mockOctokit . actions . getSelfHostedRunnerForRepo . mockResolvedValueOnce ( {
364+ data : { runnerId : 1234567890 , name : orphanRunner . instanceId , busy : true , status : 'online' } ,
365+ } ) ;
366+ } else {
367+ mockOctokit . actions . getSelfHostedRunnerForOrg . mockResolvedValueOnce ( {
368+ data : { runnerId : 1234567890 , name : orphanRunner . instanceId , busy : true , status : 'online' } ,
369+ } ) ;
370+ }
371+
372+ // act
373+ await scaleDown ( ) ;
374+
375+ // assert
376+ expect ( mockUntagRunners ) . toHaveBeenCalledWith ( orphanRunner . instanceId , [
377+ { Key : 'ghr:orphan' , Value : 'true' } ,
378+ ] ) ;
379+ expect ( mockTerminateRunners ) . not . toHaveBeenCalledWith ( orphanRunner . instanceId ) ;
380+
381+ // arrange
382+ if ( type === 'Repo' ) {
383+ mockOctokit . actions . getSelfHostedRunnerForRepo . mockResolvedValueOnce ( {
384+ data : { runnerId : 1234567890 , name : orphanRunner . instanceId , busy : true , status : 'offline' } ,
385+ } ) ;
386+ } else {
387+ mockOctokit . actions . getSelfHostedRunnerForOrg . mockResolvedValueOnce ( {
388+ data : { runnerId : 1234567890 , name : orphanRunner . instanceId , busy : true , status : 'offline' } ,
389+ } ) ;
390+ }
391+
392+ // act
393+ await scaleDown ( ) ;
394+
395+ // assert
396+ expect ( mockTerminateRunners ) . toHaveBeenCalledWith ( orphanRunner . instanceId ) ;
397+ } ) ;
398+
351399 it ( `Should ignore errors when termination orphan fails.` , async ( ) => {
352400 // setup
353401 const orphanRunner = createRunnerTestData ( 'orphan-1' , type , MINIMUM_BOOT_TIME + 1 , false , true , true ) ;
@@ -625,6 +673,7 @@ function createRunnerTestData(
625673 orphan : boolean ,
626674 shouldBeTerminated : boolean ,
627675 owner ?: string ,
676+ runnerId ?: number ,
628677) : RunnerTestItem {
629678 return {
630679 instanceId : `i-${ name } -${ type . toLowerCase ( ) } ` ,
@@ -638,5 +687,6 @@ function createRunnerTestData(
638687 registered,
639688 orphan,
640689 shouldBeTerminated,
690+ runnerId : runnerId !== undefined ? String ( runnerId ) : undefined ,
641691 } ;
642692}
0 commit comments