UNPKG

nginx-testing

Version:

Support for integration/acceptance testing of nginx configuration.

240 lines 9.69 kB
/// <reference types="node" /> import { Writable } from 'node:stream'; import { PatchOperation } from './nginxConf'; type ConfigPatch = Array<PatchOperation & { ifModule?: string; }>; /** * The default patch to be applied on the nginx configs to make it compatible with * the runner. */ export declare const configPatch: ConfigPatch; /** * Options for the {@link startNginx} function. */ export type NginxOptions = RequiredKeys<BaseOptions, 'configPath'> | RequiredKeys<BaseOptions, 'config'>; /** * Options for the {@link startNginx} function. */ interface BaseOptions { /** * Name or path of the nginx binary to start. Defaults to `'nginx'`. * * This option is ignored if `version` is provided. */ binPath?: string; /** * A SemVer version range specifying the nginx version to run. * * Nginx binary for your OS and architecture will be downloaded from * [nginx-binaries](https://github.com/jirutka/nginx-binaries). It will be stored in * directory `.cache/nginx-binaries/` inside the nearest writable `node_modules` * directory or in `nginx-binaries/` inside the system-preferred temp directory. * * Not all versions are available. You can find a list of available binaries at * [nginx-binaries](https://jirutka.github.io/nginx-binaries/). */ version?: string; /** * Nginx configuration to use. * * If `configPath` is provided, the processed config will be written to a temporary * file `.<filename>~` (where `<filename>` is a filename from `configPath`) in the * `configPath`'s directory (e.g. `conf/nginx.conf` -> `conf/.nginx.conf~`). Otherwise * it will be written into `nginx.conf` file in `workDir`. In either case, this file * will be automatically deleted after stopping the nginx. * * The config may include the following placeholders which will be replaced with * corresponding values: * * - `__ADDRESS__` -- The address as specified in `bindAddress`. * - `__CONFDIR__` -- Path to directory with the config file as specified in `configPath`. * - `__CWD__` -- The current working directory as reported by `process.cwd()`. * - `__WORKDIR__` -- Path to the nginx's working directory as specified in `workDir`. * - `__PORT__`, `__PORT_1__`, ..., `__PORT_9__` -- The port numbers as specified in * `ports` and `preferredPorts`. * * It will be modified for compatibility with the runner by applying patch operations * specified in {@link configPatch} variable. * * Either `configPath`, or `config` must be provided! */ config?: string; /** * Path of the nginx configuration file to use. * * This file will be processed and the resulting config file will be written to * a temporary file `.<filename>~` (where `<filename>` is a filename from `configPath`) * in the `configPath`'s directory (e.g. `conf/nginx.conf` -> `conf/.nginx.conf~`). * This temporary file will be automatically deleted after stopping the nginx. * * See {@link config} option for information about placeholders and patching. * * Either `configPath`, or `config` must be provided! */ configPath?: string; /** * Hostname or IP address the port(s) will be binding on. This is used when searching * for free ports (see `preferredPorts`) and for substituting `__ADDRESS__` placeholder * in the given nginx config. Defaults to `'127.0.0.1'`. */ bindAddress?: string; /** * A list of port numbers for substituting `__PORT__`, `__PORT_1__`, ..., `__PORT_9__` * placeholders in the given nginx config. Unlike `preferredPorts`, these are _not_ * checked for availability and nginx will fail to start if any of the provided and * used ports is unavailable. * * If it's not provided or more ports are needed, next ports are selected from the * `preferredPorts` or randomly. */ ports?: number[]; /** * A list of preferred port numbers to use for substituting `__PORT__`, `__PORT_1__`, * ..., `__PORT_9__` placeholders in the given nginx config. * * Unavailable ports (used by some other program or restricted by OS) are skipped. * If there are no preferred ports left and another port is needed, a random port * number is used. */ preferredPorts?: number[]; /** * Path of a directory that will be passed as a _prefix_ (`-p`) into `nginx`. * It will be automatically created if doesn't exist. * * If not provided, an unique temporary directory will be created: * `.cache/nginx-testing-XXXXXX/` relative to the nearest writable `node_modules` * (nearest to `process.cwd()`) or `nginx-testing-XXXXXX/` in the system-preferred * temp directory. The created directory will be automatically deleted after stopping. */ workDir?: string; /** * One of: * * - `'buffer'` -- Collect the nginx's stderr to a buffer that can be read using * `readErrorLog()` (default). * - `'ignore'` -- Ignore nginx's stderr. * - `'inherit'` -- Pass through the nginx's stderr output to the Node process. * - `<Writable>` -- A writable stream to pipe the nginx's stderr to. * * Nginx error log is expected to be redirected to _stderr_. * Directive `error_log stderr info;` will be automatically added to the config, * unless there's already `error_log` defined in the main context. */ errorLog?: 'buffer' | 'ignore' | 'inherit' | Writable; /** * One of: * * - `'buffer'` -- Collect the nginx's access log to a buffer that can be read using * `readAccessLog()` (default). * - `'ignore'` -- Ignore nginx's access log. * - `<Writable>` -- A writable stream to pipe the nginx's access log to. * * Nginx access log is expected to be redirected to file `<workDir>/access.log`. * Directive `access_log access.log;` will be automatically added to the config, * unless there's already `access_log` defined in the `http` context. */ accessLog?: 'buffer' | 'ignore' | Writable; /** * Number of milliseconds after the start to wait for the nginx to respond to the * health-check request (`HEAD http://<bindAddress>:<ports[0]>/health`). Any HTTP * status is considered as success - it just checks if the nginx is listening and * responding. * * Defaults to `1000`. */ startTimeoutMsec?: number; } type RequiredKeys<O extends object, K extends keyof O = keyof O> = O & { [L in K]-?: O[L]; }; /** * A return value of the {@link startNginx} function. */ export interface NginxServer { /** * The current nginx configuration. */ readonly config: string; /** * PID of the nginx process. */ readonly pid: number; /** * Number of the first port allocated for nginx, i.e. the port on which nginx * should listen for connections. It's the same as `ports[0]`. */ readonly port: number; /** * A list of port numbers allocated for nginx. */ readonly ports: ReadonlyArray<number>; /** * Path of the nginx's working directory. */ readonly workDir: string; /** * Reads new messages from the access log since the last call of `readAccessLog()`. * * @throws {Error} if the process was created with option `accessLog` other than * `'buffer'` or `undefined`. */ readAccessLog(): Promise<string>; /** * Reads new messages from the error log since the last call of `readErrorLog()`. * * @throws {Error} if the process was created with option `errorLog` other than * `'buffer'` or `undefined`. */ readErrorLog(): Promise<string>; /** * Reloads the nginx (using SIGHUP), optionally with a new configuration. * Options `config` and `configPath` are mutually exclusive here. * * Nginx can be reloaded only when running with the master process. This is disabled * by default, but you can override it by declaring `master_process on` in the config. * * **Important:** The function you are looking for is `restart()`. Use `reload()` only * if you know that you cannot use `restart()`. * * **Cation:** This function doesn't work on Windows! * * @throws {Error} if nginx was started with `master_process off`. * @throws {Error} if running on Windows (`win32` platform). */ reload(opts?: RestartOptions): Promise<void>; /** * Restarts the nginx, optionally with a new configuration. * Options `config` and `configPath` are mutually exclusive here. * * The new nginx process will be started with the same ports, working directory etc. */ restart(opts?: RestartOptions): Promise<void>; /** * Stops the nginx and cleans-up temporary files and directories. */ stop(): Promise<void>; } type RestartOptions = Pick<BaseOptions, 'config' | 'configPath'>; /** * Starts nginx server with the given configuration. * * @example * import { startNginx, NginxServer } from 'nginx-testing' * import fetch from 'node-fetch' * * let nginx: NginxServer * * before(async () => { * nginx = await startNginx({ version: '1.24.x', configPath: './nginx.conf' }) * }) * after(nginx.stop) * * test('GET / results in HTTP 200', async () => { * const resp = await fetch(`http://localhost:${nginx.port}/`) * assert(resp.status === 200) * }) */ export declare function startNginx(opts: NginxOptions): Promise<NginxServer>; export {}; //# sourceMappingURL=nginxRunner.d.ts.map