1
1
import { Octokit } from '@octokit/rest' ;
2
2
import { mocked } from 'jest-mock' ;
3
+ import moment from 'moment-timezone' ;
3
4
import nock from 'nock' ;
4
5
5
6
import { listEC2Runners } from '../aws/runners' ;
6
7
import * as ghAuth from '../gh-auth/gh-auth' ;
7
- import * as scale from '../scale-runners/scale-up' ;
8
+ import { createRunners } from '../scale-runners/scale-up' ;
8
9
import { adjust } from './pool' ;
9
10
10
11
const mockOctokit = {
@@ -24,6 +25,7 @@ jest.mock('@octokit/rest', () => ({
24
25
25
26
jest . mock ( './../aws/runners' ) ;
26
27
jest . mock ( './../gh-auth/gh-auth' ) ;
28
+ jest . mock ( './../scale-runners/scale-up' ) ;
27
29
28
30
const mocktokit = Octokit as jest . MockedClass < typeof Octokit > ;
29
31
const mockedAppAuth = mocked ( ghAuth . createGithubAppAuth , {
@@ -36,6 +38,28 @@ const mockListRunners = mocked(listEC2Runners);
36
38
const cleanEnv = process . env ;
37
39
38
40
const ORG = 'my-org' ;
41
+ const MINIMUM_TIME_RUNNING = 15 ;
42
+
43
+ const ec2InstancesRegistered = [
44
+ {
45
+ instanceId : 'i-1' ,
46
+ launchTime : new Date ( ) ,
47
+ type : 'Org' ,
48
+ owner : ORG ,
49
+ } ,
50
+ {
51
+ instanceId : 'i-2' ,
52
+ launchTime : new Date ( ) ,
53
+ type : 'Org' ,
54
+ owner : ORG ,
55
+ } ,
56
+ {
57
+ instanceId : 'i-3' ,
58
+ launchTime : new Date ( ) ,
59
+ type : 'Org' ,
60
+ owner : ORG ,
61
+ } ,
62
+ ] ;
39
63
40
64
beforeEach ( ( ) => {
41
65
nock . disableNetConnect ( ) ;
@@ -54,6 +78,7 @@ beforeEach(() => {
54
78
process . env . INSTANCE_TYPES = 'm5.large' ;
55
79
process . env . INSTANCE_TARGET_CAPACITY_TYPE = 'spot' ;
56
80
process . env . RUNNER_OWNER = ORG ;
81
+ process . env . RUNNER_BOOT_TIME_IN_MINUTES = MINIMUM_TIME_RUNNING . toString ( ) ;
57
82
58
83
const mockTokenReturnValue = {
59
84
data : {
@@ -87,44 +112,9 @@ beforeEach(() => {
87
112
busy : false ,
88
113
labels : [ ] ,
89
114
} ,
90
- {
91
- id : 11 ,
92
- name : 'j-1' , // some runner of another env
93
- os : 'linux' ,
94
- status : 'online' ,
95
- busy : false ,
96
- labels : [ ] ,
97
- } ,
98
- {
99
- id : 12 ,
100
- name : 'j-2' , // some runner of another env
101
- os : 'linux' ,
102
- status : 'online' ,
103
- busy : true ,
104
- labels : [ ] ,
105
- } ,
106
115
] ) ;
107
116
108
- mockListRunners . mockImplementation ( async ( ) => [
109
- {
110
- instanceId : 'i-1' ,
111
- launchTime : new Date ( ) ,
112
- type : 'Org' ,
113
- owner : ORG ,
114
- } ,
115
- {
116
- instanceId : 'i-2' ,
117
- launchTime : new Date ( ) ,
118
- type : 'Org' ,
119
- owner : ORG ,
120
- } ,
121
- {
122
- instanceId : 'i-3' ,
123
- launchTime : new Date ( ) ,
124
- type : 'Org' ,
125
- owner : ORG ,
126
- } ,
127
- ] ) ;
117
+ mockListRunners . mockImplementation ( async ( ) => ec2InstancesRegistered ) ;
128
118
129
119
const mockInstallationIdReturnValueOrgs = {
130
120
data : {
@@ -155,16 +145,64 @@ beforeEach(() => {
155
145
156
146
describe ( 'Test simple pool.' , ( ) => {
157
147
describe ( 'With GitHub Cloud' , ( ) => {
158
- it ( 'Top up pool with pool size 2.' , async ( ) => {
159
- const spy = jest . spyOn ( scale , 'createRunners' ) ;
160
- await expect ( adjust ( { poolSize : 2 } ) ) . resolves ;
161
- expect ( spy ) . toBeCalled ;
148
+ it ( 'Top up pool with pool size 2 registered.' , async ( ) => {
149
+ await expect ( await adjust ( { poolSize : 3 } ) ) . resolves ;
150
+ expect ( createRunners ) . toHaveBeenCalledTimes ( 1 ) ;
162
151
} ) ;
163
152
164
153
it ( 'Should not top up if pool size is reached.' , async ( ) => {
165
- const spy = jest . spyOn ( scale , 'createRunners' ) ;
166
- await expect ( adjust ( { poolSize : 1 } ) ) . resolves ;
167
- expect ( spy ) . not . toHaveBeenCalled ;
154
+ await expect ( await adjust ( { poolSize : 1 } ) ) . resolves ;
155
+ expect ( createRunners ) . not . toHaveBeenCalled ( ) ;
156
+ } ) ;
157
+
158
+ it ( 'Should top up if pool size is not reached including a booting instance.' , async ( ) => {
159
+ mockListRunners . mockImplementation ( async ( ) => [
160
+ ...ec2InstancesRegistered ,
161
+ {
162
+ instanceId : 'i-4-still-booting' ,
163
+ launchTime : moment ( new Date ( ) )
164
+ . subtract ( MINIMUM_TIME_RUNNING - 3 , 'minutes' )
165
+ . toDate ( ) ,
166
+ type : 'Org' ,
167
+ owner : ORG ,
168
+ } ,
169
+ {
170
+ instanceId : 'i-5-orphan' ,
171
+ launchTime : moment ( new Date ( ) )
172
+ . subtract ( MINIMUM_TIME_RUNNING + 3 , 'minutes' )
173
+ . toDate ( ) ,
174
+ type : 'Org' ,
175
+ owner : ORG ,
176
+ } ,
177
+ ] ) ;
178
+
179
+ await expect ( await adjust ( { poolSize : 5 } ) ) . resolves ;
180
+ expect ( createRunners ) . toHaveBeenCalledTimes ( 1 ) ;
181
+ } ) ;
182
+
183
+ it ( 'Should not top up if pool size is reached including a booting instance.' , async ( ) => {
184
+ mockListRunners . mockImplementation ( async ( ) => [
185
+ ...ec2InstancesRegistered ,
186
+ {
187
+ instanceId : 'i-4-still-booting' ,
188
+ launchTime : moment ( new Date ( ) )
189
+ . subtract ( MINIMUM_TIME_RUNNING - 3 , 'minutes' )
190
+ . toDate ( ) ,
191
+ type : 'Org' ,
192
+ owner : ORG ,
193
+ } ,
194
+ {
195
+ instanceId : 'i-5-orphan' ,
196
+ launchTime : moment ( new Date ( ) )
197
+ . subtract ( MINIMUM_TIME_RUNNING + 3 , 'minutes' )
198
+ . toDate ( ) ,
199
+ type : 'Org' ,
200
+ owner : ORG ,
201
+ } ,
202
+ ] ) ;
203
+
204
+ await expect ( await adjust ( { poolSize : 2 } ) ) . resolves ;
205
+ expect ( createRunners ) . not . toHaveBeenCalled ( ) ;
168
206
} ) ;
169
207
} ) ;
170
208
@@ -174,9 +212,8 @@ describe('Test simple pool.', () => {
174
212
} ) ;
175
213
176
214
it ( 'Top up if the pool size is set to 5' , async ( ) => {
177
- const spy = jest . spyOn ( scale , 'createRunners' ) ;
178
- await expect ( adjust ( { poolSize : 5 } ) ) . resolves ;
179
- expect ( spy ) . toBeCalled ;
215
+ await expect ( await adjust ( { poolSize : 3 } ) ) . resolves ;
216
+ expect ( createRunners ) . toHaveBeenCalledTimes ( 1 ) ;
180
217
} ) ;
181
218
} ) ;
182
219
} ) ;
0 commit comments