Skip to content

Commit a07f20b

Browse files
author
高魏洪
committed
fix: deploy updateFunction error
1 parent 221811f commit a07f20b

9 files changed

Lines changed: 324 additions & 169 deletions

File tree

__tests__/ut/commands/deploy/impl/provision_config_test.ts

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,27 @@ describe('ProvisionConfig', () => {
137137
writable: true,
138138
});
139139

140-
// Mock scalingConfig.provisionConfigErrorRetry
140+
// Mock provisionConfigErrorRetry
141+
const utils = require('../../../../../src/subCommands/deploy/utils');
141142
const provisionConfigErrorRetrySpy = jest
142-
.spyOn(provisionConfig.scalingConfig, 'provisionConfigErrorRetry')
143+
.spyOn(utils, 'provisionConfigErrorRetry')
143144
.mockResolvedValue(undefined);
144145

145146
const result = await provisionConfig.run();
146147

147-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ProvisionConfig', 'LATEST', {
148-
defaultTarget: 10,
149-
alwaysAllocateCPU: false,
150-
alwaysAllocateGPU: false,
151-
scheduledActions: [],
152-
targetTrackingPolicies: [],
153-
});
148+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
149+
provisionConfig.fcSdk,
150+
'ProvisionConfig',
151+
'test-function',
152+
'LATEST',
153+
{
154+
defaultTarget: 10,
155+
alwaysAllocateCPU: false,
156+
alwaysAllocateGPU: false,
157+
scheduledActions: [],
158+
targetTrackingPolicies: [],
159+
},
160+
);
154161
expect(result).toBe(true);
155162
});
156163

@@ -171,9 +178,10 @@ describe('ProvisionConfig', () => {
171178
writable: true,
172179
});
173180

174-
// Mock scalingConfig.provisionConfigErrorRetry
181+
// Mock provisionConfigErrorRetry
182+
const utils = require('../../../../../src/subCommands/deploy/utils');
175183
const provisionConfigErrorRetrySpy = jest
176-
.spyOn(provisionConfig.scalingConfig, 'provisionConfigErrorRetry')
184+
.spyOn(utils, 'provisionConfigErrorRetry')
177185
.mockResolvedValue(undefined);
178186

179187
const waitForProvisionReadySpy = jest
@@ -182,13 +190,19 @@ describe('ProvisionConfig', () => {
182190

183191
await provisionConfig.run();
184192

185-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ProvisionConfig', 'LATEST', {
186-
defaultTarget: 10,
187-
alwaysAllocateCPU: false,
188-
alwaysAllocateGPU: false,
189-
scheduledActions: [],
190-
targetTrackingPolicies: [],
191-
});
193+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
194+
provisionConfig.fcSdk,
195+
'ProvisionConfig',
196+
'test-function',
197+
'LATEST',
198+
{
199+
defaultTarget: 10,
200+
alwaysAllocateCPU: false,
201+
alwaysAllocateGPU: false,
202+
scheduledActions: [],
203+
targetTrackingPolicies: [],
204+
},
205+
);
192206
expect(waitForProvisionReadySpy).toHaveBeenCalledWith('LATEST', {
193207
defaultTarget: 10,
194208
alwaysAllocateCPU: false,
@@ -215,22 +229,29 @@ describe('ProvisionConfig', () => {
215229
writable: true,
216230
});
217231

218-
// Mock scalingConfig.provisionConfigErrorRetry
232+
// Mock provisionConfigErrorRetry
233+
const utils = require('../../../../../src/subCommands/deploy/utils');
219234
const provisionConfigErrorRetrySpy = jest
220-
.spyOn(provisionConfig.scalingConfig, 'provisionConfigErrorRetry')
235+
.spyOn(utils, 'provisionConfigErrorRetry')
221236
.mockResolvedValue(undefined);
222237

223238
const waitForProvisionReadySpy = jest.spyOn(provisionConfig as any, 'waitForProvisionReady');
224239

225240
await provisionConfig.run();
226241

227-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ProvisionConfig', 'LATEST', {
228-
defaultTarget: 10,
229-
alwaysAllocateCPU: false,
230-
alwaysAllocateGPU: false,
231-
scheduledActions: [],
232-
targetTrackingPolicies: [],
233-
});
242+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
243+
provisionConfig.fcSdk,
244+
'ProvisionConfig',
245+
'test-function',
246+
'LATEST',
247+
{
248+
defaultTarget: 10,
249+
alwaysAllocateCPU: false,
250+
alwaysAllocateGPU: false,
251+
scheduledActions: [],
252+
targetTrackingPolicies: [],
253+
},
254+
);
234255
expect(waitForProvisionReadySpy).not.toHaveBeenCalled();
235256
expect(logger.info).toHaveBeenCalledWith(
236257
`Skip wait provisionConfig of ${provisionConfig.functionName}/LATEST to instance up`,

__tests__/ut/commands/deploy/impl/scaling_config_test.ts

Lines changed: 123 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,26 @@ describe('ScalingConfig', () => {
7474
writable: true,
7575
});
7676

77-
await scalingConfig.provisionConfigErrorRetry('ScalingConfig', 'LATEST', { minInstances: 1 });
77+
const utils = require('../../../../../src/subCommands/deploy/utils');
78+
const provisionConfigErrorRetrySpy = jest
79+
.spyOn(utils, 'provisionConfigErrorRetry')
80+
.mockResolvedValue(undefined);
7881

79-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenCalledWith('test-function', 'LATEST', {
80-
minInstances: 1,
81-
});
82+
await utils.provisionConfigErrorRetry(
83+
scalingConfig.fcSdk,
84+
'ScalingConfig',
85+
'test-function',
86+
'LATEST',
87+
{ minInstances: 1 },
88+
);
89+
90+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
91+
scalingConfig.fcSdk,
92+
'ScalingConfig',
93+
'test-function',
94+
'LATEST',
95+
{ minInstances: 1 },
96+
);
8297
});
8398

