11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci// Flags: --expose-internals
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common');
51cb0ef41Sopenharmony_ciif (!common.hasCrypto)
61cb0ef41Sopenharmony_ci  common.skip('missing crypto');
71cb0ef41Sopenharmony_ciconst http2 = require('http2');
81cb0ef41Sopenharmony_ciconst { internalBinding } = require('internal/test/binding');
91cb0ef41Sopenharmony_ciconst {
101cb0ef41Sopenharmony_ci  constants,
111cb0ef41Sopenharmony_ci  Http2Stream,
121cb0ef41Sopenharmony_ci  nghttp2ErrorString
131cb0ef41Sopenharmony_ci} = internalBinding('http2');
141cb0ef41Sopenharmony_ciconst { NghttpError } = require('internal/http2/util');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// Tests error handling within pushStream
171cb0ef41Sopenharmony_ci// - NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE (should emit session error)
181cb0ef41Sopenharmony_ci// - NGHTTP2_ERR_STREAM_CLOSED (should emit stream error)
191cb0ef41Sopenharmony_ci// - every other NGHTTP2 error from binding (should emit stream error)
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciconst specificTestKeys = [
221cb0ef41Sopenharmony_ci  'NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE',
231cb0ef41Sopenharmony_ci  'NGHTTP2_ERR_STREAM_CLOSED',
241cb0ef41Sopenharmony_ci];
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciconst specificTests = [
271cb0ef41Sopenharmony_ci  {
281cb0ef41Sopenharmony_ci    ngError: constants.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE,
291cb0ef41Sopenharmony_ci    error: {
301cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_OUT_OF_STREAMS',
311cb0ef41Sopenharmony_ci      name: 'Error',
321cb0ef41Sopenharmony_ci      message: 'No stream ID is available because ' +
331cb0ef41Sopenharmony_ci               'maximum stream ID has been reached'
341cb0ef41Sopenharmony_ci    },
351cb0ef41Sopenharmony_ci    type: 'stream'
361cb0ef41Sopenharmony_ci  },
371cb0ef41Sopenharmony_ci  {
381cb0ef41Sopenharmony_ci    ngError: constants.NGHTTP2_ERR_STREAM_CLOSED,
391cb0ef41Sopenharmony_ci    error: {
401cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_INVALID_STREAM',
411cb0ef41Sopenharmony_ci      name: 'Error'
421cb0ef41Sopenharmony_ci    },
431cb0ef41Sopenharmony_ci    type: 'stream'
441cb0ef41Sopenharmony_ci  },
451cb0ef41Sopenharmony_ci];
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ciconst genericTests = Object.getOwnPropertyNames(constants)
481cb0ef41Sopenharmony_ci  .filter((key) => (
491cb0ef41Sopenharmony_ci    key.indexOf('NGHTTP2_ERR') === 0 && specificTestKeys.indexOf(key) < 0
501cb0ef41Sopenharmony_ci  ))
511cb0ef41Sopenharmony_ci  .map((key) => ({
521cb0ef41Sopenharmony_ci    ngError: constants[key],
531cb0ef41Sopenharmony_ci    error: {
541cb0ef41Sopenharmony_ci      code: 'ERR_HTTP2_ERROR',
551cb0ef41Sopenharmony_ci      constructor: NghttpError,
561cb0ef41Sopenharmony_ci      name: 'Error',
571cb0ef41Sopenharmony_ci      message: nghttp2ErrorString(constants[key])
581cb0ef41Sopenharmony_ci    },
591cb0ef41Sopenharmony_ci    type: 'stream'
601cb0ef41Sopenharmony_ci  }));
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ciconst tests = specificTests.concat(genericTests);
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_cilet currentError;
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// Mock submitPushPromise because we only care about testing error handling
681cb0ef41Sopenharmony_ciHttp2Stream.prototype.pushPromise = () => currentError.ngError;
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciconst server = http2.createServer();
711cb0ef41Sopenharmony_ciserver.on('stream', common.mustCall((stream, headers) => {
721cb0ef41Sopenharmony_ci  stream.pushStream({}, common.expectsError(currentError.error));
731cb0ef41Sopenharmony_ci  stream.respond();
741cb0ef41Sopenharmony_ci  stream.end();
751cb0ef41Sopenharmony_ci}, tests.length));
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => runTest(tests.shift())));
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cifunction runTest(test) {
801cb0ef41Sopenharmony_ci  const url = `http://localhost:${server.address().port}`;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  const client = http2.connect(url);
831cb0ef41Sopenharmony_ci  const req = client.request();
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  currentError = test;
861cb0ef41Sopenharmony_ci  req.resume();
871cb0ef41Sopenharmony_ci  req.end();
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  req.on('close', common.mustCall(() => {
901cb0ef41Sopenharmony_ci    client.close();
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    if (!tests.length) {
931cb0ef41Sopenharmony_ci      server.close();
941cb0ef41Sopenharmony_ci    } else {
951cb0ef41Sopenharmony_ci      runTest(tests.shift());
961cb0ef41Sopenharmony_ci    }
971cb0ef41Sopenharmony_ci  }));
981cb0ef41Sopenharmony_ci}
99