-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix tests for citgm #4221
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
Fix tests for citgm #4221
Changes from all commits
b4bf907
7211b86
54aefda
689adf9
b1a649c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| 'use strict'; | ||
|
|
||
| const ChildProcess = require('child_process'); | ||
|
|
||
| const internals = {}; | ||
|
|
||
| internals.hasLsof = () => { | ||
|
|
||
| try { | ||
| ChildProcess.execSync(`lsof -p ${process.pid}`, { stdio: 'ignore' }); | ||
| } | ||
| catch (err) { | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| }; | ||
|
|
||
| exports.hasLsof = internals.hasLsof(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ const Http = require('http'); | |
| const Net = require('net'); | ||
| const Stream = require('stream'); | ||
| const Url = require('url'); | ||
| const Events = require('events'); | ||
|
|
||
| const Boom = require('@hapi/boom'); | ||
| const Code = require('@hapi/code'); | ||
|
|
@@ -275,45 +276,57 @@ describe('Request', () => { | |
|
|
||
| describe('active()', () => { | ||
|
|
||
| it('exits handler early when request is no longer active', async () => { | ||
| it('exits handler early when request is no longer active', { retry: true }, async (flags) => { | ||
|
|
||
| let testComplete = false; | ||
|
|
||
| const onCleanup = []; | ||
| flags.onCleanup = async () => { | ||
|
|
||
| testComplete = true; | ||
|
|
||
| for (const cleanup of onCleanup) { | ||
| await cleanup(); | ||
| } | ||
| }; | ||
|
|
||
| const server = Hapi.server(); | ||
| const team = new Teamwork.Team(); | ||
| const team2 = new Teamwork.Team(); | ||
| const leaveHandlerTeam = new Teamwork.Team(); | ||
|
|
||
| let rounds = 0; | ||
| server.route({ | ||
| method: 'GET', | ||
| path: '/', | ||
| options: { | ||
| handler: async (request, h) => { | ||
|
|
||
| team2.attend(); | ||
| for (let i = 0; i < 100; ++i) { | ||
| ++rounds; | ||
| await Hoek.wait(10); | ||
| req.abort(); | ||
|
|
||
| if (!request.active()) { | ||
| break; | ||
| } | ||
| while (request.active() && !testComplete) { | ||
| await Hoek.wait(10); | ||
| } | ||
|
|
||
| team.attend(); | ||
| leaveHandlerTeam.attend({ | ||
| active: request.active(), | ||
| testComplete | ||
| }); | ||
|
|
||
| return null; | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| await server.start(); | ||
| onCleanup.unshift(() => server.stop()); | ||
|
|
||
| const req = Http.get(server.info.uri, (res) => { }); | ||
| const req = Http.get(server.info.uri, Hoek.ignore); | ||
| req.on('error', Hoek.ignore); | ||
| await team2.work; | ||
| req.abort(); | ||
| await server.stop(); | ||
|
|
||
| await team.work; | ||
| expect(rounds).to.be.below(10); | ||
| const note = await leaveHandlerTeam.work; | ||
|
|
||
| expect(note).to.equal({ | ||
| active: false, | ||
| testComplete: false | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
|
|
@@ -847,10 +860,10 @@ describe('Request', () => { | |
|
|
||
| describe('_postCycle()', () => { | ||
|
|
||
| it('skips onPreResponse when validation terminates request', async () => { | ||
| it('skips onPreResponse when validation terminates request', { retry: true }, async (flags) => { | ||
kanongil marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const server = Hapi.server(); | ||
| const team = new Teamwork.Team(); | ||
| const abortedReqTeam = new Teamwork.Team(); | ||
|
|
||
| let called = false; | ||
| server.ext('onPreResponse', (request, h) => { | ||
|
|
@@ -863,28 +876,38 @@ describe('Request', () => { | |
| method: 'GET', | ||
| path: '/', | ||
| options: { | ||
| handler: () => null, | ||
| handler: (request) => { | ||
|
|
||
| // Stash raw so that we can access it on response validation | ||
| Object.assign(request.app, request.raw); | ||
|
|
||
| return null; | ||
| }, | ||
| response: { | ||
| status: { | ||
| 200: async () => { | ||
| 200: async (_, { context }) => { | ||
|
|
||
| req.abort(); | ||
| await Hoek.wait(10); | ||
| team.attend(); | ||
|
|
||
| const raw = context.app.request; | ||
| await Events.once(raw.req, 'aborted'); | ||
|
|
||
| abortedReqTeam.attend(); | ||
devinivy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| await server.start(); | ||
| flags.onCleanup = () => server.stop(); | ||
|
|
||
| const req = Http.get(server.info.uri, (res) => { }); | ||
| const req = Http.get(server.info.uri, Hoek.ignore); | ||
| req.on('error', Hoek.ignore); | ||
|
|
||
| await team.work; | ||
| await Hoek.wait(100); | ||
| await server.stop(); | ||
| await abortedReqTeam.work; | ||
|
|
||
| await server.events.once('response'); | ||
|
|
||
| expect(called).to.be.false(); | ||
| }); | ||
|
|
@@ -2279,41 +2302,41 @@ describe('Request', () => { | |
| expect(res.statusCode).to.equal(200); | ||
| }); | ||
|
|
||
| it('handles race condition between equal client and server timeouts', async () => { | ||
| it('handles race condition between equal client and server timeouts', async (flags) => { | ||
|
|
||
| const onCleanup = []; | ||
| flags.onCleanup = async () => { | ||
|
|
||
| for (const cleanup of onCleanup) { | ||
| await cleanup(); | ||
| } | ||
| }; | ||
|
|
||
| const server = Hapi.server({ routes: { timeout: { server: 100 }, payload: { timeout: 100 } } }); | ||
| server.route({ method: 'POST', path: '/timeout', options: { handler: Hoek.block } }); | ||
|
|
||
| await server.start(); | ||
| onCleanup.unshift(() => server.stop()); | ||
|
|
||
| const timer = new Hoek.Bench(); | ||
| const options = { | ||
| hostname: '127.0.0.1', | ||
| hostname: 'localhost', | ||
| port: server.info.port, | ||
| path: '/timeout', | ||
| method: 'POST' | ||
| }; | ||
|
|
||
| await new Promise(async (resolve) => { | ||
| const req = Http.request(options); | ||
| onCleanup.unshift(() => req.destroy()); | ||
|
|
||
| const req = Http.request(options, (res) => { | ||
| req.write('\n'); | ||
|
|
||
| expect([503, 408]).to.contain(res.statusCode); | ||
| expect(timer.elapsed()).to.be.at.least(80); | ||
| resolve(); | ||
| }); | ||
| const [res] = await Events.once(req, 'response'); | ||
|
|
||
| req.on('error', (err) => { | ||
| expect([503, 408]).to.contain(res.statusCode); | ||
| expect(timer.elapsed()).to.be.at.least(80); | ||
|
|
||
| expect(err).to.not.exist(); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In some (flaky) cases this error was being triggered late and causing the next test to fail.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, lab does not bind the expect to a specific test, so it can only assume that errors are caused by the current test. |
||
| }); | ||
|
|
||
| req.write('\n'); | ||
| await Hoek.wait(200); | ||
| req.end(); | ||
| }); | ||
|
|
||
| await server.stop({ timeout: 1 }); | ||
| await Events.once(req, 'close'); // Ensures that req closes without error | ||
| }); | ||
| }); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.