mirror of
https://github.com/tj/n.git
synced 2024-11-21 10:38:57 +01:00
Add test folder and tests
This commit is contained in:
parent
6fc267147a
commit
af1f7fe75e
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
test/proxy~~.dump
|
11
package-lock.json
generated
11
package-lock.json
generated
@ -1,5 +1,14 @@
|
||||
{
|
||||
"name": "n",
|
||||
"version": "3.0.3-0",
|
||||
"lockfileVersion": 1
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"bats": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bats/-/bats-1.1.0.tgz",
|
||||
"integrity": "sha512-1pA29OhDByrUtAXX+nmqZxgRgx2y8PvuZzbLJVjd2dpEDVDvz0MjcBMdmIPNq5lC+tG53G+RbeRsbIlv3vw7tg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,12 @@
|
||||
"type": "git",
|
||||
"url": "git://github.com/tj/n.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "test/bin/run-all-tests"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bats": "^1.1.0"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"os": [
|
||||
"!win32"
|
||||
|
47
test/bin/proxy-build
Executable file
47
test/bin/proxy-build
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unoffical bash safe mode
|
||||
set -euo pipefail
|
||||
BIN_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
waitproxy() {
|
||||
while ! nc -z localhost 8080 ; do sleep 1 ; done
|
||||
}
|
||||
|
||||
if nc -z localhost 8080; then
|
||||
echo "Error: port 8080 already in use. Is mitmdump already running?"
|
||||
pgrep -f -l mitmdump
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "Launching proxy..."
|
||||
mitmdump -w proxy~~.dump &> /dev/null &
|
||||
mitm_process="$!"
|
||||
echo "Waiting for proxy..."
|
||||
waitproxy
|
||||
|
||||
echo "Recording downloads..."
|
||||
|
||||
source tests/shared-functions.bash
|
||||
unset_n_env
|
||||
setup_tmp_prefix
|
||||
install_dummy_node
|
||||
|
||||
# Hack curl to avoid certificate issues with proxy
|
||||
readonly CURL_HOME="$(dirname "${BIN_DIRECTORY}")/config"
|
||||
export CURL_HOME
|
||||
|
||||
# Go through proxy so it can record traffic, http for taobao redirects
|
||||
http_proxy="$(hostname):8080"
|
||||
export http_proxy
|
||||
https_proxy="$(hostname):8080"
|
||||
export https_proxy
|
||||
|
||||
# native
|
||||
tests/install-reference-versions.bash
|
||||
# linux
|
||||
docker-compose run ubuntu-curl /mnt/tests/install-reference-versions.bash
|
||||
|
||||
rm -rf "${TMP_PREFIX_DIR}"
|
||||
echo "Stopping proxy"
|
||||
kill "${mitm_process}"
|
||||
|
12
test/bin/proxy-run
Executable file
12
test/bin/proxy-run
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
BIN_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
echo ""
|
||||
echo "To make use of proxy server:"
|
||||
echo " export https_proxy=\"$(hostname):8080\""
|
||||
echo " export http_proxy=\"$(hostname):8080\""
|
||||
echo " export CURL_HOME=$(dirname "${BIN_DIRECTORY}")/config"
|
||||
echo ""
|
||||
|
||||
echo "Launching proxy server..."
|
||||
mitmdump --server-replay-nopop --server-replay proxy~~.dump
|
14
test/bin/run-all-tests
Executable file
14
test/bin/run-all-tests
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
BIN_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
services=( ubuntu-curl ubuntu-wget )
|
||||
|
||||
cd "$(dirname "${BIN_DIRECTORY}")" || exit 2
|
||||
for service in "${services[@]}" ; do
|
||||
echo "${service}"
|
||||
docker-compose run --rm "${service}" "bats" "/mnt/tests"
|
||||
echo ""
|
||||
done
|
||||
|
||||
uname -s
|
||||
../node_modules/.bin/bats tests
|
2
test/config/.curlrc
Normal file
2
test/config/.curlrc
Normal file
@ -0,0 +1,2 @@
|
||||
# Allow use of mitm proxy
|
||||
--insecure
|
20
test/docker-base.yml
Normal file
20
test/docker-base.yml
Normal file
@ -0,0 +1,20 @@
|
||||
version: '2'
|
||||
# Define base service to specify the mounts and environment variables
|
||||
services:
|
||||
testbed:
|
||||
volumes:
|
||||
# make locally installed bats available in container (based on bats/install.sh)
|
||||
- ../node_modules/bats/bin/bats:/usr/local/bin/bats
|
||||
- ../node_modules/bats/libexec/bats-core:/usr/local/libexec/bats-core
|
||||
- ../node_modules/bats/man/bats.1:/usr/local/share/man/man1"
|
||||
- ../node_modules/bats/man/bats.7:/usr/local/share/man/man7"
|
||||
# the bats tests
|
||||
- ./tests:/mnt/tests
|
||||
# the n script
|
||||
- ../bin/n:/usr/local/bin/n
|
||||
# override curl settings to allow insecure connection in case using proxy
|
||||
- ./config/.curlrc:/root/.curlrc
|
||||
environment:
|
||||
# pass through proxy settings to allow caching proxy
|
||||
- http_proxy
|
||||
- https_proxy
|
16
test/docker-compose.yml
Normal file
16
test/docker-compose.yml
Normal file
@ -0,0 +1,16 @@
|
||||
version: '2'
|
||||
services:
|
||||
ubuntu-curl:
|
||||
extends:
|
||||
file: ./docker-base.yml
|
||||
service: testbed
|
||||
build:
|
||||
context: dockerfiles
|
||||
dockerfile: Dockerfile-ubuntu-curl
|
||||
ubuntu-wget:
|
||||
extends:
|
||||
file: ./docker-base.yml
|
||||
service: testbed
|
||||
build:
|
||||
context: dockerfiles
|
||||
dockerfile: Dockerfile-ubuntu-wget
|
9
test/dockerfiles/Dockerfile-ubuntu-curl
Normal file
9
test/dockerfiles/Dockerfile-ubuntu-curl
Normal file
@ -0,0 +1,9 @@
|
||||
FROM ubuntu:latest
|
||||
|
||||
# curl
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["/bin/bash"]
|
9
test/dockerfiles/Dockerfile-ubuntu-wget
Normal file
9
test/dockerfiles/Dockerfile-ubuntu-wget
Normal file
@ -0,0 +1,9 @@
|
||||
FROM ubuntu:latest
|
||||
|
||||
# wget
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["/bin/bash"]
|
70
test/tests.md
Normal file
70
test/tests.md
Normal file
@ -0,0 +1,70 @@
|
||||
# n-test
|
||||
|
||||
Prototype and develop a set of automated tests for `n`.
|
||||
|
||||
## Setup
|
||||
|
||||
Optional proxy using mitmproxy:
|
||||
|
||||
# using homebrew (Mac) to install mitmproxy
|
||||
brew install mitmproxy
|
||||
|
||||
|
||||
## Running Tests
|
||||
|
||||
Run all the tests across a range of containers and on the host system:
|
||||
|
||||
npm run test
|
||||
|
||||
Run all the tests on a single system:
|
||||
|
||||
cd test
|
||||
npx bats tests
|
||||
docker-compose run ubuntu-curl bats /mnt/tests
|
||||
|
||||
Run single test on a single system::
|
||||
|
||||
cd test
|
||||
npx bats tests/install-contents.bats
|
||||
docker-compose run ubuntu-curl bats /mnt/tests/install-contents.bats
|
||||
|
||||
## Proxy
|
||||
|
||||
To speed up running tests multiple times, you can optionally run a caching proxy for the node downloads. The curl settings are modified
|
||||
to allow an insecure connection through the mitm proxy.
|
||||
|
||||
cd test
|
||||
bin/proxy-build
|
||||
bin/proxy-run
|
||||
# follow the instructions for configuring environment variables for using proxy, then run tests
|
||||
|
||||
`node` versions added to proxy cache (and used in tests):
|
||||
|
||||
* v4.9.1
|
||||
* lts
|
||||
* latest
|
||||
|
||||
## Docker Tips
|
||||
|
||||
Using `docker-compose` in addition to `docker` for convenient mounting of `n` script and the tests into the container. Changes to the tests or to `n` itself are reflected immediately without needing to rebuild the containers.
|
||||
|
||||
`bats` is being mounted directly out of `node_modules` into the container as a manual install based on its own install script. This is a bit of a hack, but avoids needing to install `git` or `npm` for a full remote install of `bats`, and means everything on the same version of `bats`.
|
||||
|
||||
The containers each have:
|
||||
|
||||
* either curl or wget (or both) installed
|
||||
|
||||
Using `docker-compose` to run the container adds:
|
||||
|
||||
* specified `n` script mounted to `/usr/local/bin/n`
|
||||
* `test/tests` mounted to `/mnt/tests`
|
||||
* `node_modules/bats` provides `/usr/local/bin/bats` et al
|
||||
* `.curlrc` with `--insecure` to allow use of proxy
|
||||
|
||||
So for example:
|
||||
|
||||
cd test
|
||||
docker-compose run ubuntu-curl
|
||||
# in container
|
||||
n --version
|
||||
bats /mnt/tests
|
43
test/tests/install-contents.bats
Normal file
43
test/tests/install-contents.bats
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load shared-functions
|
||||
|
||||
|
||||
function setup() {
|
||||
unset_n_env
|
||||
}
|
||||
|
||||
|
||||
# Test that files get installed to expected locations
|
||||
# https://github.com/tj/n/issues/246
|
||||
|
||||
@test "install: contents" {
|
||||
readonly TARGET_VERSION="4.9.1"
|
||||
setup_tmp_prefix
|
||||
|
||||
[ ! -d "${N_PREFIX}/n/versions" ]
|
||||
[ ! -d "${N_PREFIX}/bin" ]
|
||||
[ ! -d "${N_PREFIX}/include" ]
|
||||
[ ! -d "${N_PREFIX}/lib" ]
|
||||
[ ! -d "${N_PREFIX}/shared" ]
|
||||
|
||||
install_dummy_node
|
||||
n ${TARGET_VERSION}
|
||||
|
||||
# Cached version
|
||||
[ -d "${N_PREFIX}/n/versions/node/${TARGET_VERSION}" ]
|
||||
# node and npm
|
||||
[ -f "${N_PREFIX}/bin/node" ]
|
||||
[ -f "${N_PREFIX}/bin/npm" ]
|
||||
# Installed something into each of other key folders
|
||||
[ -d "${N_PREFIX}/include/node" ]
|
||||
[ -d "${N_PREFIX}/lib/node_modules" ]
|
||||
[ -d "${N_PREFIX}/share/doc/node" ]
|
||||
# Did not install files from top level of tarball
|
||||
[ ! -f "${N_PREFIX}/README.md" ]
|
||||
|
||||
run node --version
|
||||
[ "${output}" = "v${TARGET_VERSION}" ]
|
||||
|
||||
rm -rf "${TMP_PREFIX_DIR}"
|
||||
}
|
37
test/tests/install-options.bats
Normal file
37
test/tests/install-options.bats
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load shared-functions
|
||||
|
||||
|
||||
function setup() {
|
||||
unset_n_env
|
||||
setup_tmp_prefix
|
||||
install_dummy_node
|
||||
}
|
||||
|
||||
|
||||
function teardown() {
|
||||
rm -rf "${TMP_PREFIX_DIR}"
|
||||
}
|
||||
|
||||
|
||||
@test "n --download 4.9.1" {
|
||||
n --download 4.9.1
|
||||
[ -d "${N_PREFIX}/n/versions/node/4.9.1" ]
|
||||
# Remember, we installed a dumy node so do have a bin/node
|
||||
[ ! -f "${N_PREFIX}/bin/npm" ]
|
||||
[ ! -d "${N_PREFIX}/include" ]
|
||||
[ ! -d "${N_PREFIX}/lib" ]
|
||||
[ ! -d "${N_PREFIX}/shared" ]
|
||||
}
|
||||
|
||||
|
||||
@test "n --quiet 4.9.1" {
|
||||
# just checking option is allowed, not testing functionality
|
||||
n --quiet 4.9.1
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
# ToDo: --arch
|
13
test/tests/install-reference-versions.bash
Executable file
13
test/tests/install-reference-versions.bash
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# These are the versions installed and hence cached by proxy-build.
|
||||
|
||||
# Run commands we want to cache downloads for
|
||||
|
||||
# Get index into cache for lookups of expected versions.
|
||||
curl --location --fail https://nodejs.org/dist/index.tab &> /dev/null
|
||||
|
||||
# Using 4.9.1 as a well known old version (which is no longer getting updated so does not change)
|
||||
n --download 4
|
||||
n --download lts
|
||||
n --download latest
|
76
test/tests/install-versions.bats
Normal file
76
test/tests/install-versions.bats
Normal file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load shared-functions
|
||||
|
||||
|
||||
function setup() {
|
||||
unset_n_env
|
||||
setup_tmp_prefix
|
||||
install_dummy_node
|
||||
}
|
||||
|
||||
|
||||
function teardown() {
|
||||
rm -rf "${TMP_PREFIX_DIR}"
|
||||
}
|
||||
|
||||
|
||||
# Explicit version
|
||||
@test "n 4.9.1" {
|
||||
n 4.9.1
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
# Explicit version, optional leading v
|
||||
@test "n v4.9.1" {
|
||||
n v4.9.1
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
# Partial version
|
||||
@test "n 4" {
|
||||
n 4
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
# Partial version, optional leading v
|
||||
@test "n v4" {
|
||||
n v4
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
# Partial version
|
||||
@test "n 4.9" {
|
||||
n 4.9
|
||||
run node --version
|
||||
[ "${output}" = "v4.9.1" ]
|
||||
}
|
||||
|
||||
|
||||
@test "n lts" {
|
||||
n lts
|
||||
run node --version
|
||||
[ "${output}" = "$(display_remote_version lts)" ]
|
||||
}
|
||||
|
||||
|
||||
@test "n stable" {
|
||||
n stable
|
||||
run node --version
|
||||
[ "${output}" = "$(display_remote_version lts)" ]
|
||||
}
|
||||
|
||||
|
||||
@test "n latest" {
|
||||
n latest
|
||||
run node --version
|
||||
[ "${output}" = "$(display_remote_version latest)" ]
|
||||
}
|
28
test/tests/lookup.bats
Normal file
28
test/tests/lookup.bats
Normal file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load shared-functions
|
||||
|
||||
|
||||
function setup() {
|
||||
unset_n_env
|
||||
}
|
||||
|
||||
|
||||
@test "n --lts" {
|
||||
run n --lts
|
||||
[ "${status}" -eq 0 ]
|
||||
local expected_version
|
||||
expected_version="$(display_remote_version lts)"
|
||||
expected_version="${expected_version#v}"
|
||||
[ "${output}" = "${expected_version}" ]
|
||||
}
|
||||
|
||||
|
||||
@test "n --latest" {
|
||||
run n --latest
|
||||
[ "${status}" -eq 0 ]
|
||||
local expected_version
|
||||
expected_version="$(display_remote_version latest)"
|
||||
expected_version="${expected_version#v}"
|
||||
[ "${output}" = "${expected_version}" ]
|
||||
}
|
104
test/tests/shared-functions.bash
Normal file
104
test/tests/shared-functions.bash
Normal file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
# unset the n environment variables so tests running from known state.
|
||||
# Globals:
|
||||
# lots
|
||||
|
||||
function unset_n_env(){
|
||||
unset N_PREFIX
|
||||
|
||||
# Undocumented [sic]
|
||||
unset NODE_MIRROR
|
||||
|
||||
# Documented under "custom source", but PROJECT and HTTP implemented as independent
|
||||
unset PROJECT_NAME
|
||||
unset PROJECT_URL
|
||||
unset PROJECT_VERSION_CHECK
|
||||
unset HTTP_USER
|
||||
unset HTTP_PASSWORD
|
||||
}
|
||||
|
||||
|
||||
# Create a dummy version of node so `n install` will always activate (and not be affected by possible system version of node).
|
||||
|
||||
function install_dummy_node() {
|
||||
local prefix="${N_PREFIX-/usr/local}"
|
||||
mkdir -p "${prefix}/bin"
|
||||
echo "echo vDummy" > "${prefix}/bin/node"
|
||||
chmod a+x "${prefix}/bin/node"
|
||||
}
|
||||
|
||||
|
||||
# Create temporary dir and configure n to use it.
|
||||
# Globals:
|
||||
# TMP_PREFIX_DIR
|
||||
# N_PREFIX
|
||||
# PATH
|
||||
|
||||
function setup_tmp_prefix() {
|
||||
TMP_PREFIX_DIR="$(mktemp -d)"
|
||||
[ -d "${TMP_PREFIX_DIR}" ] || exit 2
|
||||
# return a safer variable to `rm -rf` later than N_PREFIX
|
||||
export TMP_PREFIX_DIR
|
||||
|
||||
export N_PREFIX="${TMP_PREFIX_DIR}"
|
||||
export PATH="${N_PREFIX}/bin:${PATH}"
|
||||
}
|
||||
|
||||
|
||||
# Display relevant file name (third field of index.tab) for current platform.
|
||||
# Based on code from nvm rather than n for independent approach. Simplified for just common platforms initially.
|
||||
# See list on https://github.com/nodejs/nodejs-dist-indexer
|
||||
|
||||
function display_compatible_file_field() {
|
||||
local os="unexpected"
|
||||
case "$(uname -a)" in
|
||||
Linux\ *) os="linux" ;;
|
||||
Darwin\ *) os="osx" ;;
|
||||
esac
|
||||
|
||||
local arch="unexpected"
|
||||
local uname_m
|
||||
uname_m="$(uname -m)"
|
||||
case "${uname_m}" in
|
||||
x86_64 | amd64) arch="x64" ;;
|
||||
i*86) arch="x86" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
*) arch="${uname_m}" ;;
|
||||
esac
|
||||
|
||||
echo "${os}-${arch}"
|
||||
}
|
||||
|
||||
|
||||
# display_remote_version <version>
|
||||
# Limited support for using index.tab to resolve version into a number.
|
||||
# Return version number, including leading v.
|
||||
|
||||
function display_remote_version() {
|
||||
# ToDo: support NODE_MIRROR
|
||||
|
||||
local fetch
|
||||
if command -v curl &> /dev/null; then
|
||||
fetch="curl --silent --location --fail"
|
||||
else
|
||||
# insecure to match current n implementation
|
||||
fetch="wget -q -O- --no-check-certificate"
|
||||
fi
|
||||
|
||||
local match='xxx'
|
||||
if [[ "$1" = "lts" ]]; then
|
||||
match='[^-]$'
|
||||
elif [[ "$1" = "latest" ]]; then
|
||||
match='.'
|
||||
fi
|
||||
|
||||
# Using awk rather than head so do not close pipe early on curl
|
||||
# (Add display_compatible_file_field when n does similar check!)
|
||||
${fetch} "https://nodejs.org/dist/index.tab" \
|
||||
| tail -n +2 \
|
||||
| grep -E "${match}" \
|
||||
| awk "NR==1" \
|
||||
| cut -f -1
|
||||
}
|
Loading…
Reference in New Issue
Block a user