nodists/nodist

Reopen #173: SIGTERM is suppressed

osher opened this issue · 2 comments

osher commented

I installed 0.8.7 with my devops yesterday EOD.
This morning I came to work and encountered the SIGRETM problem.
#173 SIGTERM does not propagate well between layers

osher commented

Let me try to propose a stripped-down reproduction scenario (also see comment bellow)
The scenario reproduces successfully with nodist@0.8.7, it does not reproduce when forcing in the env var PATH a concrete node version.

having

  1. nodist@0.8.7 installed
  2. the files described bellow are created in current-work-dir. Mind the folder-structure.
  3. make sure you can run mocha either by npm install mocha or npm install mocha -g at your choice.

scenario

  1. run mocha first time
    • expect the tests to pass so what. please carry on
  2. run mocha second time

Expected

  • the tests should to pass for the second time as well

Found

  • before-all hook failure: the server won't launch because the port is occupied by the server launched in the first pass.
c:\ws\nodejs\sandbox>mocha

  my cool server
service started: server.js
    √ will pass but doesnt really matter

service termination ended OK

  1 passing (360ms)

c:\ws\nodejs\sandbox>mocha

  my cool server
    1) "before all" hook: createSvr

service termination ended OK

  0 passing (565ms)
  1 failing

  1) my cool server "before all" hook: createSvr:
     Error: Server could not start: Address In Use
      at Socket.<anonymous> (test\server.test.js:36:18)
      at readableAddChunk (_stream_readable.js:176:18)
      at Socket.Readable.push (_stream_readable.js:134:10)
      at Pipe.onread (net.js:548:20)

c:\ws\nodejs\sandbox>

files:

server.js

require('http').createServer( function(q,r) { r.end('ok') } ).listen(3000, function() {
   console.log('server is up');
   process.on('SIGTERM', close);
   process.on('SIGINT', close);
})
function close() { 
    console.log('closing...');
    process.exit();
}

test/server-test.js

var fs    = require('fs');
var spawn = require('child_process').spawn;
var ctx   = { 
  args:         ["server.js"],
  logPath:      "./e2e.log",
  readyNotice:  'server is up'
};

describe('my cool server', function() {
    before(createSvr);

    it('will pass but doesnt really matter', function() {});

    after(termSvr);
})

function createSvr(done) {
    try { fs.unlinkSync( ctx.logPath ) } catch(e) {}

    this.timeout(ctx.timeout);
    this.slow(ctx.slow);

    var log =
      ctx.log =
        fs.createWriteStream(ctx.logPath, { flags: "a"} );


    var child =
      ctx.child =
        spawn("node", ctx.args, { env: process.env } );

    child.stderr.on('data', function(data) {
        data = data + "";
        if (log.writable) log.write("ERR: " + data);
        if (~data.indexOf("Error: listen EADDRINUSE")) {
            done(new Error("Server could not start: Address In Use"));
        }       
    });
    child.stdout.on('data', function(data) {
        data = data.toString();
        if (log.writable) log.write(data);

        if (~data.indexOf(ctx.readyNotice)) {
            console.log("service started: %s", ctx.args.join(' '));
            done();
        }
    });

    child.on('exit', function(e) { 
        child.exitted = true;
        console.log("\n\nservice termination ended", e || "OK");

        ctx.log.writable = false;
        ctx.log.end(function() {
            child.emit('--over--')
        });        
    });  
}

function termSvr(done) {
    if (ctx.child.exitted) return done()
    ctx.child.on('--over--', done);
    ctx.child.kill('SIGTERM');
}

Comments

I experience it a bit differently.
I work on a code generator, so I generate from template a web project where I start by removing the target folder completely (We decided here not to remove the folder in the end of the test because we wish to inspect the generated files).
So I fail in the second pass because I cannot remove the folder where a process keeps an open handle to it, where the process is the tested server launched on the first pass, so I don't even get to generate it and lunch the test on the second pass.

(reopened #173)