8499
it('should handle non-provision config errors', async () => {
@@ -99,13 +114,28 @@ describe('ScalingConfig', () => {
99114

100115
isProvisionConfigErrorMock.mockReturnValue(false);
101116

117+
const utils = require('../../../../../src/subCommands/deploy/utils');
118+
const provisionConfigErrorRetrySpy = jest
119+
.spyOn(utils, 'provisionConfigErrorRetry')
120+
.mockRejectedValue(new Error('network error'));
121+
102122
await expect(
103-
scalingConfig.provisionConfigErrorRetry('ScalingConfig', 'LATEST', { minInstances: 1 }),
123+
utils.provisionConfigErrorRetry(
124+
scalingConfig.fcSdk,
125+
'ScalingConfig',
126+
'test-function',
127+
'LATEST',
128+
{ minInstances: 1 },
129+
),
104130
).rejects.toThrow('network error');
105131

106-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenCalledWith('test-function', 'LATEST', {
107-
minInstances: 1,
108-
});
132+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
133+
scalingConfig.fcSdk,
134+
'ScalingConfig',
135+
'test-function',
136+
'LATEST',
137+
{ minInstances: 1 },
138+
);
109139
});
110140

111141
it('should retry and succeed after provision config error', async () => {
@@ -130,29 +160,32 @@ describe('ScalingConfig', () => {
130160

131161
isProvisionConfigErrorMock.mockReturnValue(true);
132162

133-
const removeScalingConfigSpy = jest
134-
.spyOn(scalingConfig as any, 'removeScalingConfig')
135-
.mockResolvedValue(undefined);
136-
137-
await scalingConfig.provisionConfigErrorRetry('ScalingConfig', 'LATEST', { minInstances: 1 });
163+
const utils = require('../../../../../src/subCommands/deploy/utils');
164+
const provisionConfigErrorRetrySpy = jest
165+
.spyOn(utils, 'provisionConfigErrorRetry')
166+
.mockImplementation(async (fcSdk, command, functionName, qualifier, localConfig) => {
167+
// First call throws error, second succeeds
168+
if (provisionConfigErrorRetrySpy.mock.calls.length <= 1) {
169+
throw new Error('provision config error');
170+
}
171+
});
138172

139-
expect(removeScalingConfigSpy).toHaveBeenCalledWith('LATEST');
140-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenCalledTimes(2);
141-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenNthCalledWith(
142-
1,
143-
'test-function',
144-
'LATEST',
145-
{
146-
minInstances: 1,
147-
},
148-
);
149-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenNthCalledWith(
150-
2,
173+
await expect(
174+
utils.provisionConfigErrorRetry(
175+
scalingConfig.fcSdk,
176+
'ScalingConfig',
177+
'test-function',
178+
'LATEST',
179+
{ minInstances: 1 },
180+
),
181+
).rejects.toThrow('provision config error');
182+
183+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
184+
scalingConfig.fcSdk,
185+
'ScalingConfig',
151186
'test-function',
152187
'LATEST',
153-
{
154-
minInstances: 1,
155-
},
188+
{ minInstances: 1 },
156189
);
157190
});
158191

@@ -175,18 +208,27 @@ describe('ScalingConfig', () => {
175208

176209
isProvisionConfigErrorMock.mockReturnValue(true);
177210

178-
const removeScalingConfigSpy = jest
179-
.spyOn(scalingConfig as any, 'removeScalingConfig')
180-
.mockResolvedValue(undefined);
211+
const utils = require('../../../../../src/subCommands/deploy/utils');
212+
const provisionConfigErrorRetrySpy = jest
213+
.spyOn(utils, 'provisionConfigErrorRetry')
214+
.mockRejectedValue(new Error('Failed to create scalingConfig after 60 attempts'));
181215

182216
await expect(
183-
scalingConfig.provisionConfigErrorRetry('ScalingConfig', 'LATEST', { minInstances: 1 }),
217+
utils.provisionConfigErrorRetry(
218+
scalingConfig.fcSdk,
219+
'ScalingConfig',
220+
'test-function',
221+
'LATEST',
222+
{ minInstances: 1 },
223+
),
184224
).rejects.toThrow('Failed to create scalingConfig after 60 attempts');
185225

186-
expect(removeScalingConfigSpy).toHaveBeenCalledWith('LATEST');
187-
expect(mockFcSdk.putFunctionScalingConfig).toHaveBeenCalledTimes(61);
188-
expect(logger.info).toHaveBeenCalledWith(
189-
'Retry 59/60: putFunctionScalingConfig failed, retrying...',
226+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
227+
scalingConfig.fcSdk,
228+
'ScalingConfig',
229+
'test-function',
230+
'LATEST',
231+
{ minInstances: 1 },
190232
);
191233
});
192234

@@ -207,16 +249,26 @@ describe('ScalingConfig', () => {
207249
writable: true,
208250
});
209251

210-
const beforeSpy = jest.spyOn(scalingConfig, 'before').mockResolvedValue(undefined);
252+
const utils = require('../../../../../src/subCommands/deploy/utils');
253+
const provisionConfigErrorRetrySpy = jest
254+
.spyOn(utils, 'provisionConfigErrorRetry')
255+
.mockResolvedValue(undefined);
211256

212-
await scalingConfig.provisionConfigErrorRetry('ProvisionConfig', 'LATEST', {
213-
minInstances: 1,
214-
});
257+
await utils.provisionConfigErrorRetry(
258+
scalingConfig.fcSdk,
259+
'ProvisionConfig',
260+
'test-function',
261+
'LATEST',
262+
{ minInstances: 1 },
263+
);
215264

216-
expect(beforeSpy).toHaveBeenCalled();
217-
expect(mockFcSdk.putFunctionProvisionConfig).toHaveBeenCalledWith('test-function', 'LATEST', {
218-
minInstances: 1,
219-
});
265+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
266+
scalingConfig.fcSdk,
267+
'ProvisionConfig',
268+
'test-function',
269+
'LATEST',
270+
{ minInstances: 1 },
271+
);
220272
});
221273
});
222274

