11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciconst assert = require('assert');
41cb0ef41Sopenharmony_ciconst { once } = require('events');
51cb0ef41Sopenharmony_ciconst v8 = require('v8');
61cb0ef41Sopenharmony_ciconst { Worker } = require('worker_threads');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci// Verify that Workers don't care about --stack-size, as they have their own
91cb0ef41Sopenharmony_ci// fixed and known stack sizes.
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciasync function runWorker(options = {}) {
121cb0ef41Sopenharmony_ci  const empiricalStackDepth = new Uint32Array(new SharedArrayBuffer(4));
131cb0ef41Sopenharmony_ci  const worker = new Worker(`
141cb0ef41Sopenharmony_ci  const { workerData: { empiricalStackDepth } } = require('worker_threads');
151cb0ef41Sopenharmony_ci  function f() {
161cb0ef41Sopenharmony_ci    empiricalStackDepth[0]++;
171cb0ef41Sopenharmony_ci    f();
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci  f();`, {
201cb0ef41Sopenharmony_ci    eval: true,
211cb0ef41Sopenharmony_ci    workerData: { empiricalStackDepth },
221cb0ef41Sopenharmony_ci    ...options
231cb0ef41Sopenharmony_ci  });
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci  const [ error ] = await once(worker, 'error');
261cb0ef41Sopenharmony_ci  if (!options.skipErrorCheck) {
271cb0ef41Sopenharmony_ci    common.expectsError({
281cb0ef41Sopenharmony_ci      constructor: RangeError,
291cb0ef41Sopenharmony_ci      message: 'Maximum call stack size exceeded'
301cb0ef41Sopenharmony_ci    })(error);
311cb0ef41Sopenharmony_ci  }
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci  return empiricalStackDepth[0];
341cb0ef41Sopenharmony_ci}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci(async function() {
371cb0ef41Sopenharmony_ci  {
381cb0ef41Sopenharmony_ci    v8.setFlagsFromString('--stack-size=500');
391cb0ef41Sopenharmony_ci    const w1stack = await runWorker();
401cb0ef41Sopenharmony_ci    v8.setFlagsFromString('--stack-size=1000');
411cb0ef41Sopenharmony_ci    const w2stack = await runWorker();
421cb0ef41Sopenharmony_ci    // Make sure the two stack sizes are within 10 % of each other, i.e. not
431cb0ef41Sopenharmony_ci    // affected by the different `--stack-size` settings.
441cb0ef41Sopenharmony_ci    assert(Math.max(w1stack, w2stack) / Math.min(w1stack, w2stack) < 1.1,
451cb0ef41Sopenharmony_ci           `w1stack = ${w1stack}, w2stack = ${w2stack} are too far apart`);
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  {
491cb0ef41Sopenharmony_ci    const w1stack = await runWorker({ resourceLimits: { stackSizeMb: 0.5 } });
501cb0ef41Sopenharmony_ci    const w2stack = await runWorker({ resourceLimits: { stackSizeMb: 1.0 } });
511cb0ef41Sopenharmony_ci    // Make sure the two stack sizes are at least 40 % apart from each other,
521cb0ef41Sopenharmony_ci    // i.e. affected by the different `stackSizeMb` settings.
531cb0ef41Sopenharmony_ci    assert(w2stack > w1stack * 1.4,
541cb0ef41Sopenharmony_ci           `w1stack = ${w1stack}, w2stack = ${w2stack} are too close`);
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // Test that various low stack sizes result in an 'error' event.
581cb0ef41Sopenharmony_ci  // Currently the stack size needs to be at least 0.3MB for the worker to be
591cb0ef41Sopenharmony_ci  // bootstrapped properly.
601cb0ef41Sopenharmony_ci  for (const stackSizeMb of [ 0.3, 0.5, 1 ]) {
611cb0ef41Sopenharmony_ci    await runWorker({ resourceLimits: { stackSizeMb }, skipErrorCheck: true });
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci})().then(common.mustCall());
64