Files
pnpm/test/server.ts
2018-04-07 00:02:23 +03:00

250 lines
7.8 KiB
TypeScript

import delay = require('delay')
import isWindows = require('is-windows')
import path = require('path')
import fs = require('mz/fs')
import tape = require('tape')
import promisifyTape from 'tape-promise'
import killcb = require('tree-kill')
import pathExists = require('path-exists')
import promisify = require('util.promisify')
import {
prepare,
execPnpm,
execPnpmSync,
spawn,
retryLoadJsonFile,
} from './utils'
const IS_WINDOWS = isWindows()
const test = promisifyTape(tape)
test.only = promisifyTape(tape.only)
const kill = promisify(killcb)
test('installation using pnpm server', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start'])
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions)
await execPnpm('install', 'is-positive@1.0.0')
t.ok(project.requireModule('is-positive'))
await execPnpm('uninstall', 'is-positive')
await execPnpm('store', 'prune')
// we don't actually know when the server will prune the store
// lets' just wait a bit before checking
await delay(1000)
await project.storeHasNot('is-positive', '1.0.0')
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('store server: headless installation', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start'])
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions)
await execPnpm('install', 'is-positive@1.0.0', '--shrinkwrap-only')
await execPnpm('install', '--frozen-shrinkwrap')
t.ok(project.requireModule('is-positive'))
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('installation using pnpm server that runs in the background', async (t: tape.Test) => {
const project = prepare(t)
await execPnpm('server', 'start', '--background')
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions)
await execPnpm('install', 'is-positive@1.0.0')
t.ok(project.requireModule('is-positive'))
await execPnpm('uninstall', 'is-positive')
await execPnpm('store', 'prune')
// we don't actually know when the server will prune the store
// lets' just wait a bit before checking
await delay(1000)
await project.storeHasNot('is-positive', '1.0.0')
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('installation using pnpm server via TCP', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start', '--protocol', 'tcp'])
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions.remotePrefix.indexOf('http://localhost:') === 0, 'TCP is used for communication')
await execPnpm('install', 'is-positive@1.0.0')
t.ok(project.requireModule('is-positive'))
await execPnpm('uninstall', 'is-positive')
await execPnpm('store', 'prune')
// we don't actually know when the server will prune the store
// lets' just wait a bit before checking
await delay(1000)
await project.storeHasNot('is-positive', '1.0.0')
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('pnpm server uses TCP when port specified', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start', '--port', '7856'])
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.equal(serverJson.connectionOptions.remotePrefix, 'http://localhost:7856', 'TCP with specified port is used for communication')
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('pnpm server fails when trying to set --port for IPC protocol', async (t: tape.Test) => {
const project = prepare(t)
t.equal(execPnpmSync('server', 'start', '--protocol', 'ipc', '--port', '7856').status, 1, 'process failed')
})
test('stopping server fails when the server disallows stopping via remote call', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start', '--ignore-stop-requests'])
await delay(2000) // lets' wait till the server starts
t.equal(execPnpmSync('server', 'stop').status, 1, 'process failed')
await kill(server.pid, 'SIGINT')
})
test('uploading cache can be disabled without breaking install', async (t: tape.Test) => {
const project = prepare(t)
const server = spawn(['server', 'start', '--ignore-upload-requests'])
// TODO: remove the delay and run install by connecting it to the store server
// Can be done once this gets implemented: https://github.com/pnpm/pnpm/issues/1018
await delay(2000)
// install a package that has side effects
await execPnpm('install', '--side-effects-cache', 'runas@3.1.1')
// make sure the installation is successful, but the cache has not been written
await project.has('runas')
const storePath = await project.getStorePath()
const engine = `${process.platform}-${process.arch}-node-${process.version.split('.')[0]}`
const cacheDir = path.join(storePath, 'localhost+4873', 'runas', '3.1.1', 'side_effects', engine, 'package')
t.notOk(await pathExists(cacheDir), 'side effects cache not uploaded')
await execPnpm('server', 'stop')
})
test('installation using store server started in the background', async (t: tape.Test) => {
const project = prepare(t)
await execPnpm('install', 'is-positive@1.0.0', '--use-store-server')
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions)
t.ok(project.requireModule('is-positive'))
await execPnpm('uninstall', 'is-positive')
await execPnpm('store', 'prune')
// we don't actually know when the server will prune the store
// lets' just wait a bit before checking
await delay(1000)
await project.storeHasNot('is-positive', '1.0.0')
await execPnpm('server', 'stop')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('store server started in the background should use store location wanted by install', async (t: tape.Test) => {
const project = prepare(t)
await execPnpm('install', 'is-positive@1.0.0', '--use-store-server', '--store', '../store2')
const serverJsonPath = path.resolve('..', 'store2', '2', 'server.json')
const serverJson = await retryLoadJsonFile(serverJsonPath)
t.ok(serverJson)
t.ok(serverJson.connectionOptions)
t.ok(project.requireModule('is-positive'))
await execPnpm('uninstall', 'is-positive', '--store', '../store2')
await execPnpm('store', 'prune', '--store', '../store2')
// we don't actually know when the server will prune the store
// lets' just wait a bit before checking
await delay(1000)
await project.storeHasNot('is-positive', '1.0.0')
await execPnpm('server', 'stop', '--store', '../store2')
t.notOk(await pathExists(serverJsonPath), 'server.json removed')
})
test('installation without store server running in the background', async (t: tape.Test) => {
const project = prepare(t)
await execPnpm('install', 'is-positive@1.0.0', '--no-use-store-server')
const serverJsonPath = path.resolve('..', 'store', '2', 'server.json')
t.notOk(await pathExists(serverJsonPath), 'store server not running')
t.ok(project.requireModule('is-positive'))
})