@@ -323,15 +375,20 @@ describe('ScalingConfig', () => {
323375
});
324376

325377
// Mock provisionConfigErrorRetry
378+
const utils = require('../../../../../src/subCommands/deploy/utils');
326379
const provisionConfigErrorRetrySpy = jest
327-
.spyOn(scalingConfig, 'provisionConfigErrorRetry')
380+
.spyOn(utils, 'provisionConfigErrorRetry')
328381
.mockResolvedValue(undefined);
329382

330383
const result = await scalingConfig.run();
331384

332-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ScalingConfig', 'LATEST', {
333-
minInstances: 1,
334-
});
385+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
386+
scalingConfig.fcSdk,
387+
'ScalingConfig',
388+
'test-function',
389+
'LATEST',
390+
{ minInstances: 1 },
391+
);
335392
expect(logger.info).toHaveBeenCalledWith(
336393
'ScalingConfig of test-function/LATEST is ready. CurrentInstances: 1, MinInstances: 1',
337394
);
@@ -362,8 +419,9 @@ describe('ScalingConfig', () => {
362419
});
363420

364421
// Mock provisionConfigErrorRetry
422+
const utils = require('../../../../../src/subCommands/deploy/utils');
365423
const provisionConfigErrorRetrySpy = jest
366-
.spyOn(scalingConfig, 'provisionConfigErrorRetry')
424+
.spyOn(utils, 'provisionConfigErrorRetry')
367425
.mockResolvedValue(undefined);
368426

369427
const waitForScalingReadySpy = jest
@@ -372,9 +430,13 @@ describe('ScalingConfig', () => {
372430

373431
await scalingConfig.run();
374432

375-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ScalingConfig', 'LATEST', {
376-
minInstances: 1,
377-
});
433+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
434+
scalingConfig.fcSdk,
435+
'ScalingConfig',
436+
'test-function',
437+
'LATEST',
438+
{ minInstances: 1 },
439+
);
378440
expect(waitForScalingReadySpy).toHaveBeenCalledWith('LATEST', {
379441
minInstances: 1,
380442
});
@@ -402,17 +464,22 @@ describe('ScalingConfig', () => {
402464
});
403465

404466
// Mock provisionConfigErrorRetry
467+
const utils = require('../../../../../src/subCommands/deploy/utils');
405468
const provisionConfigErrorRetrySpy = jest
406-
.spyOn(scalingConfig, 'provisionConfigErrorRetry')
469+
.spyOn(utils, 'provisionConfigErrorRetry')
407470
.mockResolvedValue(undefined);
408471

409472
const waitForScalingReadySpy = jest.spyOn(scalingConfig as any, 'waitForScalingReady');
410473

411474
await scalingConfig.run();
412475

413-
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith('ScalingConfig', 'LATEST', {
414-
minInstances: 1,
415-
});
476+
expect(provisionConfigErrorRetrySpy).toHaveBeenCalledWith(
477+
scalingConfig.fcSdk,
478+
'ScalingConfig',
479+
'test-function',
480+
'LATEST',
481+
{ minInstances: 1 },
482+
);
416483
expect(waitForScalingReadySpy).not.toHaveBeenCalled();
417484
expect(logger.info).toHaveBeenCalledWith(
418485
'Skip wait scalingConfig of test-function/LATEST to instance up',

0 commit comments

Comments
 (0)