|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// This test validates the --max-old-space-size-percentage flag functionality |
| 4 | + |
| 5 | +require('../common'); |
| 6 | +constassert=require('node:assert'); |
| 7 | +const{ spawnSync }=require('child_process'); |
| 8 | +constos=require('os'); |
| 9 | + |
| 10 | +// Valid cases |
| 11 | +constvalidPercentages=[ |
| 12 | +'1','10','25','50','75','99','100','25.5', |
| 13 | +]; |
| 14 | + |
| 15 | +// Invalid cases |
| 16 | +constinvalidPercentages=[ |
| 17 | +['',/--max-old-space-size-percentage=requiresanargument/], |
| 18 | +['0',/--max-old-space-size-percentagemustbegreaterthan0andupto100\.Got:0/], |
| 19 | +['101',/--max-old-space-size-percentagemustbegreaterthan0andupto100\.Got:101/], |
| 20 | +['-1',/--max-old-space-size-percentagemustbegreaterthan0andupto100\.Got:-1/], |
| 21 | +['abc',/--max-old-space-size-percentagemustbegreaterthan0andupto100\.Got:abc/], |
| 22 | +['1%',/--max-old-space-size-percentagemustbegreaterthan0andupto100\.Got:1%/], |
| 23 | +]; |
| 24 | + |
| 25 | +// Test valid cases |
| 26 | +validPercentages.forEach((input)=>{ |
| 27 | +constresult=spawnSync(process.execPath,[ |
| 28 | +`--max-old-space-size-percentage=${input}`, |
| 29 | +],{stdio: ['pipe','pipe','pipe']}); |
| 30 | +assert.strictEqual(result.status,0,`Expected exit code 0 for valid input ${input}`); |
| 31 | +assert.strictEqual(result.stderr.toString(),'',`Expected empty stderr for valid input ${input}`); |
| 32 | +}); |
| 33 | + |
| 34 | +// Test invalid cases |
| 35 | +invalidPercentages.forEach((input)=>{ |
| 36 | +constresult=spawnSync(process.execPath,[ |
| 37 | +`--max-old-space-size-percentage=${input[0]}`, |
| 38 | +],{stdio: ['pipe','pipe','pipe']}); |
| 39 | +assert.notStrictEqual(result.status,0,`Expected non-zero exit for invalid input ${input[0]}`); |
| 40 | +assert(input[1].test(result.stderr.toString()),`Unexpected error message for invalid input ${input[0]}`); |
| 41 | +}); |
| 42 | + |
| 43 | +// Test NODE_OPTIONS with valid percentages |
| 44 | +validPercentages.forEach((input)=>{ |
| 45 | +constresult=spawnSync(process.execPath,[],{ |
| 46 | +stdio: ['pipe','pipe','pipe'], |
| 47 | +env: { ...process.env,NODE_OPTIONS: `--max-old-space-size-percentage=${input}`} |
| 48 | +}); |
| 49 | +assert.strictEqual(result.status,0,`NODE_OPTIONS: Expected exit code 0 for valid input ${input}`); |
| 50 | +assert.strictEqual(result.stderr.toString(),'',`NODE_OPTIONS: Expected empty stderr for valid input ${input}`); |
| 51 | +}); |
| 52 | + |
| 53 | +// Test NODE_OPTIONS with invalid percentages |
| 54 | +invalidPercentages.forEach((input)=>{ |
| 55 | +constresult=spawnSync(process.execPath,[],{ |
| 56 | +stdio: ['pipe','pipe','pipe'], |
| 57 | +env: { ...process.env,NODE_OPTIONS: `--max-old-space-size-percentage=${input[0]}`} |
| 58 | +}); |
| 59 | +assert.notStrictEqual(result.status,0,`NODE_OPTIONS: Expected non-zero exit for invalid input ${input[0]}`); |
| 60 | +assert(input[1].test(result.stderr.toString()),`NODE_OPTIONS: Unexpected error message for invalid input ${input[0]}`); |
| 61 | +}); |
| 62 | + |
| 63 | +// Test percentage calculation validation |
| 64 | +functiongetHeapSizeForPercentage(percentage){ |
| 65 | +constresult=spawnSync(process.execPath,[ |
| 66 | +'--max-old-space-size=3000',// This value should be ignored, since percentage takes precedence |
| 67 | +`--max-old-space-size-percentage=${percentage}`, |
| 68 | +'--max-old-space-size=1000',// This value should be ignored, since percentage take precedence |
| 69 | +'-e',` |
| 70 | + const v8 = require('v8'); |
| 71 | + const stats = v8.getHeapStatistics(); |
| 72 | + const heapSizeLimitMB = Math.floor(stats.heap_size_limit / 1024 / 1024); |
| 73 | + console.log(heapSizeLimitMB); |
| 74 | + `, |
| 75 | +],{ |
| 76 | +stdio: ['pipe','pipe','pipe'], |
| 77 | +env: { |
| 78 | + ...process.env, |
| 79 | +NODE_OPTIONS: `--max-old-space-size=2000`// This value should be ignored, since percentage takes precedence |
| 80 | +} |
| 81 | +}); |
| 82 | + |
| 83 | +if(result.status!==0){ |
| 84 | +thrownewError(`Failed to get heap size for ${percentage}: ${result.stderr.toString()}`); |
| 85 | +} |
| 86 | + |
| 87 | +returnparseInt(result.stdout.toString(),10); |
| 88 | +} |
| 89 | + |
| 90 | +consttestPercentages=[25,50,75,100]; |
| 91 | +constheapSizes={}; |
| 92 | + |
| 93 | +// Get heap sizes for all test percentages |
| 94 | +testPercentages.forEach((percentage)=>{ |
| 95 | +heapSizes[percentage]=getHeapSizeForPercentage(percentage); |
| 96 | +}); |
| 97 | + |
| 98 | +// Test relative relationships between percentages |
| 99 | +// 50% should be roughly half of 100% |
| 100 | +constratio50to100=heapSizes[50]/heapSizes[100]; |
| 101 | +assert( |
| 102 | +ratio50to100>=0.4&&ratio50to100<=0.6, |
| 103 | +`50% heap size should be roughly half of 100% (got ${ratio50to100.toFixed(2)}, expected ~0.5)` |
| 104 | +); |
| 105 | + |
| 106 | +// 25% should be roughly quarter of 100% |
| 107 | +constratio25to100=heapSizes[25]/heapSizes[100]; |
| 108 | +assert( |
| 109 | +ratio25to100>=0.15&&ratio25to100<=0.35, |
| 110 | +`25% heap size should be roughly quarter of 100% (got ${ratio25to100.toFixed(2)}, expected ~0.25)` |
| 111 | +); |
| 112 | + |
| 113 | +// 75% should be roughly three-quarters of 100% |
| 114 | +constratio75to100=heapSizes[75]/heapSizes[100]; |
| 115 | +assert( |
| 116 | +ratio75to100>=0.65&&ratio75to100<=0.85, |
| 117 | +`75% heap size should be roughly three-quarters of 100% (got ${ratio75to100.toFixed(2)}, expected ~0.75)` |
| 118 | +); |
| 119 | + |
| 120 | +// Validate heap sizes against system memory |
| 121 | +consttotalMemoryMB=Math.floor(os.totalmem()/1024/1024); |
| 122 | +constmargin=10;// 5% margin |
| 123 | +testPercentages.forEach((percentage)=>{ |
| 124 | +constupperLimit=totalMemoryMB*((percentage+margin)/100); |
| 125 | +assert( |
| 126 | +heapSizes[percentage]<=upperLimit, |
| 127 | +`Heap size for ${percentage}% (${heapSizes[percentage]} MB) should not exceed upper limit (${upperLimit} MB)` |
| 128 | +); |
| 129 | +constlowerLimit=totalMemoryMB*((percentage-margin)/100); |
| 130 | +assert( |
| 131 | +heapSizes[percentage]>=lowerLimit, |
| 132 | +`Heap size for ${percentage}% (${heapSizes[percentage]} MB) should not be less than lower limit (${lowerLimit} MB)` |
| 133 | +); |
| 134 | +}); |
0 commit comments