Skip to content

Commit 39c3d67

Browse files
authored
Merge pull request #131 from devsapp/fix-sync
feat: Add scaling configuration support to Sync command and enhance t…
2 parents c612e82 + b0db75c commit 39c3d67

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

__tests__/ut/commands/sync_test.ts

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import fs from 'fs';
55
import fs_extra from 'fs-extra';
66
import downloads from '@serverless-devs/downloads';
77

8+
// Mock the ScalingPolicy import that's causing issues
9+
jest.mock('@alicloud/fc20230330', () => ({
10+
ScalingPolicy: jest.fn().mockImplementation((config) => config),
11+
}));
12+
813
// Mock dependencies
914
jest.mock('../../../src/resources/fc', () => {
1015
// Define GetApiType enum for the mock
@@ -108,6 +113,7 @@ describe('Sync', () => {
108113
listTriggers: jest.fn(),
109114
getAsyncInvokeConfig: jest.fn(),
110115
getFunctionProvisionConfig: jest.fn(),
116+
getFunctionScalingConfig: jest.fn(),
111117
getFunctionConcurrency: jest.fn(),
112118
getVpcBinding: jest.fn(),
113119
getFunctionCode: jest.fn(),
@@ -158,6 +164,14 @@ describe('Sync', () => {
158164
vpcIds: ['vpc-12345'],
159165
});
160166

167+
mockFcInstance.getFunctionScalingConfig.mockResolvedValue({
168+
currentInstances: 1,
169+
minInstances: 1,
170+
targetInstances: 1,
171+
currentError: '',
172+
functionArn: 'arn:acs:fc:cn-hangzhou:123456789:functions/test-function',
173+
});
174+
161175
mockFcInstance.getFunctionCode.mockResolvedValue({
162176
url: 'https://test.oss-cn-hangzhou.aliyuncs.com/code.zip',
163177
});
@@ -306,6 +320,7 @@ describe('Sync', () => {
306320
expect(mockFcInstance.listTriggers).toHaveBeenCalled();
307321
expect(mockFcInstance.getAsyncInvokeConfig).toHaveBeenCalled();
308322
expect(mockFcInstance.getFunctionProvisionConfig).toHaveBeenCalled();
323+
expect(mockFcInstance.getFunctionScalingConfig).toHaveBeenCalled();
309324
expect(mockFcInstance.getFunctionConcurrency).toHaveBeenCalled();
310325
expect(mockFcInstance.getVpcBinding).toHaveBeenCalled();
311326
expect(result).toHaveProperty('ymlPath');
@@ -345,6 +360,26 @@ describe('Sync', () => {
345360

346361
expect(downloads).toHaveBeenCalled();
347362
});
363+
364+
it('should handle scaling config successfully', async () => {
365+
mockFcInstance.getFunctionScalingConfig.mockResolvedValue({
366+
currentInstances: 1,
367+
minInstances: 1,
368+
targetInstances: 1,
369+
currentError: '',
370+
functionArn: 'arn:acs:fc:cn-hangzhou:123456789:functions/test-function',
371+
});
372+
373+
const sync = new Sync(mockInputs);
374+
const result = await sync.run();
375+
376+
expect(mockFcInstance.getFunctionScalingConfig).toHaveBeenCalledWith(
377+
'test-function',
378+
'LATEST',
379+
);
380+
expect(result).toHaveProperty('ymlPath');
381+
expect(result).toHaveProperty('codePath');
382+
});
348383
});
349384

350385
describe('write', () => {
@@ -385,6 +420,13 @@ describe('Sync', () => {
385420
currentError: '',
386421
functionArn: 'arn:acs:fc:cn-hangzhou:123456789:functions/test-function',
387422
};
423+
const scalingConfig = {
424+
currentInstances: 1,
425+
minInstances: 1,
426+
targetInstances: 1,
427+
currentError: '',
428+
functionArn: 'arn:acs:fc:cn-hangzhou:123456789:functions/test-function',
429+
};
388430

389431
const result = await sync.write(
390432
functionConfig,
@@ -393,6 +435,7 @@ describe('Sync', () => {
393435
vpcBindingConfig,
394436
concurrencyConfig,
395437
provisionConfig,
438+
scalingConfig,
396439
);
397440

398441
expect(fs_extra.removeSync).toHaveBeenCalledWith(
@@ -422,7 +465,7 @@ describe('Sync', () => {
422465
},
423466
};
424467

425-
await sync.write(functionConfig, [], {}, {}, {}, {});
468+
await sync.write(functionConfig, [], {}, {}, {}, {}, {});
426469

427470
expect(downloads).not.toHaveBeenCalled();
428471
expect(fs_extra.removeSync).not.toHaveBeenCalled();
@@ -443,9 +486,48 @@ describe('Sync', () => {
443486
{},
444487
{},
445488
{},
489+
{},
446490
);
447491

448492
expect(fs.mkdirSync).toHaveBeenCalledWith('/custom/target', { recursive: true });
449493
});
494+
495+
it('should handle scaling configuration in write method', async () => {
496+
const sync = new Sync(mockInputs);
497+
const functionConfig = {
498+
functionName: 'test-function',
499+
runtime: 'nodejs18',
500+
handler: 'index.handler',
501+
code: {
502+
location: 'https://test.oss-cn-hangzhou.aliyuncs.com/code.zip',
503+
},
504+
};
505+
const triggers = [];
506+
const asyncInvokeConfig = {};
507+
const vpcBindingConfig = {};
508+
const concurrencyConfig = {};
509+
const provisionConfig = {};
510+
const scalingConfig = {
511+
currentInstances: 2,
512+
minInstances: 1,
513+
targetInstances: 3,
514+
currentError: '',
515+
functionArn: 'arn:acs:fc:cn-hangzhou:123456789:functions/test-function',
516+
};
517+
518+
const result = await sync.write(
519+
functionConfig,
520+
triggers,
521+
asyncInvokeConfig,
522+
vpcBindingConfig,
523+
concurrencyConfig,
524+
provisionConfig,
525+
scalingConfig,
526+
);
527+
528+
expect(fs.writeFileSync).toHaveBeenCalled();
529+
expect(result).toHaveProperty('ymlPath');
530+
expect(result).toHaveProperty('codePath');
531+
});
450532
});
451533
});

src/subCommands/sync/index.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export default class Sync {
106106
let vpcBindingConfig = {};
107107
let concurrencyConfig = {};
108108
let provisionConfig = {};
109+
let scalingConfig = {};
109110
try {
110111
asyncInvokeConfig = await this.fcSdk.getAsyncInvokeConfig(
111112
this.functionName,
@@ -122,6 +123,12 @@ export default class Sync {
122123
// eslint-disable-next-line no-empty
123124
}
124125

126+
try {
127+
scalingConfig = await this.fcSdk.getFunctionScalingConfig(this.functionName, 'LATEST');
128+
} catch (ex) {
129+
// eslint-disable-next-line no-empty
130+
}
131+
125132
try {
126133
concurrencyConfig = await this.fcSdk.getFunctionConcurrency(this.functionName);
127134
} catch (ex) {
@@ -143,6 +150,7 @@ export default class Sync {
143150
vpcBindingConfig,
144151
concurrencyConfig,
145152
provisionConfig,
153+
scalingConfig,
146154
);
147155
}
148156

@@ -153,6 +161,7 @@ export default class Sync {
153161
vpcBindingConfig: any,
154162
concurrencyConfig: any,
155163
provisionConfig: any,
164+
scalingConfig: any,
156165
) {
157166
const syncFolderName = 'sync-clone';
158167

@@ -207,12 +216,28 @@ export default class Sync {
207216
if (!_.isEmpty(asyncInvokeConfig)) {
208217
props.asyncInvokeConfig = asyncInvokeConfig;
209218
}
219+
210220
if (!_.isEmpty(provisionConfig)) {
211221
_.unset(provisionConfig, 'current');
212222
_.unset(provisionConfig, 'currentError');
213223
_.unset(provisionConfig, 'functionArn');
214-
props.provisionConfig = provisionConfig;
224+
const isElasticInstance =
225+
provisionConfig.alwaysAllocateCPU === true && provisionConfig.alwaysAllocateGPU === true;
226+
227+
if (isElasticInstance) {
228+
props.provisionConfig = provisionConfig;
229+
} else if (!_.isEmpty(scalingConfig)) {
230+
_.unset(scalingConfig, 'currentError');
231+
_.unset(scalingConfig, 'currentInstances');
232+
_.unset(scalingConfig, 'targetInstances');
233+
_.unset(scalingConfig, 'enableOnDemandScaling');
234+
_.unset(scalingConfig, 'functionArn');
235+
props.scalingConfig = scalingConfig;
236+
} else {
237+
throw new Error('ScalingConfig not found');
238+
}
215239
}
240+
216241
if (!_.isEmpty(concurrencyConfig)) {
217242
_.unset(concurrencyConfig, 'functionArn');
218243
props.concurrencyConfig = concurrencyConfig;

0 commit comments

Comments
 (0)