'L{IProcessProtocol.processEnded} is called after the child process
exits and L{IProcessProtocol.childConnectionLost} is called for each of
its file descriptors.'

def test_processEnded(self):

    ended = Deferred()
    lost = []
    class Ender(ProcessProtocol, ):
        def childDataReceived(self, fd, data):
            msg(('childDataReceived(%d,    %r)' % (fd, data)))
            self.transport.loseConnection()
        def childConnectionLost(self, childFD):
            msg(('childConnectionLost(%d)' % (childFD,)))
            lost.append(childFD)
        def processExited(self, reason):
            msg(('processExited(%r)' % (reason,)))
        def processEnded(self, reason):
            msg(('processEnded(%r)' % (reason,)))
            ended.callback([reason])
    reactor = self.buildReactor()
    reactor.callWhenRunning(reactor.spawnProcess, Ender(), pyExe, [pyExe, '-m', self.keepStdioOpenProgram, 'child', self.keepStdioOpenArg], env=properEnv, usePTY=self.usePTY)
    def cbEnded(args):
        (failure,) = args
        failure.trap(ProcessDone)
        self.assertEqual(set(lost), set([0, 1, 2]))
    ended.addCallback(cbEnded)
    ended.addErrback(err)
    ended.addCallback((lambda ign: reactor.stop()))
    self.runReactor(reactor)
