Tests doesn't pass and exit with a timeout exception #519

Closed
Fodi69 opened this Issue Sep 12, 2011 · 7 comments

Comments

Projects
None yet
3 participants
@Fodi69

Fodi69 commented Sep 12, 2011

I run 'make test' and I get:

make[1]: Entering directory `/home/feri/wwwroot/socket.io'
.
  info  - socket.io started

  uncaught: Error: 'test handshake' timed out
   at Object._onTimeout (/home/feri/wwwroot/socket.io/node_modules/expresso/bin/expresso:844:43)
   at Timer.callback (timers.js:62:39)

Testing stops, so tests doesn't continue to run after this exception. (but the test suite doesn't exits, just waits and waits)
I followed the guide for contributing (https://github.com/LearnBoost/socket.io/wiki/Contributing)
If I comment this test case out, then the next one fails, and so on.

@3rd-Eden

This comment has been minimized.

Show comment
Hide comment
@3rd-Eden

3rd-Eden Sep 12, 2011

Contributor

are you using linux?

Contributor

3rd-Eden commented Sep 12, 2011

are you using linux?

@Fodi69

This comment has been minimized.

Show comment
Hide comment
@Fodi69

Fodi69 Sep 12, 2011

Yes, I'm using Ubuntu GNU/Linux.
I thought that is clear, because of the '/home/feri/...' file location

Fodi69 commented Sep 12, 2011

Yes, I'm using Ubuntu GNU/Linux.
I thought that is clear, because of the '/home/feri/...' file location

@3rd-Eden

This comment has been minimized.

Show comment
Hide comment
@3rd-Eden

3rd-Eden Sep 12, 2011

Contributor

Fodi69 no, that was not clear because it could be the other unix system aka mac.

We have issues with our test suite that they are not working on linux distributions. Which is most likely the issue that you are currently bumping in to.

Contributor

3rd-Eden commented Sep 12, 2011

Fodi69 no, that was not clear because it could be the other unix system aka mac.

We have issues with our test suite that they are not working on linux distributions. Which is most likely the issue that you are currently bumping in to.

@mixu

This comment has been minimized.

Show comment
Hide comment
@mixu

mixu Nov 28, 2011

Contributor

Is there anything I can do to help fix the tests on Linux? Any clues to what the problem might be?

I'd like to write more tests and a few features that I need for our deployment, and would definitely prefer not starting a second set of tests to work around this.

If you can point me to the right direction, I'll do what I can to figure it out.

Contributor

mixu commented Nov 28, 2011

Is there anything I can do to help fix the tests on Linux? Any clues to what the problem might be?

I'd like to write more tests and a few features that I need for our deployment, and would definitely prefer not starting a second set of tests to work around this.

If you can point me to the right direction, I'll do what I can to figure it out.

@3rd-Eden

This comment has been minimized.

Show comment
Hide comment
@3rd-Eden

3rd-Eden Nov 28, 2011

Contributor

@mixu it seems that Node.js 0.6 actually fixed this behavior, so it's not really worth the effort of making it run under 0.4 in my opinion.

Contributor

3rd-Eden commented Nov 28, 2011

@mixu it seems that Node.js 0.6 actually fixed this behavior, so it's not really worth the effort of making it run under 0.4 in my opinion.

@mixu

This comment has been minimized.

Show comment
Hide comment
@mixu

mixu Nov 28, 2011

Contributor

I would prefer to have this on Node 0.4 as well, and I figured it out, the problem is that on OSX, libev seems to use a different backend which results in different behavior. Basically:

  1. The tests always start a server and then immediately use it.
  2. On OSX, the backend Node uses causes the server connection to be established immediately
  3. On Linux, the backend Node uses queues the listen() call until the next tick occurs

Since the tests try to connect immediately without passing control back to the Node event loop, on Linux the server won't be started when the client tries to connect. Then the ECONNREFUSED error gets discarded, so nothing happens

Note that according to node.cc (v.0.4.12), if you have OSX 10.6, then EVBACKEND_KQUEUE is used, but otherwise EVFLAG_AUTO is set, which defines the default backend as whatever libev deems appropriate.

Can I fix this and send a pull request? I'd love to have the mainline tests work on older Node.js versions, since that's what we're on.

The fix involves adding a process.nextTick() wrapper somewhere in the tests. Here is an example for the first test:

  'namespace pass no authentication': function (done) {
    var cl = client(++ports)
      , io = create(cl)
      , ws;

    io.of('/a')
      .on('connection', function (socket) {
        cl.end();
        ws.finishClose();
        io.server.close()
        console.log('TEST PASS');
        done();
      });

    process.nextTick(function() {
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        console.log('WEBSOCKET', ws);
        ws.on('open', function () {
          ws.packet({
              type: 'connect'
            , endpoint: '/a'
          });
        })
      });
    });
  },

Can I add the process.nextTick() to the tests, or would you prefer some other way, e.g. by adding the wrapper to client.handshake() where possible? I'm not particularly familiar with the tests but I think I could just add the wrapper to common.js that delays execution of the client code until nextTick(), at least where the tests start with a handshake. Is that OK?

Contributor

mixu commented Nov 28, 2011

I would prefer to have this on Node 0.4 as well, and I figured it out, the problem is that on OSX, libev seems to use a different backend which results in different behavior. Basically:

  1. The tests always start a server and then immediately use it.
  2. On OSX, the backend Node uses causes the server connection to be established immediately
  3. On Linux, the backend Node uses queues the listen() call until the next tick occurs

Since the tests try to connect immediately without passing control back to the Node event loop, on Linux the server won't be started when the client tries to connect. Then the ECONNREFUSED error gets discarded, so nothing happens

Note that according to node.cc (v.0.4.12), if you have OSX 10.6, then EVBACKEND_KQUEUE is used, but otherwise EVFLAG_AUTO is set, which defines the default backend as whatever libev deems appropriate.

Can I fix this and send a pull request? I'd love to have the mainline tests work on older Node.js versions, since that's what we're on.

The fix involves adding a process.nextTick() wrapper somewhere in the tests. Here is an example for the first test:

  'namespace pass no authentication': function (done) {
    var cl = client(++ports)
      , io = create(cl)
      , ws;

    io.of('/a')
      .on('connection', function (socket) {
        cl.end();
        ws.finishClose();
        io.server.close()
        console.log('TEST PASS');
        done();
      });

    process.nextTick(function() {
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        console.log('WEBSOCKET', ws);
        ws.on('open', function () {
          ws.packet({
              type: 'connect'
            , endpoint: '/a'
          });
        })
      });
    });
  },

Can I add the process.nextTick() to the tests, or would you prefer some other way, e.g. by adding the wrapper to client.handshake() where possible? I'm not particularly familiar with the tests but I think I could just add the wrapper to common.js that delays execution of the client code until nextTick(), at least where the tests start with a handshake. Is that OK?

@mixu

This comment has been minimized.

Show comment
Hide comment
@mixu

mixu Nov 29, 2011

Contributor

I guess the correct solution would be to alter create() to accept a callback to run after is has been started, since then the test won't rely on undefined behavior (e.g. what happens when httpServer.listen() but control has not been passed back to the event loop). That would prevent the problem from reoccurring, though this requires a lot of tests to be restructured. The current tests rely on a platform-specific behavior in the backend which means they can break again if the libev backend is switched.

Related: https://gist.github.com/1402427

Contributor

mixu commented Nov 29, 2011

I guess the correct solution would be to alter create() to accept a callback to run after is has been started, since then the test won't rely on undefined behavior (e.g. what happens when httpServer.listen() but control has not been passed back to the event loop). That would prevent the problem from reoccurring, though this requires a lot of tests to be restructured. The current tests rely on a platform-specific behavior in the backend which means they can break again if the libev backend is switched.

Related: https://gist.github.com/1402427

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment