def test_logoutAfterDecref(self):
        """
        If a L{RemoteReference} to an L{IPerspective} avatar is decrefed and
        there remain no other references to the avatar on the server, the
        avatar is garbage collected and the logout method called.
        """
        loggedOut = Deferred()

        class EventPerspective(pb.Avatar):
            """
            An avatar which fires a Deferred when it is logged out.
            """
            def __init__(self, avatarId):
                pass

            def logout(self):
                loggedOut.callback(None)

        self.realm.perspectiveFactory = EventPerspective

        self.portal.registerChecker(
            checkers.InMemoryUsernamePasswordDatabaseDontUse(foo=b'bar'))

        d = self.clientFactory.login(
            credentials.UsernamePassword(b'foo', b'bar'), "BRAINS!")

        def cbLoggedIn(avatar):
            # Just wait for the logout to happen, as it should since the
            # reference to the avatar will shortly no longer exists.
            return loggedOut

        d.addCallback(cbLoggedIn)
        def cbLoggedOut(ignored):
            # Verify that the server broker's _localCleanup dict isn't growing
            # without bound.
            self.assertEqual(self.serverFactory.protocolInstance._localCleanup, {})
        d.addCallback(cbLoggedOut)

        self.establishClientAndServer()

        # complete authentication
        self.pump.flush()
        # _PortalAuthChallenger and our Avatar should be dead by now;
        # force a collection to trigger their __del__s
        gc.collect()
        # push their decref messages through
        self.pump.flush()
        return d

        If a L{RemoteReference} to an L{IPerspective} avatar is decrefed and
        there remain no other references to the avatar on the server, the
        avatar is garbage collected and the logout method called.
        
stackoverflow/venv/lib/python3.6/site-packages/twisted/spread/test/test_pb.py