Skip to content

Commit 8ed590f

Browse files
committed
feat: Add support for micro-sandbox configuration
1 parent 4ca1c1b commit 8ed590f

7 files changed

Lines changed: 186 additions & 9 deletions

File tree

__tests__/complete-props.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ resources:
7777
project: string
7878
memorySize: 512
7979
instanceConcurrency: 1 # 该参数仅针对 custom/custom.debian10/custom.debian11/custom-container runtime 有效,范围为 [1, 200]
80+
microSandboxConfig:
81+
osType: string
82+
readyCommand: string
83+
startCommand: string
8084
nasConfig:
8185
groupId: 65534
8286
mountPoints:

__tests__/ut/local/local_test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,20 @@ describe('ComponentLocal', () => {
339339
expect(mockInstance.invoke).toHaveBeenCalled();
340340
});
341341

342+
it('should route micro-sandbox runtime to CustomContainerLocalInvoke', async () => {
343+
mockInputs.props.runtime = 'micro-sandbox';
344+
const {
345+
CustomContainerLocalInvoke,
346+
} = require('../../../src/subCommands/local/impl/invoke/customContainerLocalInvoke');
347+
const mockInstance = { invoke: jest.fn().mockResolvedValue(undefined) };
348+
(CustomContainerLocalInvoke as jest.Mock).mockImplementation(() => mockInstance);
349+
350+
await componentLocal.invoke(mockInputs);
351+
352+
expect(CustomContainerLocalInvoke).toHaveBeenCalledWith(mockInputs);
353+
expect(mockInstance.invoke).toHaveBeenCalled();
354+
});
355+
342356
it('should warn when function has http trigger', async () => {
343357
mockInputs.props.runtime = 'nodejs18';
344358
mockInputs.props.triggers = [
@@ -557,6 +571,30 @@ describe('ComponentLocal', () => {
557571
expect(mockInstance.start).toHaveBeenCalled();
558572
});
559573

574+
it('should route micro-sandbox runtime to CustomContainerLocalStart', async () => {
575+
mockInputs.props.runtime = 'micro-sandbox';
576+
mockInputs.props.triggers = [
577+
{
578+
triggerType: 'http',
579+
triggerName: 'httpTrigger',
580+
triggerConfig: {
581+
authType: 'anonymous',
582+
methods: ['GET'],
583+
},
584+
},
585+
];
586+
const {
587+
CustomContainerLocalStart,
588+
} = require('../../../src/subCommands/local/impl/start/customContainerLocalStart');
589+
const mockInstance = { start: jest.fn().mockResolvedValue(undefined) };
590+
(CustomContainerLocalStart as jest.Mock).mockImplementation(() => mockInstance);
591+
592+
await componentLocal.start(mockInputs);
593+
594+
expect(CustomContainerLocalStart).toHaveBeenCalledWith(mockInputs);
595+
expect(mockInstance.start).toHaveBeenCalled();
596+
});
597+
560598
it('should log error when function does not have http trigger', async () => {
561599
mockInputs.props.runtime = 'nodejs18';
562600
mockInputs.props.triggers = [

__tests__/ut/resources/fc/impl/client_test.ts

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ import FC_Client, { fc2Client } from '../../../../../src/resources/fc/impl/clien
22
import { ICredentials } from '@serverless-devs/component-interface';
33
import { Config } from '@alicloud/openapi-client';
44
import FC2 from '@alicloud/fc2';
5-
import { IRegion } from '../../../../../src/interface';
5+
import { IRegion, IFunction } from '../../../../../src/interface';
66
import * as utils from '../../../../../src/resources/fc/impl/utils';
77
import _ from 'lodash';
88

99
// Mock external dependencies
1010
jest.mock('@alicloud/openapi-client');
1111
jest.mock('@alicloud/fc2');
12+
jest.mock('@alicloud/fc20230330', () => {
13+
const actual = jest.requireActual('@alicloud/fc20230330');
14+
return Object.assign({}, actual, {
15+
__esModule: true,
16+
default: jest.fn().mockImplementation(() => ({})),
17+
});
18+
});
1219
jest.mock('../../../../../src/resources/fc/impl/utils', () => ({
1320
...jest.requireActual('../../../../../src/resources/fc/impl/utils'),
1421
getCustomEndpoint: jest.fn(),
@@ -201,4 +208,107 @@ describe('FC_Client', () => {
201208
expect(result).toBe(false);
202209
});
203210
});
211+
212+
describe('createFunction', () => {
213+
let client: FC_Client;
214+
215+
beforeEach(() => {
216+
(utils.getCustomEndpoint as jest.Mock).mockReturnValue({
217+
protocol: 'https',
218+
host: 'test-endpoint.com',
219+
endpoint: 'https://test-endpoint.com',
220+
});
221+
client = new FC_Client(mockRegion, mockCredentials, mockOptions);
222+
});
223+
224+
it('should forward microSandboxConfig to the request body', async () => {
225+
const createFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
226+
Object.defineProperty(client, 'fc20230330Client', {
227+
value: { createFunctionWithOptions },
228+
writable: true,
229+
});
230+
231+
const config: IFunction = {
232+
functionName: 'test-function',
233+
runtime: 'micro-sandbox',
234+
microSandboxConfig: {
235+
osType: 'linux',
236+
readyCommand: 'echo ready',
237+
startCommand: 'echo start',
238+
},
239+
} as IFunction;
240+
241+
await client.createFunction(config);
242+
243+
expect(createFunctionWithOptions).toHaveBeenCalledTimes(1);
244+
const request = createFunctionWithOptions.mock.calls[0][0];
245+
const bodyMap = request.body.toMap();
246+
expect(bodyMap.runtime).toBe('micro-sandbox');
247+
expect(bodyMap.microSandboxConfig).toEqual({
248+
osType: 'linux',
249+
readyCommand: 'echo ready',
250+
startCommand: 'echo start',
251+
});
252+
});
253+
254+
it('should not set microSandboxConfig when it is not provided', async () => {
255+
const createFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
256+
Object.defineProperty(client, 'fc20230330Client', {
257+
value: { createFunctionWithOptions },
258+
writable: true,
259+
});
260+
261+
await client.createFunction({
262+
functionName: 'test-function',
263+
runtime: 'nodejs18',
264+
} as IFunction);
265+
266+
const bodyMap = createFunctionWithOptions.mock.calls[0][0].body.toMap();
267+
expect(bodyMap.microSandboxConfig).toBeUndefined();
268+
});
269+
});
270+
271+
describe('updateFunction', () => {
272+
let client: FC_Client;
273+
274+
beforeEach(() => {
275+
(utils.getCustomEndpoint as jest.Mock).mockReturnValue({
276+
protocol: 'https',
277+
host: 'test-endpoint.com',
278+
endpoint: 'https://test-endpoint.com',
279+
});
280+
client = new FC_Client(mockRegion, mockCredentials, mockOptions);
281+
});
282+
283+
it('should forward microSandboxConfig to the update request body', async () => {
284+
const updateFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
285+
Object.defineProperty(client, 'fc20230330Client', {
286+
value: { updateFunctionWithOptions },
287+
writable: true,
288+
});
289+
290+
const config: IFunction = {
291+
functionName: 'test-function',
292+
runtime: 'micro-sandbox',
293+
microSandboxConfig: {
294+
osType: 'linux',
295+
readyCommand: 'echo ready',
296+
startCommand: 'echo start',
297+
},
298+
} as IFunction;
299+
300+
await client.updateFunction(config);
301+
302+
expect(updateFunctionWithOptions).toHaveBeenCalledTimes(1);
303+
// first positional arg is functionName, second is the request
304+
expect(updateFunctionWithOptions.mock.calls[0][0]).toBe('test-function');
305+
const request = updateFunctionWithOptions.mock.calls[0][1];
306+
const bodyMap = request.body.toMap();
307+
expect(bodyMap.microSandboxConfig).toEqual({
308+
osType: 'linux',
309+
readyCommand: 'echo ready',
310+
startCommand: 'echo start',
311+
});
312+
});
313+
});
204314
});

package-lock.json

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"dependencies": {
2525
"@alicloud/devs20230714": "^2.5.0",
2626
"@alicloud/fc2": "^2.6.6",
27-
"@alicloud/fc20230330": "4.7.5",
27+
"@alicloud/fc20230330": "4.7.7",
2828
"@alicloud/pop-core": "^1.8.0",
2929
"@serverless-cd/srm-aliyun-oss": "^0.0.1-beta.8",
3030
"@serverless-cd/srm-aliyun-pop-core": "^0.0.8-beta.1",

src/interface/function.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ export interface ILogConfig {
7575
logBeginRule?: 'DefaultRegex' | 'None';
7676
}
7777

78+
export interface IMicroSandboxConfig {
79+
osType?: string;
80+
readyCommand?: string;
81+
startCommand?: string;
82+
}
83+
7884
export interface INasConfig {
7985
userId: number;
8086
groupId: number;
@@ -141,6 +147,7 @@ export interface IFunction {
141147
resourceGroupId?: string;
142148

143149
logConfig?: 'auto' | ILogConfig;
150+
microSandboxConfig?: IMicroSandboxConfig;
144151
nasConfig?: 'auto' | INasConfig;
145152
ossMountConfig?: 'auto' | IOssMountConfig;
146153
role?: 'auto' | string;

src/schema.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,20 @@
637637
],
638638
"type": "object"
639639
},
640+
"IMicroSandboxConfig": {
641+
"properties": {
642+
"osType": {
643+
"type": "string"
644+
},
645+
"readyCommand": {
646+
"type": "string"
647+
},
648+
"startCommand": {
649+
"type": "string"
650+
}
651+
},
652+
"type": "object"
653+
},
640654
"INasConfig": {
641655
"properties": {
642656
"groupId": {
@@ -1313,6 +1327,9 @@
13131327
"minimum": 128,
13141328
"maximum": 32768
13151329
},
1330+
"microSandboxConfig": {
1331+
"$ref": "#/definitions/IMicroSandboxConfig"
1332+
},
13161333
"nasConfig": {
13171334
"anyOf": [
13181335
{

0 commit comments

Comments
 (0)