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
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ module.exports = {
'^.+\\.ts$': 'ts-jest',
},
verbose: true,
testTimeout: 15000,
};
2 changes: 1 addition & 1 deletion package-lock.json

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

109 changes: 107 additions & 2 deletions packages/engine/__tests__/engine.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Engine, { IStepOptions, IContext } from '../lib';
// import Engine, { IStepOptions, IContext } from '../lib';
import Engine, { IStepOptions, IContext } from '../src';
import { lodash } from '@serverless-cd/core';
import * as path from 'path';
const { get, map } = lodash;
Expand Down Expand Up @@ -258,7 +259,7 @@ test('inputs测试 env', async () => {
]);
});

test.only('测试plugin安装逻辑', async () => {
test('测试plugin安装逻辑', async () => {
const steps = [
{ run: 'echo "hello"', id: 'xhello' },
{ plugin: '@serverless-cd/ding-talk', id: 'ding' },
Expand All @@ -277,4 +278,108 @@ test.only('测试plugin安装逻辑', async () => {
{ status: 'success', name: 'Run echo "hello"' },
{ status: 'failure', name: 'Run @serverless-cd/ding-talk' },
]);
});

// 新增性能统计测试
test('性能统计功能测试', async () => {
const steps = [
{ run: 'echo "step1"' },
{ run: 'sleep 1 && echo "step2"' }, // 添加短暂延迟
{ run: 'echo "step3"' },
] as IStepOptions[];

const engine = new Engine({
steps,
logConfig: { logPrefix }
});

const res: IContext | undefined = await engine.start();

// 验证任务执行成功
expect(res?.status).toBe('success');

// 验证性能数据存在
expect(res?.performance).toBeDefined();

// 验证初始化耗时存在
expect(res?.performance?.initTime).toBeDefined();
expect(res?.performance?.initTime).toBeGreaterThanOrEqual(0);

// 验证总耗时存在
expect(res?.performance?.totalTime).toBeDefined();
expect(res?.performance?.totalTime).toBeGreaterThanOrEqual(0);

// 验证步骤耗时存在
expect(res?.performance?.stepTimes).toBeDefined();
expect(Object.keys(res?.performance?.stepTimes || {})).toHaveLength(steps.length);

// 验证任务状态和步骤数
expect(res?.performance?.taskStatus).toBe('success');

// 验证除初始化外每个步骤都有耗时记录
for (const step of res?.steps || []) {
if (step.stepCount&&step.stepCount!=='0') {
expect(res?.performance?.stepTimes?.[step.stepCount]).toBeDefined();
expect(res?.performance?.stepTimes?.[step.stepCount]).toBeGreaterThanOrEqual(0);
}
}
});

// 测试带超时的性能统计
test('带超时的性能统计功能测试', async () => {
const steps = [
{ run: 'echo "step1"' },
{ run: 'sleep 0.1 && echo "step2"' },
] as IStepOptions[];

const engine = new Engine({
steps,
logConfig: { logPrefix },
stepTimeout: 3
});

const res: IContext | undefined = await engine.start();

// 验证任务执行成功
expect(res?.status).toBe('success');
// 验证性能数据存在
expect(res?.performance).toBeDefined();
// 验证超时配置被正确传递
// 这部分验证需要查看Engine内部实现
});

// 测试失败情况下的性能统计
test('失败情况下的性能统计功能测试', async () => {
const steps = [
{ run: 'echo "step1"' },
{ run: 'exit 1' }, // 故意失败的步骤
{ run: 'echo "step3"' },
] as IStepOptions[];

const engine = new Engine({
steps,
logConfig: { logPrefix }
});

const res: IContext | undefined = await engine.start();

// 验证任务执行失败
expect(res?.status).toBe('failure');

// 验证性能数据仍然存在
expect(res?.performance).toBeDefined();

// 验证初始化耗时存在
expect(res?.performance?.initTime).toBeDefined();
expect(res?.performance?.initTime).toBeGreaterThanOrEqual(0);

// 验证总耗时存在
expect(res?.performance?.totalTime).toBeDefined();
expect(res?.performance?.totalTime).toBeGreaterThanOrEqual(0);

// 验证步骤耗时存在(即使任务失败也应该记录)
expect(res?.performance?.stepTimes).toBeDefined();

// 验证任务状态
expect(res?.performance?.taskStatus).toBe('failure');
});
9 changes: 9 additions & 0 deletions packages/engine/__tests__/failure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ test('某一步执行失败,错误信息记录在context.error', async () => {
{ run: 'echo "world"', id: 'xworld' },
] as IStepOptions[];

const engine = new Engine({ steps, logConfig: { logPrefix } });
const res: IContext | undefined = await engine.start();
expect(res.error).toBeInstanceOf(Object);
});

test('路径错误,正常抛出', async () => {
const steps = [
{ run: 'npm install', id: 'xhello', "working-directory": './xsadads' },
] as IStepOptions[];
const engine = new Engine({ steps, logConfig: { logPrefix } });
const res: IContext | undefined = await engine.start();
expect(res.error).toBeInstanceOf(Error);
Expand Down
10 changes: 10 additions & 0 deletions packages/engine/__tests__/fixtures/timeout-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
run: async (inputs, context, logger) => {
// 模拟一个长时间运行的插件
return new Promise((resolve) => {
setTimeout(() => {
resolve({ success: true });
}, 5000); // 5秒延迟
});
}
};
4 changes: 2 additions & 2 deletions packages/engine/__tests__/mock/run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ steps:
echo "Serverless Devs is not installed."
exit 1
fi
s config add --AccessKeyID "${access_key_id}" --NewAccessKeySecret "${access_key_secret}" \
--AccountID "${uid}" --NewSecurityToken "${security_token}" --access "${alias}" -f
s config add --AccessKeyID "${access_key_id}" --AccessKeySecret "${access_key_secret}" \
--AccountID "${uid}" --SecurityToken "${security_token}" --access "${alias}" -f
if [[ $? -ne 0 ]]; then
echo "Failed to setup Serverless Devs."
exit 1
Expand Down
Loading