Skip to content
Open
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
4 changes: 4 additions & 0 deletions __tests__/complete-props.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ resources:
project: string
memorySize: 512
instanceConcurrency: 1 # 该参数仅针对 custom/custom.debian10/custom.debian11/custom-container runtime 有效,范围为 [1, 200]
microSandboxConfig:
osType: string
readyCommand: string
startCommand: string
nasConfig:
groupId: 65534
mountPoints:
Expand Down
38 changes: 38 additions & 0 deletions __tests__/ut/local/local_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,20 @@ describe('ComponentLocal', () => {
expect(mockInstance.invoke).toHaveBeenCalled();
});

it('should route micro-sandbox runtime to CustomContainerLocalInvoke', async () => {
mockInputs.props.runtime = 'micro-sandbox';
const {
CustomContainerLocalInvoke,
} = require('../../../src/subCommands/local/impl/invoke/customContainerLocalInvoke');
const mockInstance = { invoke: jest.fn().mockResolvedValue(undefined) };
(CustomContainerLocalInvoke as jest.Mock).mockImplementation(() => mockInstance);

await componentLocal.invoke(mockInputs);

expect(CustomContainerLocalInvoke).toHaveBeenCalledWith(mockInputs);
expect(mockInstance.invoke).toHaveBeenCalled();
});

