From ed7dac4982519251cf4ec3b1b141ceb09205e493 Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Sun, 11 Dec 2022 19:23:43 +0800 Subject: [PATCH 1/6] fix: normal exit --- src/configure-inl.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/configure-inl.h b/src/configure-inl.h index a7ad2a0..9a208b4 100644 --- a/src/configure-inl.h +++ b/src/configure-inl.h @@ -7,7 +7,12 @@ namespace xprofiler { template T GetConfig(std::string key) { - return ProcessData::Get()->config_store()->GetConfig(key); + T result = T(); + try { + result = ProcessData::Get()->config_store()->GetConfig(key); + } catch (nlohmann::json::exception& e) { + } + return result; } } // namespace xprofiler From b2973649e1c4c08287a291ab0ec000d591403865 Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Mon, 9 Jan 2023 15:42:47 +0800 Subject: [PATCH 2/6] feat: support auto increase heap limit --- README.md | 5 ++++- configuration.js | 19 ++++++++++++++++++- index.d.ts | 1 + test/fixtures/cases/command.js | 5 +++++ test/fixtures/cases/config.js | 6 ++++++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea17316..8f0dcc8 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ require('xprofiler')(); * **enable_fatal_error_report**: 是否需要在 V8 出现 FataLError 时导出 Report 文件,默认 `true` * **enable_fatal_error_coredump**: 是否需要在 V8 出现 FataLError 时 Coredump,默认 `false` * **enable_http_profiling**: 是否需要 CPU 采样时进行 HTTP Profiling。默认 `false` +* **enable_auto_incr_heap_limit**: 是否需要在 Node.js 进程达到堆上限时自动增加堆上限防止 OOM,默认 `false` 您可以通过环境变量或者在 JavaScript 代码中引入插件时传入配置的方式来使用这些配置,具体如下所示: @@ -97,12 +98,13 @@ require('xprofiler')(); * **XPROFILER_LOG_FORMAT_ALINODE**: 其值为 YES/NO,覆盖 `log_format_alinode` * **XPROFILER_PATCH_HTTP**: 其值为 YES/NO,覆盖 `patch_http` * **XPROFILER_PATCH_HTTP_TIMEOUT**: 其值为 String,覆盖 `patch_http_timeout` -* **XPROFILER_CHECK_THROW**: 其值为 YES/NO `check_throw` +* **XPROFILER_CHECK_THROW**: 其值为 YES/NO 覆盖 `check_throw` * **XPROFILER_ENABLE_LOG_UV_HANDLES**: 其值为 YES/NO,覆盖 `enable_log_uv_handles` * **XPROFILER_ENABLE_FATAL_ERROR_HOOK**: 其值为 YES/NO,覆盖 `enable_fatal_error_hook` * **XPROFILER_ENABLE_FATAL_ERROR_REPORT**: 其值为 YES/NO,覆盖 `enable_fatal_error_report` * **XPROFILER_ENABLE_FATAL_ERROR_COREDUMP**: 其值为 YES/NO,覆盖 `enable_fatal_error_coredump` * **XPROFILER_ENABLE_HTTP_PROFILING**: 其值为 YES/NO,覆盖 `enable_http_profiling` +* **XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT**: 其值为 YES/NO 覆盖 `enable_auto_incr_heap_limit` #### 2. 引入插件时传入配置 @@ -138,6 +140,7 @@ const defaultConfig = { enable_fatal_error_report: true, enable_fatal_error_coredump: false, enable_http_profiling: false, + enable_auto_incr_heap_limit: false, }; const xprofilerConfig = Object.assign({}, defaultConfig, envConfig, userConfig); diff --git a/configuration.js b/configuration.js index 057e04a..c2c7b2a 100644 --- a/configuration.js +++ b/configuration.js @@ -16,53 +16,70 @@ module.exports = () => { ...xprofctl(false), ...config('log_dir', 'XPROFILER_LOG_DIR', 'string', os.tmpdir(), ['path']), }, + { ...xprofctl(false), ...config('log_interval', 'XPROFILER_LOG_INTERVAL', 'number', 60), // seconds }, + { ...xprofctl(true, '日志级别: info, error, debug', [0, 1, 2],), ...config('log_level', 'XPROFILER_LOG_LEVEL', 'number', 1), // 0: info, 1: error, 2: debug }, + { ...xprofctl(true, '日志输出位置: 文件, 控制台', [0, 1]), ...config('log_type', 'XPROFILER_LOG_TYPE', 'number', 0), // 0: file, 1: console }, + { ...xprofctl(false), ...config('log_format_alinode', 'XPROFILER_LOG_FORMAT_ALINODE', 'boolean', false), }, + { ...xprofctl(false), ...config('patch_http', 'XPROFILER_PATCH_HTTP', 'boolean', true), }, + { ...xprofctl(false), ...config('patch_http_timeout', 'XPROFILER_PATCH_HTTP_TIMEOUT', 'number', 30), // seconds }, + { ...xprofctl(false), ...config('check_throw', 'XPROFILER_CHECK_THROW', 'boolean', true), }, + { ...xprofctl(true, enable => `${enable ? '开启' : '关闭'} libuv 句柄详情采集`), ...config('enable_log_uv_handles', 'XPROFILER_ENABLE_LOG_UV_HANDLES', 'boolean', true), }, + { ...xprofctl(false), ...config('enable_fatal_error_hook', 'XPROFILER_ENABLE_FATAL_ERROR_HOOK', 'boolean', true), }, + { ...xprofctl(true, enable => `${enable ? '开启' : '关闭'} FatalError 时自动 Report`), ...config('enable_fatal_error_report', 'XPROFILER_ENABLE_FATAL_ERROR_REPORT', 'boolean', true), }, + { ...xprofctl(true, enable => `${enable ? '开启' : '关闭'} FatalError 时自动 Coredump`), ...config('enable_fatal_error_coredump', 'XPROFILER_ENABLE_FATAL_ERROR_COREDUMP', 'boolean', false), }, + { ...xprofctl(true, enable => `在 CPU 采样期间${enable ? '开启' : '关闭'} HTTP Profiling`), ...config('enable_http_profiling', 'XPROFILER_ENABLE_HTTP_PROFILING', 'boolean', false), - } + }, + + { + ...xprofctl(true, enable => `${enable ? '启用' : '禁用'} Node.js 自动增加堆上限`), + ...config('enable_auto_incr_heap_limit', 'XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT', 'boolean', false), + }, ]; }; \ No newline at end of file diff --git a/index.d.ts b/index.d.ts index 11dc94f..b99caab 100644 --- a/index.d.ts +++ b/index.d.ts @@ -14,6 +14,7 @@ export interface XprofilerConfig { enable_fatal_error_report?: boolean; enable_fatal_error_coredump?: boolean; enable_http_profiling?: boolean; + enable_auto_incr_heap_limit?: boolean; } /** diff --git a/test/fixtures/cases/command.js b/test/fixtures/cases/command.js index ada7bc4..a353c3f 100644 --- a/test/fixtures/cases/command.js +++ b/test/fixtures/cases/command.js @@ -234,10 +234,12 @@ exports = module.exports = function (logdir) { { key: 'data.enable_fatal_error_report', rule: { label: 'true', test: value => value === true } }, { key: 'data.enable_fatal_error_coredump', rule: { label: 'false', test: value => value === false } }, { key: 'data.enable_http_profiling', rule: { label: 'false', test: value => value === false } }, + { key: 'data.enable_auto_incr_heap_limit', rule: { label: 'false', test: value => value === false } }, ], xprofctlRules(data) { return [new RegExp(`^X-Profiler 当前配置\\(pid ${data.pid}\\):\n` + ' - check_throw: false\n' + + ' - enable_auto_incr_heap_limit: false\n' + ' - enable_fatal_error_coredump: false\n' + ' - enable_fatal_error_hook: true\n' + ' - enable_fatal_error_report: true\n' @@ -262,6 +264,7 @@ exports = module.exports = function (logdir) { enable_fatal_error_report: false, enable_fatal_error_coredump: true, enable_http_profiling: true, + enable_auto_incr_heap_limit: true, }, xctlRules: [ { key: 'data.log_level', rule: /^2$/ }, @@ -270,9 +273,11 @@ exports = module.exports = function (logdir) { { key: 'data.enable_fatal_error_report', rule: { label: 'false', test: value => value === false } }, { key: 'data.enable_fatal_error_coredump', rule: { label: 'true', test: value => value === true } }, { key: 'data.enable_http_profiling', rule: { label: 'true', test: value => value === true } }, + { key: 'data.enable_auto_incr_heap_limit', rule: { label: 'true', test: value => value === true } }, ], xprofctlRules(data) { return [new RegExp(`^X-Profiler 配置\\(pid ${data.pid}\\)成功:\n` + + ' - enable_auto_incr_heap_limit: true\n' + ' - enable_fatal_error_coredump: true\n' + ' - enable_fatal_error_report: false\n' + ' - enable_http_profiling: true\n' diff --git a/test/fixtures/cases/config.js b/test/fixtures/cases/config.js index f6a7b71..b0f7816 100644 --- a/test/fixtures/cases/config.js +++ b/test/fixtures/cases/config.js @@ -136,6 +136,12 @@ const configure = { envValue: 'YES', userValue: true }, + enable_auto_incr_heap_limit: { + defaultValue: false, + envKey: 'XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT', + envValue: 'YES', + userValue: true + }, }; module.exports = getTestKeys(configure); \ No newline at end of file From 3cc5df3882fc3c214c1993bec496ed2af444262b Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Tue, 10 Jan 2023 09:49:18 +0800 Subject: [PATCH 3/6] feat: support auto incr heap limit --- binding.gyp | 1 + src/hooks/heap_limit.cc | 36 ++++++++++++++++++++++++++++++++++++ src/hooks/heap_limit.h | 10 ++++++++++ src/jsapi/export_hooks.cc | 6 ++++++ 4 files changed, 53 insertions(+) create mode 100644 src/hooks/heap_limit.cc create mode 100644 src/hooks/heap_limit.h diff --git a/binding.gyp b/binding.gyp index afdb8da..d10875f 100644 --- a/binding.gyp +++ b/binding.gyp @@ -44,6 +44,7 @@ "src/commands/report/system_statistics.cc", "src/commands/coredumper/coredumper.cc", "src/hooks/fatal_error.cc", + "src/hooks/heap_limit.cc", "src/jsapi/export_environment.cc", "src/jsapi/export_configure.cc", "src/jsapi/export_logger.cc", diff --git a/src/hooks/heap_limit.cc b/src/hooks/heap_limit.cc new file mode 100644 index 0000000..bb7e6cb --- /dev/null +++ b/src/hooks/heap_limit.cc @@ -0,0 +1,36 @@ +#include "heap_limit.h" + +#include "environment_data.h" +#include "logger.h" + +namespace xprofiler { +static const char module_type[] = "heap_limit"; + +size_t NearHeapLimitCallback(void* data, size_t current_heap_limit, + size_t initial_heap_limit) { + // const size_t heapdump_factor = 2; + // size_t max_limit = (std::numeric_limits::max)() / 4; + // size_t increased_heap = + // current_heap_limit + + // std::min(max_limit, initial_heap_limit * heapdump_factor); + + size_t increased_heap = current_heap_limit + 512 * 1024 * 1024; + + ThreadId thread_id = *static_cast(data); + InfoT(module_type, thread_id, + "current_heap_limit is %d, initial_heap_limit is %d, increased_heap is " + "%d.", + current_heap_limit, initial_heap_limit, increased_heap); + + return increased_heap; +} + +void AutoIncreaseHeapLimit(v8::Isolate* isolate) { + EnvironmentData* env_data = EnvironmentData::GetCurrent(isolate); + ThreadId thread_id = env_data->thread_id(); + + InfoT(module_type, thread_id, "auto increase heap limit hook."); + isolate->AddNearHeapLimitCallback(NearHeapLimitCallback, + static_cast(&thread_id)); +} +} // namespace xprofiler \ No newline at end of file diff --git a/src/hooks/heap_limit.h b/src/hooks/heap_limit.h new file mode 100644 index 0000000..b939604 --- /dev/null +++ b/src/hooks/heap_limit.h @@ -0,0 +1,10 @@ +#ifndef XPROFILER_SRC_HOOKS_HEAP_LIMIT_H +#define XPROFILER_SRC_HOOKS_HEAP_LIMIT_H + +#include "nan.h" + +namespace xprofiler { +void AutoIncreaseHeapLimit(v8::Isolate* isolate); +} // namespace xprofiler + +#endif /* XPROFILER_SRC_HOOKS_HEAP_LIMIT_H */ diff --git a/src/jsapi/export_hooks.cc b/src/jsapi/export_hooks.cc index 831c99d..cb467e8 100644 --- a/src/jsapi/export_hooks.cc +++ b/src/jsapi/export_hooks.cc @@ -2,6 +2,7 @@ #include "configure-inl.h" #include "hooks/fatal_error.h" +#include "hooks/heap_limit.h" namespace xprofiler { using Nan::FunctionCallbackInfo; @@ -12,5 +13,10 @@ void SetHooks(const FunctionCallbackInfo& info) { if (GetConfig("enable_fatal_error_hook")) { SetFatalErrorHandler(info.GetIsolate()); } + + // set auto increas heap limit hook + if (GetConfig("enable_auto_incr_heap_limit")) { + AutoIncreaseHeapLimit(info.GetIsolate()); + } } } // namespace xprofiler From 3499b990625f868c015c6a8e70443843ae6fd832 Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Tue, 10 Jan 2023 10:38:21 +0800 Subject: [PATCH 4/6] feat: support auto increase heap limit size --- README.md | 3 +++ configuration.js | 5 +++++ index.d.ts | 1 + src/hooks/heap_limit.cc | 11 ++++++++--- test/fixtures/cases/command.js | 2 ++ test/fixtures/cases/config.js | 6 ++++++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8f0dcc8..b471e6f 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ require('xprofiler')(); * **patch_http**: 是否对原生 http 模块进行 patch,输出 http 请求相关信息,默认 `true` * **patch_http_timeout**: 默认 http 请求超时时间,单位秒,作为 http 请求统计,默认 `30` * **check_throw**: `xprofiler` 启动时检测错误时是否需要 throw,默认 `true` +* **auto_incr_heap_limit_size**: `enable_auto_incr_heap_limit` 开启后,每次自动增加的堆上限大小,默认为 `512` (MB) * **enable_log_uv_handles**: 是否要采集 libuv 句柄的详细分类信息,比如 tcp 句柄数量,timers 数量,文件句柄数量等,默认为 `true` * **enable_fatal_error_hook**: 是否需要在 V8 出现 FatalError 时配置钩子,默认 `true` * **enable_fatal_error_report**: 是否需要在 V8 出现 FataLError 时导出 Report 文件,默认 `true` @@ -99,6 +100,7 @@ require('xprofiler')(); * **XPROFILER_PATCH_HTTP**: 其值为 YES/NO,覆盖 `patch_http` * **XPROFILER_PATCH_HTTP_TIMEOUT**: 其值为 String,覆盖 `patch_http_timeout` * **XPROFILER_CHECK_THROW**: 其值为 YES/NO 覆盖 `check_throw` +* **XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE**: 其值为 String 覆盖 `auto_incr_heap_limit_size` * **XPROFILER_ENABLE_LOG_UV_HANDLES**: 其值为 YES/NO,覆盖 `enable_log_uv_handles` * **XPROFILER_ENABLE_FATAL_ERROR_HOOK**: 其值为 YES/NO,覆盖 `enable_fatal_error_hook` * **XPROFILER_ENABLE_FATAL_ERROR_REPORT**: 其值为 YES/NO,覆盖 `enable_fatal_error_report` @@ -135,6 +137,7 @@ const defaultConfig = { patch_http: true, patch_http_timeout: 30, // seconds, check_throw: true, + auto_incr_heap_limit_size: 128 // MB, enable_log_uv_handles: true, enable_fatal_error_hook: true, enable_fatal_error_report: true, diff --git a/configuration.js b/configuration.js index c2c7b2a..f80e609 100644 --- a/configuration.js +++ b/configuration.js @@ -52,6 +52,11 @@ module.exports = () => { ...config('check_throw', 'XPROFILER_CHECK_THROW', 'boolean', true), }, + { + ...xprofctl(false), + ...config('auto_incr_heap_limit_size', 'XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE', 'number', 256), // MB + }, + { ...xprofctl(true, enable => `${enable ? '开启' : '关闭'} libuv 句柄详情采集`), ...config('enable_log_uv_handles', 'XPROFILER_ENABLE_LOG_UV_HANDLES', 'boolean', true), diff --git a/index.d.ts b/index.d.ts index b99caab..3c04932 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,6 +10,7 @@ export interface XprofilerConfig { patch_http?: boolean; patch_http_timeout?: number; check_throw?: boolean; + auto_incr_heap_limit_size?: number; enable_fatal_error_hook?: boolean; enable_fatal_error_report?: boolean; enable_fatal_error_coredump?: boolean; diff --git a/src/hooks/heap_limit.cc b/src/hooks/heap_limit.cc index bb7e6cb..d52dd7c 100644 --- a/src/hooks/heap_limit.cc +++ b/src/hooks/heap_limit.cc @@ -1,5 +1,6 @@ #include "heap_limit.h" +#include "configure-inl.h" #include "environment_data.h" #include "logger.h" @@ -14,13 +15,17 @@ size_t NearHeapLimitCallback(void* data, size_t current_heap_limit, // current_heap_limit + // std::min(max_limit, initial_heap_limit * heapdump_factor); - size_t increased_heap = current_heap_limit + 512 * 1024 * 1024; + int auto_incr_heap_limit_size = GetConfig("auto_incr_heap_limit_size"); + size_t increased_heap = + current_heap_limit + auto_incr_heap_limit_size * 1024 * 1024; ThreadId thread_id = *static_cast(data); InfoT(module_type, thread_id, - "current_heap_limit is %d, initial_heap_limit is %d, increased_heap is " + "current_heap_limit is %d, initial_heap_limit is %d, " + "auto_incr_heap_limit_size is %d, increased_heap is " "%d.", - current_heap_limit, initial_heap_limit, increased_heap); + current_heap_limit, initial_heap_limit, auto_incr_heap_limit_size, + increased_heap); return increased_heap; } diff --git a/test/fixtures/cases/command.js b/test/fixtures/cases/command.js index a353c3f..e06564c 100644 --- a/test/fixtures/cases/command.js +++ b/test/fixtures/cases/command.js @@ -230,6 +230,7 @@ exports = module.exports = function (logdir) { { key: 'data.patch_http', rule: { label: 'true', test: value => value === true } }, { key: 'data.patch_http_timeout', rule: /^30$/ }, { key: 'data.check_throw', rule: { label: 'false', test: value => value === false } }, + { key: 'data.auto_incr_heap_limit_size', rule: /^256$/ }, { key: 'data.enable_fatal_error_hook', rule: { label: 'true', test: value => value === true } }, { key: 'data.enable_fatal_error_report', rule: { label: 'true', test: value => value === true } }, { key: 'data.enable_fatal_error_coredump', rule: { label: 'false', test: value => value === false } }, @@ -238,6 +239,7 @@ exports = module.exports = function (logdir) { ], xprofctlRules(data) { return [new RegExp(`^X-Profiler 当前配置\\(pid ${data.pid}\\):\n` + + ' - auto_incr_heap_limit_size: 256\n' + ' - check_throw: false\n' + ' - enable_auto_incr_heap_limit: false\n' + ' - enable_fatal_error_coredump: false\n' diff --git a/test/fixtures/cases/config.js b/test/fixtures/cases/config.js index b0f7816..1f2591f 100644 --- a/test/fixtures/cases/config.js +++ b/test/fixtures/cases/config.js @@ -112,6 +112,12 @@ const configure = { envValue: 'NO', userValue: false }, + auto_incr_heap_limit_size: { + defaultValue: 256, + envKey: 'XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE', + envValue: 1024, + userValue: 2048, + }, enable_fatal_error_hook: { defaultValue: true, envKey: 'XPROFILER_ENABLE_FATAL_ERROR_HOOK', From dbba157dc8c668b0369a5ccf0407a52611d62e1d Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Tue, 10 Jan 2023 11:20:22 +0800 Subject: [PATCH 5/6] test: add test --- .eslintrc | 2 +- README.md | 2 +- test/fixtures/cases/limit.js | 18 +++++++ test/fixtures/scripts/fatal_error.js | 4 +- test/limit.test.js | 70 ++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/cases/limit.js create mode 100644 test/limit.test.js diff --git a/.eslintrc b/.eslintrc index 6bbf0e8..5fbca9e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,7 +25,7 @@ "no-implied-eval": 2, "no-labels": 2, "no-with": 2, - "no-loop-func": 1, + "no-loop-func": 0, "no-native-reassign": 2, "no-redeclare": [2, {"builtinGlobals": true}], "no-delete-var": 2, diff --git a/README.md b/README.md index b471e6f..1ebe3a3 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ require('xprofiler')(); * **patch_http**: 是否对原生 http 模块进行 patch,输出 http 请求相关信息,默认 `true` * **patch_http_timeout**: 默认 http 请求超时时间,单位秒,作为 http 请求统计,默认 `30` * **check_throw**: `xprofiler` 启动时检测错误时是否需要 throw,默认 `true` -* **auto_incr_heap_limit_size**: `enable_auto_incr_heap_limit` 开启后,每次自动增加的堆上限大小,默认为 `512` (MB) +* **auto_incr_heap_limit_size**: `enable_auto_incr_heap_limit` 开启后,每次自动增加的堆上限大小,默认为 `256` (MB) * **enable_log_uv_handles**: 是否要采集 libuv 句柄的详细分类信息,比如 tcp 句柄数量,timers 数量,文件句柄数量等,默认为 `true` * **enable_fatal_error_hook**: 是否需要在 V8 出现 FatalError 时配置钩子,默认 `true` * **enable_fatal_error_report**: 是否需要在 V8 出现 FataLError 时导出 Report 文件,默认 `true` diff --git a/test/fixtures/cases/limit.js b/test/fixtures/cases/limit.js new file mode 100644 index 0000000..193df3d --- /dev/null +++ b/test/fixtures/cases/limit.js @@ -0,0 +1,18 @@ +'use strict'; + +const path = require('path'); +const { filterTestCaseByPlatform } = require('../utils'); + +const exitFatalErrorScriptPath = path.join(__dirname, '../scripts/fatal_error.js'); + +exports = module.exports = function () { + const list = [ + { + title: 'limit hook is valid', + subTitle: 'auto increase heap limit is ok.', + jspath: exitFatalErrorScriptPath, + } + ]; + + return filterTestCaseByPlatform(list); +}; \ No newline at end of file diff --git a/test/fixtures/scripts/fatal_error.js b/test/fixtures/scripts/fatal_error.js index d01b762..189a181 100644 --- a/test/fixtures/scripts/fatal_error.js +++ b/test/fixtures/scripts/fatal_error.js @@ -16,6 +16,6 @@ process.send({ type: utils.clientConst.xprofilerDone }); const array = []; setInterval(() => { - array.push(new Array(10e6).fill('*')); - console.log('now rss:', process.memoryUsage().rss / 1024 / 1024 + ' Mb'); + array.push(new Array(0.5 * 10e6).fill('*')); + console.log('now rss:', process.memoryUsage().rss / 1024 / 1024 + ' MB'); }, Number(process.env.XPROFILER_FATAL_ERROR_INTERVAL) || 1); \ No newline at end of file diff --git a/test/limit.test.js b/test/limit.test.js new file mode 100644 index 0000000..71a75dc --- /dev/null +++ b/test/limit.test.js @@ -0,0 +1,70 @@ +'use strict'; + +const os = require('os'); +const fs = require('fs'); +const cp = require('child_process'); +const path = require('path'); +const expect = require('expect.js'); +const promisify = require('util').promisify; +const readdir = promisify(fs.readdir); +const unlink = promisify(fs.unlink); +const utils = require('./fixtures/utils'); +const cases = require('./fixtures/cases/limit')(); + +const currentPlatform = os.platform(); + +const logdir = utils.createLogDir('logdir_limit'); + +const casesLength = cases.length; + +for (const cse of cases) { + const ospt = cse.platform || currentPlatform; + describe(`[${ospt}] ${cse.title}`, function () { + const initialHeapLimit = 128; + const autoIncreaseHeapLimitSize = 128; + const MB = 1024 * 1024; + + let stdout = ''; + let subprocess = null; + before(async function () { + subprocess = cp.fork(cse.jspath, { + execArgv: [`--max-old-space-size=${initialHeapLimit}`], + env: Object.assign({}, process.env, { + XPROFILER_LOG_DIR: logdir, + XPROFILER_LOG_LEVEL: 2, + XPROFILER_LOG_TYPE: 1, + XPROFILER_ENABLE_AUTO_INCR_HEAP_LIMIT: 'YES', + XPROFILER_AUTO_INCR_HEAP_LIMIT_SIZE: autoIncreaseHeapLimitSize, + XPROFILER_FATAL_ERROR_INTERVAL: 500, + }, cse.env), + stdio: [0, 'pipe', 'pipe', 'ipc'], + }); + subprocess.stdout.on('data', chunk => stdout += chunk.toString()); + await utils.sleep(5000); + subprocess.kill(); + console.log('========= stdout =========\n\n', stdout, '\n========= end ========='); + }); + after(async function () { + const files = await readdir(logdir); + for (const file of files) { + await unlink(path.join(logdir, file)); + } + if (cse === cases[casesLength - 1]) { + utils.cleanDir(logdir); + } + + subprocess.kill(); + }); + + for (let i = 1; i < 3; i++) { + it(`${cse.subTitle} with ${i} times heap increase factor`, function () { + const increaseLog = `current_heap_limit is ${(initialHeapLimit + (i - 1) * autoIncreaseHeapLimitSize) * MB}, ` + + `initial_heap_limit is ${initialHeapLimit * MB}, ` + + `auto_incr_heap_limit_size is ${autoIncreaseHeapLimitSize}, ` + + `increased_heap is ${initialHeapLimit * MB + i * autoIncreaseHeapLimitSize * MB}`; + console.log('increaseLog:', increaseLog); + expect(stdout).to.contain(increaseLog); + }); + } + }); +} \ No newline at end of file From f62d0ae7e60fdf9e17ce8722879bbeb76dc9ed49 Mon Sep 17 00:00:00 2001 From: hyj1991 Date: Tue, 10 Jan 2023 11:44:07 +0800 Subject: [PATCH 6/6] ignore windows --- test/fixtures/cases/limit.js | 2 ++ test/limit.test.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/fixtures/cases/limit.js b/test/fixtures/cases/limit.js index 193df3d..48e8f0a 100644 --- a/test/fixtures/cases/limit.js +++ b/test/fixtures/cases/limit.js @@ -1,5 +1,6 @@ 'use strict'; +const os = require('os'); const path = require('path'); const { filterTestCaseByPlatform } = require('../utils'); @@ -11,6 +12,7 @@ exports = module.exports = function () { title: 'limit hook is valid', subTitle: 'auto increase heap limit is ok.', jspath: exitFatalErrorScriptPath, + skip: os.platform() === 'win32' } ]; diff --git a/test/limit.test.js b/test/limit.test.js index 71a75dc..293d963 100644 --- a/test/limit.test.js +++ b/test/limit.test.js @@ -57,7 +57,7 @@ for (const cse of cases) { }); for (let i = 1; i < 3; i++) { - it(`${cse.subTitle} with ${i} times heap increase factor`, function () { + (cse.skip ? it.skip : it)(`${cse.subTitle} with ${i} times heap increase factor`, function () { const increaseLog = `current_heap_limit is ${(initialHeapLimit + (i - 1) * autoIncreaseHeapLimitSize) * MB}, ` + `initial_heap_limit is ${initialHeapLimit * MB}, ` + `auto_incr_heap_limit_size is ${autoIncreaseHeapLimitSize}, `