Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions __tests__/e2e/ci-mac-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ s info -t s2.yaml
s remove -y -t s2.yaml
cd ..

echo " ********* test scaling config *********"
cd scaling && ./run && cd -

echo " ********* command-api *********"
cd command-api && ./run && cd -
cd command-api && ./run_cli_mode && cd -
6 changes: 6 additions & 0 deletions __tests__/e2e/command-api/run_cli_mode
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ s cli $fc3_dir provision remove --qualifier test -y --region $REGION --function-
s cli $fc3_dir provision list --region $REGION --function-name $functionName -a quanxi
s cli $fc3_dir provision put --qualifier test --target 2 --region $REGION --function-name $functionName -a quanxi


s cli $fc3_dir scaling put --qualifier test --min-instances 1 --region $REGION --function-name $functionName -a quanxi
s cli $fc3_dir scaling list --region $REGION --function-name $functionName -a quanxi
s cli $fc3_dir scaling list --region $REGION --function-name $functionName -a quanxi
s cli $fc3_dir scaling remove -y --region $REGION --function-name $functionName -a quanxi

s cli $fc3_dir remove -y --region $REGION --function-name $functionName -a quanxi


Expand Down
10 changes: 10 additions & 0 deletions __tests__/e2e/scaling/code/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
exports.handler = async (event) => {
console.log('Received event:', JSON.stringify(event, null, 2));
return {
statusCode: 200,
body: JSON.stringify({
message: 'Hello from FC3 with Scaling Config!',
event,
}),
};
};
41 changes: 41 additions & 0 deletions __tests__/e2e/scaling/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

set -e
set -v

export fc_component_function_name=nodejs-$(uname)-$(uname -m)-$RANDSTR

echo "test command scaling config..."

# 部署函数
s deploy -y

# 测试scaling config相关命令
echo "Testing scaling config commands..."

# 发布版本
s version publish --description test
s version list

# 创建别名
s alias publish --alias-name test --version-id latest
s alias list

# 测试scaling config
s scaling put --qualifier test --min-instances 2 --horizontal-scaling-policies '[{"name":"test-policy","metricType":"CPUUtilization","metricTarget":0.7,"minInstances":2,"maxInstances":15}]' --scheduled-policies '[{"name":"test-scheduled","scheduleExpression":"cron(0 0 5 * * *)","target":8,"startTime":"2023-08-15T02:04:00.000Z","endTime":"2033-08-15T03:04:00.000Z"}]'
s scaling put --min-instances 2
s scaling list

# # 删除scaling config
s scaling remove --qualifier test -y
s scaling list

# 使用配置文件部署
s deploy -y

# 再次检查
s scaling get
s scaling list

# 清理
s remove -y
37 changes: 37 additions & 0 deletions __tests__/e2e/scaling/s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
edition: 3.0.0
name: test-scaling-config
access: quanxi

vars:
region: ${env('REGION', 'cn-hongkong')}

resources:
fcDemo:
component: ${env('fc_component_version', path('../../../'))}
props:
region: ${vars.region}
functionName: fc3-scaling-${env('fc_component_function_name', 'scaling')}
runtime: nodejs18
code: ./code
handler: index.handler
memorySize: 128
timeout: 60
logConfig: auto

scalingConfig:
minInstances: 1
horizontalScalingPolicies:
- name: test-policy
metricType: CPUUtilization
metricTarget: 0.6
minInstances: 1
maxInstances: 10
scheduledPolicies:
- name: test-scheduled
scheduleExpression: cron(0 0 4 * * *)
target: 5
startTime: '2023-08-15T02:04:00.000Z'
endTime: '2033-08-15T03:04:00.000Z'

concurrencyConfig:
reservedConcurrency: 100
36 changes: 36 additions & 0 deletions __tests__/e2e/scaling/s2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
edition: 3.0.0
name: test-scaling-config
access: quanxi

resources:
fcDemo:
component: ${env('fc_component_version', path('../../../'))}
props:
region: cn-shanghai
functionName: fc3-scaling-pool-${env('fc_component_function_name', 'scaling')}
code: ./code
handler: index.handler
timeout: 60
logConfig: auto
gpuConfig:
gpuMemorySize: 49152
gpuType: fc.gpu.ada.1
runtime: custom-container
cpu: 8
customContainerConfig:
image: >-
registry.cn-shanghai.aliyuncs.com/serverless_devs/custom-container-http-examples:springboot
port: 9000
instanceConcurrency: 20
memorySize: 65536
diskSize: 10240

provisionConfig:
defaultTarget: 1
# alwaysAllocateCPU: false
# alwaysAllocateGPU: false

# scalingConfig:
# # residentPoolId: fc-pool-5f044a31f87171jkwaraws
# minInstances: 1

25 changes: 25 additions & 0 deletions __tests__/e2e/scaling/s3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
edition: 3.0.0
name: test-scaling-config
access: quanxi

vars:
region: ${env('REGION', 'cn-hongkong')}