it('should warn when function has http trigger', async () => {
mockInputs.props.runtime = 'nodejs18';
mockInputs.props.triggers = [
Expand Down Expand Up @@ -557,6 +571,30 @@ describe('ComponentLocal', () => {
expect(mockInstance.start).toHaveBeenCalled();
});

it('should route micro-sandbox runtime to CustomContainerLocalStart', async () => {
mockInputs.props.runtime = 'micro-sandbox';
mockInputs.props.triggers = [
{
triggerType: 'http',
triggerName: 'httpTrigger',
triggerConfig: {
authType: 'anonymous',
methods: ['GET'],
},
},
];
const {
CustomContainerLocalStart,
} = require('../../../src/subCommands/local/impl/start/customContainerLocalStart');
const mockInstance = { start: jest.fn().mockResolvedValue(undefined) };
(CustomContainerLocalStart as jest.Mock).mockImplementation(() => mockInstance);

await componentLocal.start(mockInputs);

expect(CustomContainerLocalStart).toHaveBeenCalledWith(mockInputs);
expect(mockInstance.start).toHaveBeenCalled();
});

it('should log error when function does not have http trigger', async () => {
mockInputs.props.runtime = 'nodejs18';
mockInputs.props.triggers = [
Expand Down
112 changes: 111 additions & 1 deletion __tests__/ut/resources/fc/impl/client_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import FC_Client, { fc2Client } from '../../../../../src/resources/fc/impl/clien
import { ICredentials } from '@serverless-devs/component-interface';
import { Config } from '@alicloud/openapi-client';
import FC2 from '@alicloud/fc2';
import { IRegion } from '../../../../../src/interface';
import { IRegion, IFunction } from '../../../../../src/interface';
import * as utils from '../../../../../src/resources/fc/impl/utils';
import _ from 'lodash';

// Mock external dependencies
jest.mock('@alicloud/openapi-client');
jest.mock('@alicloud/fc2');
jest.mock('@alicloud/fc20230330', () => {
const actual = jest.requireActual('@alicloud/fc20230330');
return Object.assign({}, actual, {
__esModule: true,
default: jest.fn().mockImplementation(() => ({})),
});
});
jest.mock('../../../../../src/resources/fc/impl/utils', () => ({
...jest.requireActual('../../../../../src/resources/fc/impl/utils'),
getCustomEndpoint: jest.fn(),
Expand Down Expand Up @@ -201,4 +208,107 @@ describe('FC_Client', () => {
expect(result).toBe(false);
});
});

describe('createFunction', () => {
let client: FC_Client;

beforeEach(() => {
(utils.getCustomEndpoint as jest.Mock).mockReturnValue({
protocol: 'https',
host: 'test-endpoint.com',
endpoint: 'https://test-endpoint.com',
});
client = new FC_Client(mockRegion, mockCredentials, mockOptions);
});

it('should forward microSandboxConfig to the request body', async () => {
const createFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
Object.defineProperty(client, 'fc20230330Client', {
value: { createFunctionWithOptions },
writable: true,
});

const config: IFunction = {
functionName: 'test-function',
runtime: 'micro-sandbox',
microSandboxConfig: {
osType: 'linux',
readyCommand: 'echo ready',
startCommand: 'echo start',
},
} as IFunction;

await client.createFunction(config);

expect(createFunctionWithOptions).toHaveBeenCalledTimes(1);
const request = createFunctionWithOptions.mock.calls[0][0];
const bodyMap = request.body.toMap();
expect(bodyMap.runtime).toBe('micro-sandbox');
expect(bodyMap.microSandboxConfig).toEqual({
osType: 'linux',
readyCommand: 'echo ready',
startCommand: 'echo start',
});
});

it('should not set microSandboxConfig when it is not provided', async () => {
const createFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
Object.defineProperty(client, 'fc20230330Client', {
value: { createFunctionWithOptions },
writable: true,
});

await client.createFunction({
functionName: 'test-function',
runtime: 'nodejs18',
} as IFunction);

const bodyMap = createFunctionWithOptions.mock.calls[0][0].body.toMap();
expect(bodyMap.microSandboxConfig).toBeUndefined();
});
});

describe('updateFunction', () => {
let client: FC_Client;

beforeEach(() => {
(utils.getCustomEndpoint as jest.Mock).mockReturnValue({
protocol: 'https',
host: 'test-endpoint.com',
endpoint: 'https://test-endpoint.com',
});
client = new FC_Client(mockRegion, mockCredentials, mockOptions);
});

it('should forward microSandboxConfig to the update request body', async () => {
const updateFunctionWithOptions = jest.fn().mockResolvedValue({} as any);
Object.defineProperty(client, 'fc20230330Client', {
value: { updateFunctionWithOptions },
writable: true,
});

const config: IFunction = {
functionName: 'test-function',
runtime: 'micro-sandbox',
microSandboxConfig: {
osType: 'linux',
readyCommand: 'echo ready',
startCommand: 'echo start',
},
} as IFunction;

await client.updateFunction(config);

expect(updateFunctionWithOptions).toHaveBeenCalledTimes(1);
// first positional arg is functionName, second is the request
expect(updateFunctionWithOptions.mock.calls[0][0]).toBe('test-function');
const request = updateFunctionWithOptions.mock.calls[0][1];
const bodyMap = request.body.toMap();
expect(bodyMap.microSandboxConfig).toEqual({
osType: 'linux',
readyCommand: 'echo ready',
startCommand: 'echo start',
});
});
});
});
15 changes: 8 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dependencies": {
"@alicloud/devs20230714": "^2.5.0",
"@alicloud/fc2": "^2.6.6",
"@alicloud/fc20230330": "4.7.5",
"@alicloud/fc20230330": "4.7.7",
"@alicloud/pop-core": "^1.8.0",
"@serverless-cd/srm-aliyun-oss": "^0.0.1-beta.8",
"@serverless-cd/srm-aliyun-pop-core": "^0.0.8-beta.1",
Expand Down
7 changes: 7 additions & 0 deletions src/interface/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ export interface ILogConfig {
logBeginRule?: 'DefaultRegex' | 'None';
}

export interface IMicroSandboxConfig {
osType?: string;
readyCommand?: string;
startCommand?: string;
}

export interface INasConfig {
userId: number;
groupId: number;
Expand Down Expand Up @@ -141,6 +147,7 @@ export interface IFunction {
resourceGroupId?: string;

logConfig?: 'auto' | ILogConfig;
microSandboxConfig?: IMicroSandboxConfig;
nasConfig?: 'auto' | INasConfig;
ossMountConfig?: 'auto' | IOssMountConfig;
role?: 'auto' | string;
Expand Down
17 changes: 17 additions & 0 deletions src/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,20 @@
],
"type": "object"
},
"IMicroSandboxConfig": {
"properties": {
"osType": {
"type": "string"
},
"readyCommand": {
"type": "string"
},
"startCommand": {
"type": "string"
}
},
"type": "object"
},
"INasConfig": {
"properties": {
"groupId": {
Expand Down Expand Up @@ -1313,6 +1327,9 @@
"minimum": 128,
"maximum": 32768
},
"microSandboxConfig": {
"$ref": "#/definitions/IMicroSandboxConfig"
},
"nasConfig": {
"anyOf": [
{
Expand Down
Loading