-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mocha's hanging CI browser tests #2890
Comments
I have reason to suspect that this might have something to do with Looked at the Node issue tracker and didn't find any issues about |
#2903 would help debug this (no pun intended). I believe I have found the root cause of the issue. Line 109 in 2bb2b9f
JSON.stringify that could do the same).
Line 713 in 2bc9c4d
I think fixing the latter (or at least allowing us to shut it off during CI runs) may give us the info we're missing from these browser failures, allowing us to confirm or deny that they're the former issue and if they're not then to get some idea of what they are instead. |
So, this is two different things. I'll explain the intent: If
|
I also realize "exceptions are not flow control" are wise words. We can abuse exceptions to halt a test immediately if the user decides it should be skipped, but outside of Zones or async_wrap there's really no way to be sure we've aborted everything: it('life is pain', function (done) {
let i = 0;
setInterval(() => {
console.log('ha ha ha');
if (++i > 5) {
throw new Error('^_^');
}
}, 1000);
setTimeout(() => {
this.skip();
}, 500);
}); Throwing a |
So, I just now had a chance to sit down and review this one. If I understood this accurately: it("should fail, but is suppressed", function(done) {
setTimeout(function() {
done()
throw new Error("Gets thrown but ignored")
}, 5)
}) ...will be marked as passed even though it throws. Assuming that's accurate: I'd consider this a bug and advocate for stopping suppression of that error (i.e. instead it should be failed with the thrown error -- even if after already printing that the test passed -- rather than considered just plain passed and nothing more). Furthermore, doing so by adding yet another special case would be inferior to doing so by removing a special case. The main problem with fixing it is that this will break any tests that were incorrectly passing due to that pattern; it's technically a bugfix but we could save it for version 4 to minimize complaints. If we were to save it for verson 4, I would want to start working on a version 4 branch so that we can get these suppressions corrected there, use version 4 (in development) to diagnose the flake/hang, and then fix the flake/hang in master and add the browser coverage etc. so that before we release 4 we can pull in the browser coverage stuff and improve how sure we are of its correctness (especially if we're dropping a bunch of shims, although correspondingly dropping browsers will make it a little easier on the other hand). (Either way, eventually having more browser coverage will help us determine if there are any remaining shims or environment special-cases we can drop.) it("synchronous pending", function() {
this.skip()
throw new Error("Should never be called")
})
it("asynchronous pending", function(done) {
var test = this
setTimeout(function() {
test.skip()
throw new Error("Should never be called")
}, 5)
})
Question: assuming the above is accurate, should we not be using NB: I have not tried running those tests and confirming their behavior then changing the code and seeing how it changes their behavior. Just wrapping my head around the ideas in the comment. * Last I checked, Domains made it into Node only to end up deprecated because people found problems with them, but Node won't remove them till there's a suitable replacement, and Zones have been proposed as that replacement but nobody can find info on how they avoid the problems Domains have. I don't have a citation or anything, that's just all the info I was able to bring up on Google last time I tried. |
honestly I think this has to do with a sauce connect problem and nothing in our codebase. basically I think we gotta go back to running all of the browsers at once. |
@ScottFreeCode see these commits I think what's happening is this:
so that's my theory. the fix would then be:
a bonus is that awhile back I talked with SauceLabs and had them increase our concurrency. when we split up the browser targets in the past, it was because we were running into problems. now, we should not have problems running all browsers we want in one fell swoop. granted, that fell swoop contains multitudes of |
fwiw, this build |
I understand your concerns about this behavior, but I'm not convinced it's causing any real problems in our build. This example: it("should fail, but is suppressed", function(done) {
setTimeout(function() {
done()
throw new Error("Gets thrown but ignored")
}, 5)
}) Isn't a case that Mocha should be handling, IMO. If code calling So, as you said, Mocha is eating the error, and to let it bubble, we'd have to add more special cases. I don't think this is necessary. Once you've called
We call If we were to change this behavior, I wouldn't suggest to not attempt to abort, even though this only covers the general case. See: it('should be a problem', function (done) {
process.nextTick(() => {
throw new Error('gotcha'); // thrown, but where does it go?
});
this.skip(); // calls done() and finishes up
throw new Error('nope nope nope nope nope'); // not thrown
}); So, if we aren't going to abort, what should we do instead? It would involve changing the API dramatically. Open to suggestions about what this should really look like, but it should require the user to either import {describe, it} from 'mocha';
it('is sync pending', test => test.pending); // or `test.pending();` or `test.pending = true; return;`, etc.
it('is async pending', (test, done) => {
done(test.pending);
});
it('is promise pending', test => {
return myPromise.then(() => test.pending); // or `await myPromise; return test.pending;`
}); At any rate, I'm not really convinced this is the source of browser flake, but this could definitely be improved. |
Of late, there has been a failure in CI that looks like a browser flake... except that it's far too consistent to be a flake. Doesn't always happen, but usually does, and always the same browsers (and usually the same point in the test). It seems like the browser hangs or something -- Sauce disconnects with a timeout of 20,000ms partway through the testsuite.
It's blocking #2886, notably, but some testing determined that it affected the commits there even before coverage was actually added, so it seems to be something that coverage makes more likely to happen but isn't the sole cause.
I have had a... cryptic breakthrough, inasmuch as while I was experimenting with something else I accidentally wound up reproducing a hang in PhantomJS with Node 8.0.0 at the same points where Sauce is disconnecting. I do not know what about my local experiment triggerred this, and am going to move further experimentation to a new checkout of Mocha to ensure this one stays where it can reproduce the hangy issue.
Here's what I have been able to discover:
should format functions saved in windows style - spaces
and for the last unit test.I feel just as stuck as before, but maybe this information will ring a bell to somebody.
The text was updated successfully, but these errors were encountered: