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',
|
||||
'WITH_EXAMPLE_OSSL',
|
||||
'EV_STANDALONE=1',
|
||||
'HAVE_UNISTD_H',
|
||||
'HAVE_ARPA_INET_H',
|
||||
'HAVE_NETINET_IN_H',
|
||||
'HAVE_NETINET_IP_H',
|
||||
],
|
||||
'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"', {
|
||||
'defines': [
|
||||
'__APPLE_USE_RFC_3542',
|
||||
|
|
@ -281,25 +291,6 @@
|
|||
'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"', {
|
||||
'link_settings': {
|
||||
'libraries': [ '-ldl', '-lrt' ],
|
||||
|
|
@ -333,8 +324,18 @@
|
|||
'HAVE_CONFIG_H',
|
||||
'WITH_EXAMPLE_OSSL',
|
||||
'EV_STANDALONE=1',
|
||||
'HAVE_UNISTD_H',
|
||||
'HAVE_ARPA_INET_H',
|
||||
'HAVE_NETINET_IN_H',
|
||||
'HAVE_NETINET_IP_H',
|
||||
],
|
||||
'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"', {
|
||||
'defines': [
|
||||
'__APPLE_USE_RFC_3542',
|
||||
|
|
@ -348,25 +349,6 @@
|
|||
'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"', {
|
||||
'link_settings': {
|
||||
'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