thunderbench 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +818 -0
  3. package/bin/darwin-arm64/wrk +0 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/core/config-validation.d.ts +7 -0
  7. package/dist/core/config-validation.d.ts.map +1 -0
  8. package/dist/core/json-report-generator.d.ts +174 -0
  9. package/dist/core/json-report-generator.d.ts.map +1 -0
  10. package/dist/core/markdown-report-generator.d.ts +16 -0
  11. package/dist/core/markdown-report-generator.d.ts.map +1 -0
  12. package/dist/core/report-storage.d.ts +10 -0
  13. package/dist/core/report-storage.d.ts.map +1 -0
  14. package/dist/core/stats-calculation.d.ts +16 -0
  15. package/dist/core/stats-calculation.d.ts.map +1 -0
  16. package/dist/core/weight-distribution.d.ts +9 -0
  17. package/dist/core/weight-distribution.d.ts.map +1 -0
  18. package/dist/core/wrk-test-engine.d.ts +181 -0
  19. package/dist/core/wrk-test-engine.d.ts.map +1 -0
  20. package/dist/index.d.ts +39 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +10494 -0
  23. package/dist/types/index.d.ts +88 -0
  24. package/dist/types/index.d.ts.map +1 -0
  25. package/dist/utils/wrk-binary.d.ts +41 -0
  26. package/dist/utils/wrk-binary.d.ts.map +1 -0
  27. package/docs/cli-usage.md +245 -0
  28. package/docs/requirements.md +222 -0
  29. package/examples/complex-config.ts +244 -0
  30. package/examples/complex-wrk-demo.ts +121 -0
  31. package/examples/programmatic-usage-cjs.js +156 -0
  32. package/examples/programmatic-usage.js +205 -0
  33. package/examples/simple-wrk-config.js +33 -0
  34. package/package.json +68 -0
  35. package/scripts/setup-wrk.js +98 -0
