1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const tick = require('../common/tick'); 6const initHooks = require('./init-hooks'); 7const { checkInvocations } = require('./hook-checks'); 8const tmpdir = require('../common/tmpdir'); 9const net = require('net'); 10 11tmpdir.refresh(); 12 13const hooks = initHooks(); 14hooks.enable(); 15let pipe1, pipe2; 16let pipeserver; 17let pipeconnect; 18 19const server = net.createServer(common.mustCall((c) => { 20 c.end(); 21 server.close(); 22 process.nextTick(maybeOnconnect.bind(null, 'server')); 23})).listen(common.PIPE, common.mustCall(onlisten)); 24 25function onlisten() { 26 const pipeservers = hooks.activitiesOfTypes('PIPESERVERWRAP'); 27 let pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); 28 assert.strictEqual(pipeservers.length, 1); 29 assert.strictEqual(pipeconnects.length, 0); 30 31 net.connect(common.PIPE, 32 common.mustCall(maybeOnconnect.bind(null, 'client'))); 33 34 const pipes = hooks.activitiesOfTypes('PIPEWRAP'); 35 pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); 36 assert.strictEqual(pipes.length, 1); 37 assert.strictEqual(pipeconnects.length, 1); 38 39 pipeserver = pipeservers[0]; 40 pipe1 = pipes[0]; 41 pipeconnect = pipeconnects[0]; 42 43 assert.strictEqual(pipeserver.type, 'PIPESERVERWRAP'); 44 assert.strictEqual(pipe1.type, 'PIPEWRAP'); 45 assert.strictEqual(pipeconnect.type, 'PIPECONNECTWRAP'); 46 for (const a of [ pipeserver, pipe1, pipeconnect ]) { 47 assert.strictEqual(typeof a.uid, 'number'); 48 assert.strictEqual(typeof a.triggerAsyncId, 'number'); 49 checkInvocations(a, { init: 1 }, 'after net.connect'); 50 } 51} 52 53const awaitOnconnectCalls = new Set(['server', 'client']); 54function maybeOnconnect(source) { 55 // Both server and client must call onconnect. On most OS's waiting for 56 // the client is sufficient, but on CentOS 5 the sever needs to respond too. 57 assert.ok(awaitOnconnectCalls.size > 0); 58 awaitOnconnectCalls.delete(source); 59 if (awaitOnconnectCalls.size > 0) return; 60 61 const pipes = hooks.activitiesOfTypes('PIPEWRAP'); 62 const pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); 63 64 assert.strictEqual(pipes.length, 2); 65 assert.strictEqual(pipeconnects.length, 1); 66 pipe2 = pipes[1]; 67 assert.strictEqual(typeof pipe2.uid, 'number'); 68 assert.strictEqual(typeof pipe2.triggerAsyncId, 'number'); 69 70 checkInvocations(pipeserver, { init: 1, before: 1, after: 1 }, 71 'pipeserver, client connected'); 72 checkInvocations(pipe1, { init: 1 }, 'pipe1, client connected'); 73 checkInvocations(pipeconnect, { init: 1, before: 1 }, 74 'pipeconnect, client connected'); 75 checkInvocations(pipe2, { init: 1 }, 'pipe2, client connected'); 76 tick(5); 77} 78 79process.on('exit', onexit); 80 81function onexit() { 82 hooks.disable(); 83 hooks.sanityCheck('PIPEWRAP'); 84 hooks.sanityCheck('PIPESERVERWRAP'); 85 hooks.sanityCheck('PIPECONNECTWRAP'); 86 // TODO(thlorenz) why have some of those 'before' and 'after' called twice 87 checkInvocations(pipeserver, { init: 1, before: 1, after: 1, destroy: 1 }, 88 'pipeserver, process exiting'); 89 checkInvocations(pipe1, { init: 1, before: 2, after: 2, destroy: 1 }, 90 'pipe1, process exiting'); 91 checkInvocations(pipeconnect, { init: 1, before: 1, after: 1, destroy: 1 }, 92 'pipeconnect, process exiting'); 93 checkInvocations(pipe2, { init: 1, before: 2, after: 2, destroy: 1 }, 94 'pipe2, process exiting'); 95} 96