resources:
fcDemo:
component: ${env('fc_component_version', path('../../../'))}
props:
region: ${vars.region}
functionName: fc3-provision-${env('fc_component_function_name', 'scaling')}
runtime: nodejs18
code: ./code
handler: index.handler
memorySize: 128
timeout: 60
logConfig: auto
# provisionConfig:
# defaultTarget: 1
# alwaysAllocateCPU: true
# alwaysAllocateGPU: true
scalingConfig:
minInstances: 1
14 changes: 14 additions & 0 deletions __tests__/ut/deploy_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ describe('Deploy', () => {
runtime: 'nodejs18',
handler: 'index.handler',
code: './code',
provisionConfig: {
defaultTarget: 10,
alwaysAllocateCPU: false,
alwaysAllocateGPU: false,
scheduledActions: [],
targetTrackingPolicies: [],
},
},
command: 'deploy',
args: [],
Expand All @@ -58,10 +65,17 @@ describe('Deploy', () => {
access: 'default',
},
outputs: {},
credential: {
AccountID: '123456789',
AccessKeyID: 'test-key',
AccessKeySecret: 'test-secret',
SecurityToken: 'test-token',
},
getCredential: jest.fn().mockResolvedValue({
AccountID: '123456789',
AccessKeyID: 'test-key',
AccessKeySecret: 'test-secret',
SecurityToken: 'test-token',
}),
};

Expand Down
30 changes: 21 additions & 9 deletions __tests__/ut/provision_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,14 @@ describe('Provision', () => {
);
});

it('should throw error when qualifier is not specified', async () => {
it('should use default qualifier when qualifier is not specified', async () => {
mockInputs.args = ['get'];
provision = new Provision(mockInputs);
await expect(provision.get()).rejects.toThrow(
'Qualifier not specified, please specify --qualifier',
// The current implementation uses 'LATEST' as default when qualifier is not specified
await expect(provision.get()).resolves.toEqual({ target: 10 });
expect(mockFcInstance.getFunctionProvisionConfig).toHaveBeenCalledWith(
'test-function',
'LATEST', // Default qualifier
);
});
});
Expand All @@ -195,11 +198,17 @@ describe('Provision', () => {
);
});

it('should throw error when qualifier is not specified', async () => {
it('should use default qualifier when qualifier is not specified', async () => {
mockInputs.args = ['put', '--target', '10'];
provision = new Provision(mockInputs);
await expect(provision.put()).rejects.toThrow(
'Qualifier not specified, please specify --qualifier',
// The current implementation uses 'LATEST' as default when qualifier is not specified
await expect(provision.put()).resolves.toEqual({ success: true });
expect(mockFcInstance.putFunctionProvisionConfig).toHaveBeenCalledWith(
'test-function',
'LATEST', // Default qualifier
expect.objectContaining({
target: 10,
}),
);
});

Expand Down Expand Up @@ -304,11 +313,14 @@ describe('Provision', () => {
);
});

it('should throw error when qualifier is not specified', async () => {
it('should use default qualifier when qualifier is not specified', async () => {
mockInputs.args = ['remove', '--assume-yes'];
provision = new Provision(mockInputs);
await expect(provision.remove()).rejects.toThrow(
'Qualifier not specified, please specify --qualifier',
// The current implementation uses 'LATEST' as default when qualifier is not specified
await expect(provision.remove()).resolves.toBeUndefined();
expect(mockFcInstance.removeFunctionProvisionConfig).toHaveBeenCalledWith(
'test-function',
'LATEST', // Default qualifier
);
});

Expand Down
22 changes: 9 additions & 13 deletions __tests__/ut/remove_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ describe('Remove', () => {
(remove as any).resources = {
function: 'test-function',
vpcBindingConfigs: { vpcIds: ['vpc-123'] },
provision: [{ qualifier: 'LATEST' }],
// provision: [{ qualifier: 'LATEST' }], // Provision code is commented out in source
concurrency: 10,
aliases: ['test-alias'],
versions: ['1'],
Expand All @@ -198,10 +198,10 @@ describe('Remove', () => {
await (remove as any).removeFunction();

expect(mockFcInstance.deleteVpcBinding).toHaveBeenCalledWith('test-function', 'vpc-123');
expect(mockFcInstance.removeFunctionProvisionConfig).toHaveBeenCalledWith(
'test-function',
'LATEST',
);
// expect(mockFcInstance.removeFunctionProvisionConfig).toHaveBeenCalledWith( // Provision code is commented out in source
// 'test-function',
// 'LATEST',
// );
expect(mockFcInstance.removeFunctionConcurrency).toHaveBeenCalledWith('test-function');
expect(mockFcInstance.removeAlias).toHaveBeenCalledWith('test-function', 'test-alias');
expect(mockFcInstance.removeFunctionVersion).toHaveBeenCalledWith('test-function', '1');
Expand All @@ -212,18 +212,14 @@ describe('Remove', () => {
// Mock resources to be removed
(remove as any).resources = {
function: 'test-function',
provision: [{ qualifier: 'LATEST' }],
// provision: [{ qualifier: 'LATEST' }], // Provision code is commented out in source
};

const provisionError = new Error('Provision config exists');
(provisionError as any).code = 'ProvisionConfigExist';
mockFcInstance.fc20230330Client.deleteFunction
.mockRejectedValueOnce(provisionError)
.mockResolvedValueOnce({});

// Since provision code is commented out in source, we'll test that the function still works
await (remove as any).removeFunction();

expect(mockFcInstance.fc20230330Client.deleteFunction).toHaveBeenCalledTimes(2);
// The function should still be called successfully
expect(mockFcInstance.fc20230330Client.deleteFunction).toHaveBeenCalledWith('test-function');
});
});

Expand Down
Loading