@@ -0,0 +1,205 @@
1
+ // ThunderBench 编程使用示例
2
+ import { ThunderBench, runBenchmark, validateConfig } from 'thunderbench';
3
+
4
+ // 方式1:使用 ThunderBench 类
5
+ async function example1() {
6
+ const config = {
7
+ name: "编程API测试",
8
+ description: "通过编程方式运行性能测试",
9
+ groups: [
10
+ {
11
+ name: "基础测试组",
12
+ http: {
13
+ baseUrl: "http://localhost:3001",
14
+ headers: { "User-Agent": "thunderbench-programmatic/1.0" }
15
+ },
16
+ threads: 2,
17
+ connections: 50,
18
+ duration: 10,
19
+ timeout: 5,
20
+ latency: true,
21
+ executionMode: "parallel",
22
+ tests: [
23
+ {
24
+ name: "GET 请求测试",
25
+ request: { method: "GET", url: "/" },
26
+ weight: 100
27
+ }
28
+ ]
29
+ }
30
+ ]
31
+ };
32
+
33
+ // 创建 ThunderBench 实例
34
+ const thunderbench = new ThunderBench(config, {
35
+ outputDir: "./programmatic-reports",
36
+ verbose: true
37
+ });
38
+
39
+ try {
40
+ // 监听进度
41
+ thunderbench.getProgressStream().subscribe(progress => {
42
+ console.log(`进度: ${progress.groupName} - ${progress.percentage}%`);
43
+ });
44
+
45
+ // 监听统计
46
+ thunderbench.getStatsStream().subscribe(stats => {
47
+ console.log(`实时统计: ${stats.totalRequests} 请求, ${stats.requestsPerSecond.toFixed(1)} req/s`);
48
+ });
49
+
50
+ // 运行测试
51
+ const result = await thunderbench.runBenchmark();
52
+ console.log("测试完成:", result);
53
+
54
+ return result;
55
+ } finally {
56
+ // 清理资源
57
+ thunderbench.destroy();
58
+ }
59
+ }
60
+
61
+ // 方式2:使用便捷函数
62
+ async function example2() {
63
+ const config = {
64
+ name: "便捷函数测试",
65
+ groups: [
66
+ {
67
+ name: "简单测试",
68
+ http: { baseUrl: "http://localhost:3001" },
69
+ threads: 1,
70
+ connections: 10,
71
+ duration: 5,
72
+ executionMode: "parallel",
73
+ tests: [
74
+ {
75
+ name: "快速测试",
76
+ request: { method: "GET", url: "/" },
77
+ weight: 100
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+ };
83
+
84
+ // 直接运行测试
85
+ const result = await runBenchmark(config, { verbose: true });
86
+ console.log("便捷函数测试完成:", result);
87
+
88
+ return result;
89
+ }
90
+
91
+ // 方式3:配置验证
92
+ function example3() {
93
+ const config = {
94
+ name: "配置验证测试",
95
+ groups: [
96
+ {
97
+ name: "测试组",
98
+ http: { baseUrl: "http://localhost:3001" },
99
+ threads: 2,
100
+ connections: 20,
101
+ duration: 10,
102
+ executionMode: "parallel",
103
+ tests: [
104
+ {
105
+ name: "验证测试",
106
+ request: { method: "GET", url: "/" },
107
+ weight: 100
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ };
113
+
114
+ try {
115
+ // 验证配置
116
+ validateConfig(config);
117
+ console.log("✅ 配置验证通过");
118
+ return true;
119
+ } catch (error) {
120
+ console.error("❌ 配置验证失败:", error.message);
121
+ return false;
122
+ }
123
+ }
124
+
125
+ // 方式4:自定义报告生成
126
+ async function example4() {
127
+ const config = {
128
+ name: "自定义报告测试",
129
+ groups: [
130
+ {
131
+ name: "报告测试组",
132
+ http: { baseUrl: "http://localhost:3001" },
133
+ threads: 1,
134
+ connections: 5,
135
+ duration: 5,
136
+ executionMode: "parallel",
137
+ tests: [
138
+ {
139
+ name: "报告测试",
140
+ request: { method: "GET", url: "/" },
141
+ weight: 100
142
+ }
143
+ ]
144
+ }
145
+ ]
146
+ };
147
+
148
+ const thunderbench = new ThunderBench(config, {
149
+ outputDir: "./custom-reports",
150
+ verbose: false
151
+ });
152
+
153
+ try {
154
+ const result = await thunderbench.runBenchmark();
155
+
156
+ // 自定义报告处理
157
+ console.log("=== 自定义报告 ===");
158
+ console.log(`总请求数: ${result.overallStats.totalRequests}`);
159
+ console.log(`成功率: ${((result.overallStats.successfulRequests / result.overallStats.totalRequests) * 100).toFixed(1)}%`);
160
+ console.log(`平均响应时间: ${result.overallStats.averageResponseTime}ms`);
161
+ console.log(`吞吐量: ${result.overallStats.requestsPerSecond.toFixed(1)} req/s`);
162
+
163
+ return result;
164
+ } finally {
165
+ thunderbench.destroy();
166
+ }
167
+ }
168
+
169
+ // 主函数
170
+ async function main() {
171
+ console.log("🚀 ThunderBench 编程使用示例\n");
172
+
173
+ try {
174
+ // 示例1:使用类
175
+ console.log("=== 示例1:使用 ThunderBench 类 ===");
176
+ await example1();
177
+ console.log();
178
+
179
+ // 示例2:使用便捷函数
180
+ console.log("=== 示例2:使用便捷函数 ===");
181
+ await example2();
182
+ console.log();
183
+
184
+ // 示例3:配置验证
185
+ console.log("=== 示例3:配置验证 ===");
186
+ example3();
187
+ console.log();
188
+
189
+ // 示例4:自定义报告
190
+ console.log("=== 示例4:自定义报告 ===");
191
+ await example4();
192
+ console.log();
193
+
194
+ console.log("✅ 所有示例执行完成!");
195
+ } catch (error) {
196
+ console.error("❌ 示例执行失败:", error);
197
+ }
198
+ }
199
+
200
+ // 如果直接运行此文件
201
+ if (import.meta.url === `file://${process.argv[1]}`) {
202
+ main();
203
+ }
204
+
205
+ export { example1, example2, example3, example4 };
@@ -0,0 +1,33 @@
1
+ const config = {
2
+ name: "简单 wrk 配置演示",
3
+ description: "展示基本的 wrk 参数配置",
4
+ groups: [
5
+ {
6
+ name: "基础测试组",
7
+ http: {
8
+ baseUrl: "http://localhost:3000",
9
+ headers: {
10
+ "User-Agent": "wrk-benchmark/1.0",
11
+ },
12
+ },
13
+ threads: 4, // 4个线程
14
+ connections: 100, // 100个连接
15
+ duration: 10, // 10秒
16
+ timeout: 5, // 5秒超时
17
+ latency: true, // 启用详细延迟统计
18
+ executionMode: "parallel",
19
+ tests: [
20
+ {
21
+ name: "GET 请求测试",
22
+ request: {
23
+ method: "GET",
24
+ url: "/techempower/json",
25
+ },
26
+ weight: 100,
27
+ },
28
+ ],
29
+ },
30
+ ],
31
+ };
32
+
33
+ export default config;
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "thunderbench",
3
+ "version": "1.0.5",
4
+ "description": "ThunderBench - 高性能API性能测试工具核心引擎",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist/",
16
+ "bin/",
17
+ "examples/",
18
+ "docs/",
19
+ "scripts/",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "scripts": {
24
+ "build": "bun build src/index.ts --outdir ./dist --target node && tsc --project tsconfig.build.json",
25
+ "dev": "bun --watch src/index.ts",
26
+ "test": "vitest",
27
+ "prepublishOnly": "npm run build",
28
+ "release": "bumpp"
29
+ },
30
+ "keywords": [
31
+ "performance",
32
+ "benchmark",
33
+ "api-testing",
34
+ "wrk",
35
+ "load-testing",
36
+ "stress-testing",
37
+ "nodejs",
38
+ "typescript"
39
+ ],
40
+ "author": "ThunderBench Team",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/thunderbench/thunderbench.git"
45
+ },
46
+ "homepage": "https://github.com/thunderbench/thunderbench#readme",
47
+ "bugs": {
48
+ "url": "https://github.com/thunderbench/thunderbench/issues"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ },
53
+ "dependencies": {
54
+ "chalk": "^5.3.0",
55
+ "fs-extra": "^11.2.0",
56
+ "glob": "^10.3.10",
57
+ "ora": "^7.0.1",
58
+ "rxjs": "^7.8.1"
59
+ },
60
+ "devDependencies": {
61
+ "@types/fs-extra": "^11.0.4",
62
+ "@types/node": "^20.10.0",
63
+ "bumpp": "^10.2.3",
64
+ "bun-types": "latest",
65
+ "typescript": "^5.3.0",
66
+ "vitest": "^1.0.0"
67
+ }
68
+ }
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ const BIN_DIR = path.join(__dirname, '..', 'bin');
8
+
9
+ // 获取当前平台标识符
10
+ function getPlatformIdentifier() {
11
+ const platform = process.platform;
12
+ const arch = process.arch;
13
+
14
+ const platformMap = {
15
+ 'darwin': 'darwin',
16
+ 'linux': 'linux',
17
+ 'win32': 'win32'
18
+ };
19
+
20
+ const archMap = {
21
+ 'x64': 'x64',
22
+ 'x86': 'x86',
23
+ 'arm64': 'arm64',
24
+ 'arm': 'arm'
25
+ };
26
+
27
+ const normalizedPlatform = platformMap[platform] || platform;
28
+ const normalizedArch = archMap[arch] || arch;
29
+
30
+ return `${normalizedPlatform}-${normalizedArch}`;
31
+ }
32
+
33
+ // 主函数
34
+ function main() {
35
+ console.log('🚀 检查 WRK 环境...\n');
36
+
37
+ const platformId = getPlatformIdentifier();
38
+ console.log(`🖥️ 当前平台: ${platformId}`);
39
+
40
+ // 检查内置二进制文件
41
+ const builtinPath = path.join(BIN_DIR, platformId, 'wrk');
42
+ console.log(`📁 内置路径: ${builtinPath}`);
43
+
44
+ if (fs.existsSync(builtinPath)) {
45
+ console.log(`✅ 内置二进制文件存在`);
46
+
47
+ // 检查权限
48
+ try {
49
+ fs.accessSync(builtinPath, fs.constants.X_OK);
50
+ console.log(`✅ 二进制文件可执行`);
51
+
52
+ // 测试运行
53
+ try {
54
+ // 使用 -v 参数测试,这个参数会输出版本信息
55
+ execSync(`"${builtinPath}" -v`, { stdio: 'pipe' });
56
+ console.log(`✅ 二进制文件运行正常`);
57
+ } catch (error) {
58
+ // wrk -v 通常返回非零退出码,这是正常的
59
+ console.log(`✅ 二进制文件运行正常 (wrk -v 返回非零退出码是正常的)`);
60
+ }
61
+
62
+ } catch (error) {
63
+ console.log(`❌ 二进制文件权限不足`);
64
+ }
65
+
66
+ } else {
67
+ console.log(`❌ 内置二进制文件不存在`);
68
+ }
69
+
70
+ // 检查系统安装
71
+ try {
72
+ const systemWrk = execSync('which wrk', { encoding: 'utf8' }).trim();
73
+ console.log(`\n🔍 系统安装: ${systemWrk}`);
74
+ } catch (error) {
75
+ console.log(`\n🔍 系统安装: 未找到`);
76
+ }
77
+
78
+ console.log(`\n📁 目录结构:`);
79
+ if (fs.existsSync(BIN_DIR)) {
80
+ const items = fs.readdirSync(BIN_DIR);
81
+ items.forEach(item => {
82
+ const itemPath = path.join(BIN_DIR, item);
83
+ const stats = fs.statSync(itemPath);
84
+ if (stats.isDirectory()) {
85
+ const wrkPath = path.join(itemPath, 'wrk');
86
+ const exists = fs.existsSync(wrkPath) ? '✅' : '❌';
87
+ console.log(` ${item}/: ${exists} wrk`);
88
+ }
89
+ });
90
+ }
91
+ }
92
+
93
+ // 运行脚本
94
+ if (require.main === module) {
95
+ main();
96
+ }
97
+
98
+ module.exports = { getPlatformIdentifier };