简体   繁体   中英

Node process crashes when running within a bash script

I'm writing a test for my client-server system. The server is a node process which is running and listening until it is killed.
When I'm running the server, and then running the test, everything works fine, and the test passes.

I've tried to write a bash script that runs the server, and only then runs the test file. The result is that the server is killed somehow.

The bash script:

#!/usr/bin/env bash

output=$(mktemp "${TMPDIR:-/tmp/}$(basename 0).XXX")
node Server/Server --port 3300 &> $output &
server_pid=$!
echo "Initializing the server with pid: $server_pid . Wait:\n"
until grep -i 'Server is listening on ip ' $output
do
  sleep 1
done

ps     # here the server is running
npm run test
a=$?
ps     # here the server is not running
kill -9 $server_pid
echo "Server killed"
exit $a

The test:

'use strict';
const cp    = require('child_process');
const ip    = require('my-local-ip');
const utils = require('../util/utils');

describe('Server and client connectivity:', () => {

    it('should transfer index.html file to client', () => {
        let basePath = __dirname.split('/');
        basePath.pop();
        basePath = basePath.join('/');

        const clientPath = basePath + '/Client';

        cp.execSync('node ' + clientPath + '/request', ['-t', ip(), '-p', 3300]);

        expect(utils.isFileExistsInDirectory(clientPath, 'index.html')).toBe(true);
    });

});

By removing the execSync command from the test, the test fails but the server is still running in the background.

How can it be that by running the server within the script, the execSync kills the server, and when running the server manually and then the test - everything works fine?

Edit:
Output of cat $output :

/Users/yinonc/Desktop/DDoSMitigation/server/Server.js:52
                    throw err;
                    ^

Error: ENOENT: no such file or directory, open './index.html'

Relevant part of Server.js file:

const server = http.createServer((req, res) => {
    console.log(`${req.method} request for ${req.url}`);
    console.log(req.connection.remoteAddress);
    let fileName = req.url;
    if (utils.isFileExistsInDirectory(__dirname, fileName)) {
        if (_.includes(fileName, '.html')) {
            fs.readFile(`./${fileName}`, (err, data) => {
                if (err) {
                    throw err; // --------- this is line 52 ----------
                }
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.end(data);
            });
        } else if (req.url.match(/.jpg$/)) {
            const imgPath = path.join(__dirname, 'images', fileName);
            const imgStream = fs.createReadStream(imgPath);

            res.writeHead(200, {'Content-Type': 'image/jpeg'});

            imgStream.pipe(res);
        } else if (req.url.match(/.png$/)) {
            const imgPath = path.join(__dirname, 'images', fileName);
            const imgStream = fs.createReadStream(imgPath);

            res.writeHead(200, {'Content-Type': 'image/png'});

            imgStream.pipe(res);
        }
    } else {
        fileName = cleaner.cleanFileName(fileName);
        fs.writeFileSync(fileName, 'File Not Found. Please check your request.\n', err => {
            if (err) {
                throw err;
            }
        });
        fs.readFile(`./${fileName}`, (err, data) => {
            if (err) {
                console.log("error 2");
                throw err;
            }
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end(data);
        });
    }
});

You need to fix the relative paths using path.join . When you run the test, your working directory is wherever the tests are running from, which causes the relative paths to break.

const server = http.createServer((req, res) => {
    console.log(`${req.method} request for ${req.url}`);
    console.log(req.connection.remoteAddress);
    let fileName = req.url;
    if (utils.isFileExistsInDirectory(__dirname, fileName)) {
        if (_.includes(fileName, '.html')) {
            fs.readFile(path.join(__dirname, `./${fileName}`), (err, data) => {
                if (err) {
                    throw err;
                }
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.end(data);
            });
        } else if (req.url.match(/.jpg$/)) {
            const imgPath = path.join(__dirname, 'images', fileName);
            const imgStream = fs.createReadStream(imgPath);

            res.writeHead(200, {'Content-Type': 'image/jpeg'});

            imgStream.pipe(res);
        } else if (req.url.match(/.png$/)) {
            const imgPath = path.join(__dirname, 'images', fileName);
            const imgStream = fs.createReadStream(imgPath);

            res.writeHead(200, {'Content-Type': 'image/png'});

            imgStream.pipe(res);
        }
    } else {
        fileName = cleaner.cleanFileName(fileName);
        fs.writeFileSync(fileName, 'File Not Found. Please check your request.\n', err => {
            if (err) {
                throw err;
            }
        });
        fs.readFile(path.join(__dirname, `./${fileName}`), (err, data) => {
            if (err) {
                console.log("error 2");
                throw err;
            }
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end(data);
        });
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM