mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 00:20:08 +01:00
tests: start adding quic test server utilities
PR-URL: https://github.com/nodejs/node/pull/59946 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
parent
65a32bac18
commit
cff138c6b1
58
deps/ngtcp2/ngtcp2.gyp
vendored
58
deps/ngtcp2/ngtcp2.gyp
vendored
|
|
@ -266,8 +266,18 @@
|
||||||
'HAVE_CONFIG_H',
|
'HAVE_CONFIG_H',
|
||||||
'WITH_EXAMPLE_OSSL',
|
'WITH_EXAMPLE_OSSL',
|
||||||
'EV_STANDALONE=1',
|
'EV_STANDALONE=1',
|
||||||
|
'HAVE_UNISTD_H',
|
||||||
|
'HAVE_ARPA_INET_H',
|
||||||
|
'HAVE_NETINET_IN_H',
|
||||||
|
'HAVE_NETINET_IP_H',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
['OS=="aix" or OS=="win"', {
|
||||||
|
# AIX does not support some of the networking features used in
|
||||||
|
# the test server. Windows also lacks the Unix-specific headers
|
||||||
|
# and system calls required by the ngtcp2 examples.
|
||||||
|
'type': 'none', # Disable as executable on AIX and Windows
|
||||||
|
}],
|
||||||
['OS=="mac"', {
|
['OS=="mac"', {
|
||||||
'defines': [
|
'defines': [
|
||||||
'__APPLE_USE_RFC_3542',
|
'__APPLE_USE_RFC_3542',
|
||||||
|
|
@ -281,25 +291,6 @@
|
||||||
'libraries': [ '-lsocket', '-lnsl' ],
|
'libraries': [ '-lsocket', '-lnsl' ],
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
['OS=="win"', {
|
|
||||||
'defines': [
|
|
||||||
'WIN32',
|
|
||||||
'_WINDOWS',
|
|
||||||
],
|
|
||||||
'msvs_settings': {
|
|
||||||
'VCCLCompilerTool': {
|
|
||||||
'CompileAs': '1'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
['OS!="win"', {
|
|
||||||
'defines': [
|
|
||||||
'HAVE_UNISTD_H',
|
|
||||||
'HAVE_ARPA_INET_H',
|
|
||||||
'HAVE_NETINET_IN_H',
|
|
||||||
'HAVE_NETINET_IP_H',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
[ 'OS=="linux" or OS=="openharmony"', {
|
[ 'OS=="linux" or OS=="openharmony"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [ '-ldl', '-lrt' ],
|
'libraries': [ '-ldl', '-lrt' ],
|
||||||
|
|
@ -333,8 +324,18 @@
|
||||||
'HAVE_CONFIG_H',
|
'HAVE_CONFIG_H',
|
||||||
'WITH_EXAMPLE_OSSL',
|
'WITH_EXAMPLE_OSSL',
|
||||||
'EV_STANDALONE=1',
|
'EV_STANDALONE=1',
|
||||||
|
'HAVE_UNISTD_H',
|
||||||
|
'HAVE_ARPA_INET_H',
|
||||||
|
'HAVE_NETINET_IN_H',
|
||||||
|
'HAVE_NETINET_IP_H',
|
||||||
],
|
],
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
['OS=="aix" or OS=="win"', {
|
||||||
|
# AIX does not support some of the networking features used in
|
||||||
|
# the test client. Windows also lacks the Unix-specific headers
|
||||||
|
# and system calls required by the ngtcp2 examples.
|
||||||
|
'type': 'none', # Disable as executable on AIX and Windows
|
||||||
|
}],
|
||||||
['OS=="mac"', {
|
['OS=="mac"', {
|
||||||
'defines': [
|
'defines': [
|
||||||
'__APPLE_USE_RFC_3542',
|
'__APPLE_USE_RFC_3542',
|
||||||
|
|
@ -348,25 +349,6 @@
|
||||||
'libraries': [ '-lsocket', '-lnsl' ],
|
'libraries': [ '-lsocket', '-lnsl' ],
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
['OS=="win"', {
|
|
||||||
'defines': [
|
|
||||||
'WIN32',
|
|
||||||
'_WINDOWS',
|
|
||||||
],
|
|
||||||
'msvs_settings': {
|
|
||||||
'VCCLCompilerTool': {
|
|
||||||
'CompileAs': '1'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
['OS!="win"', {
|
|
||||||
'defines': [
|
|
||||||
'HAVE_UNISTD_H',
|
|
||||||
'HAVE_ARPA_INET_H',
|
|
||||||
'HAVE_NETINET_IN_H',
|
|
||||||
'HAVE_NETINET_IP_H',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
[ 'OS=="linux" or OS=="openharmony"', {
|
[ 'OS=="linux" or OS=="openharmony"', {
|
||||||
'link_settings': {
|
'link_settings': {
|
||||||
'libraries': [ '-ldl', '-lrt' ],
|
'libraries': [ '-ldl', '-lrt' ],
|
||||||
|
|
|
||||||
64
test/common/quic/test-client.mjs
Normal file
64
test/common/quic/test-client.mjs
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import { spawn } from 'node:child_process';
|
||||||
|
|
||||||
|
export default class QuicTestClient {
|
||||||
|
#pathToClient;
|
||||||
|
#runningProcess;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.#pathToClient = resolve(process.execPath, '../ngtcp2_test_client');
|
||||||
|
console.log(this.#pathToClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
help(options = { stdio: 'inherit' }) {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers();
|
||||||
|
const proc = spawn(this.#pathToClient, ['--help'], options);
|
||||||
|
proc.on('error', reject);
|
||||||
|
proc.on('exit', (code, signal) => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Process exited with code ${code} and signal ${signal}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
run(address, port, uri, options = { stdio: 'inherit' }) {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers();
|
||||||
|
if (this.#runningProcess) {
|
||||||
|
reject(new Error('Server is already running'));
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
const args = [
|
||||||
|
address,
|
||||||
|
port,
|
||||||
|
uri ?? '',
|
||||||
|
];
|
||||||
|
this.#runningProcess = spawn(this.#pathToClient, args, options);
|
||||||
|
this.#runningProcess.on('error', (err) => {
|
||||||
|
this.#runningProcess = undefined;
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
this.#runningProcess.on('exit', (code, signal) => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
if (code === null && signal === 'SIGTERM') {
|
||||||
|
// Normal termination due to stop() being called.
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject(new Error(`Process exited with code ${code} and signal ${signal}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (this.#runningProcess) {
|
||||||
|
this.#runningProcess.kill();
|
||||||
|
this.#runningProcess = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
66
test/common/quic/test-server.mjs
Normal file
66
test/common/quic/test-server.mjs
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import { spawn } from 'node:child_process';
|
||||||
|
|
||||||
|
export default class QuicTestServer {
|
||||||
|
#pathToServer;
|
||||||
|
#runningProcess;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.#pathToServer = resolve(process.execPath, '../ngtcp2_test_server');
|
||||||
|
console.log(this.#pathToServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
help(options = { stdio: 'inherit' }) {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers();
|
||||||
|
const proc = spawn(this.#pathToServer, ['--help'], options);
|
||||||
|
proc.on('error', reject);
|
||||||
|
proc.on('exit', (code, signal) => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Process exited with code ${code} and signal ${signal}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
run(address, port, keyFile, certFile, options = { stdio: 'inherit' }) {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers();
|
||||||
|
if (this.#runningProcess) {
|
||||||
|
reject(new Error('Server is already running'));
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
const args = [
|
||||||
|
address,
|
||||||
|
port,
|
||||||
|
keyFile,
|
||||||
|
certFile,
|
||||||
|
];
|
||||||
|
this.#runningProcess = spawn(this.#pathToServer, args, options);
|
||||||
|
this.#runningProcess.on('error', (err) => {
|
||||||
|
this.#runningProcess = undefined;
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
this.#runningProcess.on('exit', (code, signal) => {
|
||||||
|
this.#runningProcess = undefined;
|
||||||
|
if (code === 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
if (code === null && signal === 'SIGTERM') {
|
||||||
|
// Normal termination due to stop() being called.
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject(new Error(`Process exited with code ${code} and signal ${signal}`));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (this.#runningProcess) {
|
||||||
|
this.#runningProcess.kill();
|
||||||
|
this.#runningProcess = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
32
test/parallel/test-quic-test-client.mjs
Normal file
32
test/parallel/test-quic-test-client.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Flags: --experimental-quic
|
||||||
|
import { hasQuic, isAIX, isWindows, skip } from '../common/index.mjs';
|
||||||
|
import { rejects } from 'node:assert';
|
||||||
|
|
||||||
|
if (!hasQuic) {
|
||||||
|
skip('QUIC support is not enabled');
|
||||||
|
}
|
||||||
|
if (isAIX) {
|
||||||
|
// AIX does not support some of the networking features used in the ngtcp2
|
||||||
|
// example server and client.
|
||||||
|
skip('QUIC third-party tests are disabled on AIX');
|
||||||
|
}
|
||||||
|
if (isWindows) {
|
||||||
|
// Windows does not support the [Li/U]nix specific headers and system calls
|
||||||
|
// required by the ngtcp2 example server/client.
|
||||||
|
skip('QUIC third-party tests are disabled on Windows');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { default: QuicTestClient } = await import('../common/quic/test-client.mjs');
|
||||||
|
|
||||||
|
const client = new QuicTestClient();
|
||||||
|
|
||||||
|
// If this completes without throwing, the test passes.
|
||||||
|
await client.help({ stdio: 'ignore' });
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
client.stop();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
// We expect this to fail since there's no server running.
|
||||||
|
await rejects(client.run('localhost', '12345', undefined, { stdio: 'ignore' }),
|
||||||
|
{ message: /Process exited with code 1 and signal null/ });
|
||||||
34
test/parallel/test-quic-test-server.mjs
Normal file
34
test/parallel/test-quic-test-server.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Flags: --experimental-quic
|
||||||
|
import { hasQuic, isAIX, isWindows, skip } from '../common/index.mjs';
|
||||||
|
|
||||||
|
if (!hasQuic) {
|
||||||
|
skip('QUIC support is not enabled');
|
||||||
|
}
|
||||||
|
if (isAIX) {
|
||||||
|
// AIX does not support some of the networking features used in the ngtcp2
|
||||||
|
// example server and client.
|
||||||
|
skip('QUIC third-party tests are disabled on AIX');
|
||||||
|
}
|
||||||
|
if (isWindows) {
|
||||||
|
// Windows does not support the [Li/U]nix specific headers and system calls
|
||||||
|
// required by the ngtcp2 example server/client.
|
||||||
|
skip('QUIC third-party tests are disabled on Windows');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { default: QuicTestServer } = await import('../common/quic/test-server.mjs');
|
||||||
|
const fixtures = await import('../common/fixtures.mjs');
|
||||||
|
|
||||||
|
const server = new QuicTestServer();
|
||||||
|
const fixturesPath = fixtures.path();
|
||||||
|
|
||||||
|
// If this completes without throwing, the test passes.
|
||||||
|
await server.help({ stdio: 'ignore' });
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
server.stop();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
await server.run('localhost', '12345',
|
||||||
|
`${fixturesPath}/keys/agent1-key.pem`,
|
||||||
|
`${fixturesPath}/keys/agent1-cert.pem`,
|
||||||
|
{ stdio: 'inherit' });
|
||||||
Loading…
Reference in New Issue
Block a user